From e2449cfcf0b969cc3b716a8ee2c07159ec7a7702 Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Tue, 23 Apr 2013 10:54:44 +0530 Subject: [PATCH] CLOUDSTACK-763: Added replaceNetworkACLList API. Added support for ACL action allow/deny and also number --- .../com/cloud/agent/api/to/NetworkACLTO.java | 35 +- api/src/com/cloud/event/EventTypes.java | 3 + api/src/com/cloud/network/Network.java | 1 + api/src/com/cloud/network/NetworkProfile.java | 7 + .../element/NetworkACLServiceProvider.java | 3 +- .../network/firewall/NetworkACLService.java | 15 +- api/src/com/cloud/network/vpc/NetworkACL.java | 3 +- .../com/cloud/network/vpc/NetworkACLItem.java | 87 ++++ .../apache/cloudstack/api/ApiConstants.java | 1 + .../cloudstack/api/ResponseGenerator.java | 5 +- .../user/network/CreateNetworkACLCmd.java | 107 ++--- .../user/network/CreateNetworkACLListCmd.java | 6 +- .../user/network/DeleteNetworkACLCmd.java | 7 +- .../user/network/DeleteNetworkACLListCmd.java | 4 +- .../user/network/ListNetworkACLListsCmd.java | 12 +- .../user/network/ListNetworkACLsCmd.java | 15 +- .../network/ReplaceNetworkACLListCmd.java | 107 +++++ .../api/response/NetworkACLItemResponse.java | 106 +++++ .../api/response/NetworkACLListResponse.java | 57 --- .../api/response/NetworkACLResponse.java | 80 +--- client/tomcatconf/applicationContext.xml.in | 1 + client/tomcatconf/commands.properties.in | 1 + .../api/routing/SetNetworkACLCommand.java | 19 +- .../src/com/cloud/network/dao/NetworkDao.java | 2 + .../com/cloud/network/dao/NetworkDaoImpl.java | 9 + .../src/com/cloud/network/dao/NetworkVO.java | 12 + server/src/com/cloud/api/ApiDBUtils.java | 30 +- .../src/com/cloud/api/ApiResponseHelper.java | 26 +- .../com/cloud/network/NetworkManagerImpl.java | 4 +- .../element/VpcVirtualRouterElement.java | 8 +- .../network/firewall/FirewallManagerImpl.java | 4 +- .../VpcVirtualNetworkApplianceManager.java | 7 +- ...VpcVirtualNetworkApplianceManagerImpl.java | 29 +- .../cloud/network/vpc/NetworkACLItemDao.java | 44 ++ .../cloud/network/vpc/NetworkACLItemVO.java | 198 ++++++++ .../cloud/network/vpc/NetworkACLManager.java | 9 +- .../network/vpc/NetworkACLManagerImpl.java | 424 ++++++++---------- .../com/cloud/network/vpc/NetworkACLVO.java | 10 + .../vpc/dao/NetworkACLItemDaoImpl.java | 147 ++++++ .../cloud/server/ManagementServerImpl.java | 1 + setup/db/db/schema-410to420.sql | 9 +- 41 files changed, 1139 insertions(+), 516 deletions(-) create mode 100644 api/src/com/cloud/network/vpc/NetworkACLItem.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java create mode 100644 api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java delete mode 100644 api/src/org/apache/cloudstack/api/response/NetworkACLListResponse.java create mode 100644 server/src/com/cloud/network/vpc/NetworkACLItemDao.java create mode 100644 server/src/com/cloud/network/vpc/NetworkACLItemVO.java create mode 100644 server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java diff --git a/api/src/com/cloud/agent/api/to/NetworkACLTO.java b/api/src/com/cloud/agent/api/to/NetworkACLTO.java index 8818e13de4a..48de40ce501 100644 --- a/api/src/com/cloud/agent/api/to/NetworkACLTO.java +++ b/api/src/com/cloud/agent/api/to/NetworkACLTO.java @@ -20,10 +20,10 @@ package com.cloud.agent.api.to; import java.util.ArrayList; import java.util.List; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.NetworkACLItem.TrafficType; import org.apache.cloudstack.api.InternalIdentity; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.utils.net.NetUtils; @@ -37,15 +37,16 @@ public class NetworkACLTO implements InternalIdentity { private List cidrList; private Integer icmpType; private Integer icmpCode; - private FirewallRule.TrafficType trafficType; - + private TrafficType trafficType; + String action; + int number; protected NetworkACLTO() { } public NetworkACLTO(long id,String vlanTag, String protocol, Integer portStart, Integer portEnd, boolean revoked, - boolean alreadyAdded, List cidrList, Integer icmpType,Integer icmpCode,TrafficType trafficType) { + boolean alreadyAdded, List cidrList, Integer icmpType,Integer icmpCode,TrafficType trafficType, boolean allow, int number) { this.vlanTag = vlanTag; this.protocol = protocol; @@ -70,12 +71,20 @@ public class NetworkACLTO implements InternalIdentity { this.icmpType = icmpType; this.icmpCode = icmpCode; this.trafficType = trafficType; + + if(allow){ + this.action = "ACCEPT"; + } else { + this.action = "DROP"; + } + + this.number = number; } - public NetworkACLTO(FirewallRule rule, String vlanTag, FirewallRule.TrafficType trafficType ) { + public NetworkACLTO(NetworkACLItem rule, String vlanTag, NetworkACLItem.TrafficType trafficType ) { this(rule.getId(), vlanTag, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), - rule.getState() == FirewallRule.State.Revoke, rule.getState() == FirewallRule.State.Active, - rule.getSourceCidrList() ,rule.getIcmpType(), rule.getIcmpCode(),trafficType); + rule.getState() == NetworkACLItem.State.Revoke, rule.getState() == NetworkACLItem.State.Active, + rule.getSourceCidrList() ,rule.getIcmpType(), rule.getIcmpCode(),trafficType, rule.getAction() == NetworkACLItem.Action.Allow, rule.getNumber()); } public long getId() { @@ -121,7 +130,15 @@ public class NetworkACLTO implements InternalIdentity { return alreadyAdded; } - public FirewallRule.TrafficType getTrafficType() { + public TrafficType getTrafficType() { return trafficType; } + + public String getAction() { + return action; + } + + public int getNumber(){ + return number; + } } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 0125f3641c6..88398875424 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -348,6 +348,9 @@ public class EventTypes { public static final String EVENT_NETWORK_ACL_CREATE = "NETWORK.ACL.CREATE"; public static final String EVENT_NETWORK_ACL_UPDATE = "NETWORK.ACL.UPDATE"; public static final String EVENT_NETWORK_ACL_DELETE = "NETWORK.ACL.DELETE"; + public static final String EVENT_NETWORK_ACL_REPLACE = "NETWORK.ACL.REPLACE"; + public static final String EVENT_NETWORK_ACL_ITEM_CREATE = "NETWORK.ACL.ITEM.CREATE"; + public static final String EVENT_NETWORK_ACL_ITEM_DELETE = "NETWORK.ACL.ITEM.DELETE"; // VPC offerings public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE"; diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index fa062c6a694..e359550d7b3 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -327,4 +327,5 @@ public interface Network extends ControlledEntity, StateObject, I */ Long getVpcId(); + Long getNetworkACLId(); } diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java index 2f56645139c..568edf7c9ec 100644 --- a/api/src/com/cloud/network/NetworkProfile.java +++ b/api/src/com/cloud/network/NetworkProfile.java @@ -52,6 +52,7 @@ public class NetworkProfile implements Network { private boolean restartRequired; private boolean specifyIpRanges; private Long vpcId; + private Long networkAclId; public NetworkProfile(Network network) { this.id = network.getId(); @@ -81,6 +82,7 @@ public class NetworkProfile implements Network { this.restartRequired = network.isRestartRequired(); this.specifyIpRanges = network.getSpecifyIpRanges(); this.vpcId = network.getVpcId(); + this.networkAclId = network.getNetworkACLId(); } public String getDns1() { @@ -236,6 +238,11 @@ public class NetworkProfile implements Network { return vpcId; } + @Override + public Long getNetworkACLId() { + return networkAclId; + } + @Override public void setTrafficType(TrafficType type) { this.trafficType = type; diff --git a/api/src/com/cloud/network/element/NetworkACLServiceProvider.java b/api/src/com/cloud/network/element/NetworkACLServiceProvider.java index 4073b07ba1b..dac0a25c668 100644 --- a/api/src/com/cloud/network/element/NetworkACLServiceProvider.java +++ b/api/src/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.rules.FirewallRule; +import com.cloud.network.vpc.NetworkACLItem; public interface NetworkACLServiceProvider extends NetworkElement{ @@ -30,6 +31,6 @@ public interface NetworkACLServiceProvider extends NetworkElement{ * @return * @throws ResourceUnavailableException */ - boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException; + boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java index 8621e48d70a..ae46d83cc9f 100644 --- a/api/src/com/cloud/network/firewall/NetworkACLService.java +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -20,36 +20,37 @@ package com.cloud.network.firewall; import java.util.List; import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.NetworkACLItem; +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; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.rules.FirewallRule; import com.cloud.user.Account; import com.cloud.utils.Pair; public interface NetworkACLService { - FirewallRule getNetworkACLItem(long ruleId); - boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException; + NetworkACLItem getNetworkACLItem(long ruleId); + boolean applyNetworkACLtoNetworks(long aclId, Account caller) throws ResourceUnavailableException; /** * @param createNetworkACLCmd * @return */ - FirewallRule createNetworkACLItem(FirewallRule acl) throws NetworkRuleConflictException; + NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd) throws NetworkRuleConflictException; /** * @param ruleId * @param apply * @return */ - boolean revokeNetworkACL(long ruleId, boolean apply); + boolean revokeNetworkACLItem(long ruleId, boolean apply); /** * @param listNetworkACLsCmd * @return */ - Pair, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd); + Pair, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd); NetworkACL createNetworkACL(CreateNetworkACLListCmd cmd); @@ -58,4 +59,6 @@ public interface NetworkACLService { boolean deleteNetworkACL(long id); Pair,Integer> listNetworkACLs(ListNetworkACLListsCmd listNetworkACLListsCmd); + + boolean replaceNetworkACL(long aclId, long networkId); } diff --git a/api/src/com/cloud/network/vpc/NetworkACL.java b/api/src/com/cloud/network/vpc/NetworkACL.java index 8839ffd2b7c..1b171e31de6 100644 --- a/api/src/com/cloud/network/vpc/NetworkACL.java +++ b/api/src/com/cloud/network/vpc/NetworkACL.java @@ -17,9 +17,10 @@ package com.cloud.network.vpc; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.InternalIdentity; -public interface NetworkACL extends InternalIdentity{ +public interface NetworkACL extends InternalIdentity, ControlledEntity{ String getDescription(); String getUuid(); diff --git a/api/src/com/cloud/network/vpc/NetworkACLItem.java b/api/src/com/cloud/network/vpc/NetworkACLItem.java new file mode 100644 index 00000000000..9cce1875d90 --- /dev/null +++ b/api/src/com/cloud/network/vpc/NetworkACLItem.java @@ -0,0 +1,87 @@ +// 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 org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +import java.util.List; + +public interface NetworkACLItem extends InternalIdentity { + + String getUuid(); + + Action getAction(); + + int getNumber(); + + enum NetworkACLType { + System, // The pre-defined rules created by admin, in the system wide + User // the rules created by user, to a specific ip + } + + enum State { + Staged, // Rule been created but has never got through network rule conflict detection. Rules in this state can not be sent to network elements. + Add, // Add means the rule has been created and has gone through network rule conflict detection. + Active, // Rule has been sent to the network elements and reported to be active. + Revoke // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + } + + enum TrafficType { + Ingress, + Egress + } + + enum Action { + Allow, + Deny + } + + /** + * @return first port of the source port range. + */ + Integer getSourcePortStart(); + + /** + * @return last port of the source prot range. If this is null, that means only one port is mapped. + */ + Integer getSourcePortEnd(); + + /** + * @return protocol to open these ports for. + */ + String getProtocol(); + + State getState(); + + long getACLId(); + + Integer getIcmpCode(); + + Integer getIcmpType(); + + List getSourceCidrList(); + + NetworkACLType getType(); + + /** + * @return + */ + TrafficType getTrafficType(); + +} diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index c76506afc10..170af2e0313 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -490,6 +490,7 @@ public class ApiConstants { public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames"; public static final String ASA_INSIDE_PORT_PROFILE = "insideportprofile"; public static final String AFFINITY_GROUP_ID = "affinitygroupid"; + public static final String ACL_ID = "aclid"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index f765dcb37fc..16760c0390a 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -25,6 +25,7 @@ import com.cloud.vm.NicSecondaryIp; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.Vpc; @@ -305,13 +306,13 @@ public interface ResponseGenerator { * @param networkACLItem * @return */ - NetworkACLResponse createNetworkACLItemResponse(FirewallRule networkACLItem); + NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem networkACLItem); /** * @param networkACL * @return */ - NetworkACLListResponse createNetworkACLResponse(NetworkACL networkACL); + NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL); /** * @param result diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java index ae1ea90545f..b6c0eb6c7c3 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java @@ -19,6 +19,9 @@ package org.apache.cloudstack.api.command.user.network; import java.util.ArrayList; import java.util.List; +import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.NetworkACLItem.NetworkACLType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -26,6 +29,7 @@ import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.log4j.Logger; @@ -36,15 +40,14 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.net.NetUtils; @APICommand(name = "createNetworkACL", description = "Creates a ACL rule the given network (the network has to belong to VPC)", -responseObject = NetworkACLResponse.class) -public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallRule { +responseObject = NetworkACLItemResponse.class) +public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateNetworkACLCmd.class.getName()); private static final String s_name = "createnetworkaclresponse"; @@ -74,10 +77,13 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR private Integer icmpCode; @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, - required=true, description="The network of the vm the ACL will be created for") private Long networkId; + @Parameter(name=ApiConstants.ACL_ID, type=CommandType.UUID, entityType = NetworkACLResponse.class, + description="The network of the vm the ACL will be created for") + private Long aclId; + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="the traffic type for the ACL," + "can be Ingress or Egress, defaulted to Ingress if not specified") private String trafficType; @@ -90,7 +96,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return null; } - @Override public String getProtocol() { return protocol.trim(); } @@ -106,25 +111,34 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR } public long getVpcId() { - Network network = _networkService.getNetwork(getNetworkId()); - if (network == null) { - throw new InvalidParameterValueException("Invalid networkId is given"); + Long vpcId = null; + + if(getACLId() != null){ + NetworkACL acl = _networkACLService.getNetworkACL(getACLId()); + if(acl == null){ + throw new InvalidParameterValueException("Invalid aclId is given"); + } + vpcId = acl.getVpcId(); + } else if(getNetworkId() != null){ + Network network = _networkService.getNetwork(getNetworkId()); + if (network == null) { + throw new InvalidParameterValueException("Invalid networkId is given"); + } + vpcId = network.getVpcId(); } - Long vpcId = network.getVpcId(); if (vpcId == null) { - throw new InvalidParameterValueException("Can create network ACL only for the network belonging to the VPC"); + throw new InvalidParameterValueException("Can create network ACL only for the ACL belonging to the VPC"); } return vpcId; } - @Override - public FirewallRule.TrafficType getTrafficType() { + public NetworkACLItem.TrafficType getTrafficType() { if (trafficType == null) { - return FirewallRule.TrafficType.Ingress; + return NetworkACLItem.TrafficType.Ingress; } - for (FirewallRule.TrafficType type : FirewallRule.TrafficType.values()) { + for (NetworkACLItem.TrafficType type : NetworkACLItem.TrafficType.values()) { if (type.toString().equalsIgnoreCase(trafficType)) { return type; } @@ -149,13 +163,13 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR public void execute() throws ResourceUnavailableException { UserContext callerContext = UserContext.current(); boolean success = false; - FirewallRule rule = _networkACLService.getNetworkACLItem(getEntityId()); + NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId()); try { UserContext.current().setEventDetails("Rule Id: " + getEntityId()); - success = _networkACLService.applyNetworkACLs(rule.getNetworkId(), callerContext.getCaller()); + success = _networkACLService.applyNetworkACLtoNetworks(rule.getACLId(), callerContext.getCaller()); // State is different after the rule is applied, so get new object here - NetworkACLResponse aclResponse = new NetworkACLResponse(); + NetworkACLItemResponse aclResponse = new NetworkACLItemResponse(); if (rule != null) { aclResponse = _responseGenerator.createNetworkACLItemResponse(rule); setResponseObject(aclResponse); @@ -163,36 +177,16 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR aclResponse.setResponseName(getCommandName()); } finally { if (!success || rule == null) { - _networkACLService.revokeNetworkACL(getEntityId(), true); + _networkACLService.revokeNetworkACLItem(getEntityId(), true); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network ACL"); } } } - @Override - public long getId() { - throw new UnsupportedOperationException("database id can only provided by VO objects"); - } - - @Override - public String getXid() { - // FIXME: We should allow for end user to specify Xid. - return null; - } - - - @Override - public String getUuid() { - // TODO Auto-generated method stub - return null; - } - - @Override public Long getSourceIpAddressId() { return null; } - @Override public Integer getSourcePortStart() { if (publicStartPort != null) { return publicStartPort.intValue(); @@ -200,7 +194,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return null; } - @Override public Integer getSourcePortEnd() { if (publicEndPort == null) { if (publicStartPort != null) { @@ -213,18 +206,11 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return null; } - @Override - public Purpose getPurpose() { - return Purpose.Firewall; - } - - @Override - public State getState() { + public NetworkACLItem.State getState() { throw new UnsupportedOperationException("Should never call me to find the state"); } - @Override - public long getNetworkId() { + public Long getNetworkId() { return networkId; } @@ -239,7 +225,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return account.getId(); } - @Override public long getDomainId() { Vpc vpc = _vpcService.getVpc(getVpcId()); return vpc.getDomainId(); @@ -256,7 +241,7 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR } try { - FirewallRule result = _networkACLService.createNetworkACLItem(this); + NetworkACLItem result = _networkACLService.createNetworkACLItem(this); setEntityId(result.getId()); setEntityUuid(result.getUuid()); } catch (NetworkRuleConflictException ex) { @@ -268,16 +253,15 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR @Override public String getEventType() { - return EventTypes.EVENT_FIREWALL_OPEN; + return EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE; } @Override public String getEventDescription() { - Network network = _networkService.getNetwork(networkId); - return ("Createing Network ACL for Netowrk: " + network + " for protocol:" + this.getProtocol()); + //Network network = _networkService.getNetwork(networkId); + return ("Creating Network ACL Item for protocol:" + this.getProtocol()); } - @Override public long getAccountId() { Vpc vpc = _vpcService.getVpc(getVpcId()); return vpc.getAccountId(); @@ -293,7 +277,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return getNetworkId(); } - @Override public Integer getIcmpCode() { if (icmpCode != null) { return icmpCode; @@ -303,7 +286,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return null; } - @Override public Integer getIcmpType() { if (icmpType != null) { return icmpType; @@ -314,14 +296,8 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return null; } - @Override - public Long getRelated() { - return null; - } - - @Override - public FirewallRuleType getType() { - return FirewallRuleType.User; + public NetworkACLType getType() { + return NetworkACLType.User; } @Override @@ -329,4 +305,7 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements FirewallR return AsyncJob.Type.FirewallRule; } + public Long getACLId() { + return aclId; + } } diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java index 9c714971203..0cc460d2b78 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java @@ -24,12 +24,12 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.user.UserContext; import org.apache.cloudstack.api.*; -import org.apache.cloudstack.api.response.NetworkACLListResponse; +import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.log4j.Logger; @APICommand(name = "createNetworkACLList", description = "Creates a Network ACL for the given VPC", -responseObject = NetworkACLListResponse.class) +responseObject = NetworkACLResponse.class) public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateNetworkACLListCmd.class.getName()); @@ -86,7 +86,7 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd { boolean success = false; NetworkACL acl = _networkACLService.getNetworkACL(getEntityId()); if(acl != null){ - NetworkACLListResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl); + NetworkACLResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl); setResponseObject(aclResponse); aclResponse.setResponseName(getCommandName()); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java index 272a12926d4..2f882303ffe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.api.command.user.network; +import com.cloud.network.vpc.NetworkACLItem; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -80,11 +81,11 @@ public class DeleteNetworkACLCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { if (ownerId == null) { - FirewallRule rule = _networkACLService.getNetworkACLItem(id); + NetworkACLItem rule = _networkACLService.getNetworkACLItem(id); if (rule == null) { throw new InvalidParameterValueException("Unable to find network ACL by id=" + id); } else { - ownerId = rule.getAccountId(); + //ownerId = rule.getAccountId(); } } return ownerId; @@ -93,7 +94,7 @@ public class DeleteNetworkACLCmd extends BaseAsyncCmd { @Override public void execute() throws ResourceUnavailableException { UserContext.current().setEventDetails("Network ACL Id: " + id); - boolean result = _networkACLService.revokeNetworkACL(id, true); + boolean result = _networkACLService.revokeNetworkACLItem(id, true); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java index f5024759e2e..42ecd8d155d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java @@ -27,7 +27,7 @@ import com.cloud.user.UserContext; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.response.AccountResponse; import org.apache.cloudstack.api.response.FirewallRuleResponse; -import org.apache.cloudstack.api.response.NetworkACLListResponse; +import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; @@ -40,7 +40,7 @@ public class DeleteNetworkACLListCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = NetworkACLListResponse.class, + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = NetworkACLResponse.class, required=true, description="the ID of the network ACL") private Long id; diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java index b043eed6ab4..55d61477ece 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java @@ -23,13 +23,15 @@ import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.response.*; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.NetworkACLResponse; +import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.List; -@APICommand(name = "listNetworkACLLists", description="Lists all network ACLs", responseObject=NetworkACLListResponse.class) +@APICommand(name = "listNetworkACLLists", description="Lists all network ACLs", responseObject=NetworkACLResponse.class) public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkACLListsCmd.class.getName()); @@ -70,11 +72,11 @@ public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ Pair,Integer> result = _networkACLService.listNetworkACLs(this); - ListResponse response = new ListResponse(); - List aclResponses = new ArrayList(); + ListResponse response = new ListResponse(); + List aclResponses = new ArrayList(); for (NetworkACL acl : result.first()) { - NetworkACLListResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl); + NetworkACLResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl); aclResponses.add(aclResponse); } response.setResponses(aclResponses, result.second()); diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java index 93842d5c58b..53e19d72f71 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java @@ -19,20 +19,21 @@ package org.apache.cloudstack.api.command.user.network; import java.util.ArrayList; import java.util.List; +import com.cloud.network.vpc.NetworkACLItem; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.FirewallRuleResponse; import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.response.NetworkACLResponse; +import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.log4j.Logger; import com.cloud.network.rules.FirewallRule; import com.cloud.utils.Pair; -@APICommand(name = "listNetworkACLs", description="Lists all network ACLs", responseObject=NetworkACLResponse.class) +@APICommand(name = "listNetworkACLs", description="Lists all network ACL items", responseObject=NetworkACLItemResponse.class) public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkACLsCmd.class.getName()); @@ -79,12 +80,12 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - Pair,Integer> result = _networkACLService.listNetworkACLItems(this); - ListResponse response = new ListResponse(); - List aclResponses = new ArrayList(); + Pair,Integer> result = _networkACLService.listNetworkACLItems(this); + ListResponse response = new ListResponse(); + List aclResponses = new ArrayList(); - for (FirewallRule acl : result.first()) { - NetworkACLResponse ruleData = _responseGenerator.createNetworkACLItemResponse(acl); + for (NetworkACLItem acl : result.first()) { + NetworkACLItemResponse ruleData = _responseGenerator.createNetworkACLItemResponse(acl); aclResponses.add(ruleData); } response.setResponses(aclResponses, result.second()); diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java new file mode 100644 index 00000000000..78e0b1a61f3 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java @@ -0,0 +1,107 @@ +// 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.api.command.user.network; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.UserContext; +import org.apache.cloudstack.api.*; +import org.apache.cloudstack.api.response.NetworkACLResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "replaceNetworkACLList", description="Replaces ACL associated with a Network", responseObject=SuccessResponse.class) +public class ReplaceNetworkACLListCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(ReplaceNetworkACLListCmd.class.getName()); + private static final String s_name = "replacenetworkacllistresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ACL_ID, type=CommandType.UUID, entityType = NetworkACLResponse.class, + required=true, description="the ID of the network ACL") + private long aclId; + + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, + required=true, description="the ID of the network") + private long networkId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public long getAclId() { + return aclId; + } + + public long getNetworkId(){ + return networkId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETWORK_ACL_REPLACE; + } + + @Override + public String getEventDescription() { + return ("Associating Network ACL id=" + aclId+ " with Network id="+ networkId); + } + + @Override + public long getEntityOwnerId() { + NetworkACL acl = _networkACLService.getNetworkACL(aclId); + if (acl == null) { + throw new InvalidParameterValueException("Unable to find network ACL by id=" + aclId); + } else { + long vpcId = acl.getVpcId(); + Vpc vpc = _vpcService.getVpc(vpcId); + if(vpc != null){ + return vpc.getAccountId(); + } else { + throw new InvalidParameterValueException("Unable to find VPC associated with network ACL by id=" + aclId); + } + } + } + + @Override + public void execute() throws ResourceUnavailableException { + UserContext.current().setEventDetails("Network ACL Id: " + aclId); + boolean result = _networkACLService.replaceNetworkACL(aclId, networkId); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to replace network ACL"); + } + } +} + diff --git a/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java new file mode 100644 index 00000000000..d40acbf0ac1 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java @@ -0,0 +1,106 @@ +// 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.api.response; + +import java.util.List; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class NetworkACLItemResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the ID of the ACL Item") + private String id; + + @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the ACL") + private String protocol; + + @SerializedName(ApiConstants.START_PORT) @Param(description="the starting port of ACL's port range") + private String startPort; + + @SerializedName(ApiConstants.END_PORT) @Param(description = "the ending port of ACL's port range") + private String endPort; + + @SerializedName(ApiConstants.TRAFFIC_TYPE) @Param(description="the traffic type for the ACL") + private String trafficType; + + @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule") + private String state; + + @SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from") + private String cidrList; + + @SerializedName(ApiConstants.ICMP_TYPE) @Param(description= "type of the icmp message being sent") + private Integer icmpType; + + @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message") + private Integer icmpCode; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the network ACLs", + responseObject = ResourceTagResponse.class) + private List tags; + + @SerializedName(ApiConstants.ACL_ID) @Param(description="the ID of the ACL this item belongs to") + private String aclId; + + public void setId(String id) { + this.id = id; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public void setStartPort(String startPort) { + this.startPort = startPort; + } + + public void setEndPort(String endPort) { + this.endPort = endPort; + } + + public void setState(String state) { + this.state = state; + } + + public void setCidrList(String cidrList) { + this.cidrList = cidrList; + } + + public void setIcmpType(Integer icmpType) { + this.icmpType = icmpType; + } + + public void setIcmpCode(Integer icmpCode) { + this.icmpCode = icmpCode; + } + + public void setTrafficType(String trafficType) { + this.trafficType = trafficType; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public void setAclId(String aclId) { + this.aclId = aclId; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/NetworkACLListResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkACLListResponse.java deleted file mode 100644 index 34878510a94..00000000000 --- a/api/src/org/apache/cloudstack/api/response/NetworkACLListResponse.java +++ /dev/null @@ -1,57 +0,0 @@ -// 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.api.response; - -import com.cloud.network.vpc.NetworkACL; -import com.cloud.serializer.Param; -import com.google.gson.annotations.SerializedName; -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; -import org.apache.cloudstack.api.EntityReference; - -import java.util.List; - -@EntityReference(value = NetworkACL.class) -public class NetworkACLListResponse extends BaseResponse { - @SerializedName(ApiConstants.ID) @Param(description="the ID of the ACL") - private String id; - - @SerializedName(ApiConstants.NAME) @Param(description="the Name of the ACL") - private String name; - - @SerializedName(ApiConstants.DESCRIPTION) @Param(description="Description of the ACL") - private String description; - - @SerializedName(ApiConstants.VPC_ID) @Param(description="Id of the VPC this ACL is associated with") - private String vpcId; - - public void setId(String id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setVpcId(String vpcId) { - this.vpcId = vpcId; - } -} diff --git a/api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java index b45b43cf6ec..12ca38b222a 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java @@ -16,84 +16,42 @@ // under the License. package org.apache.cloudstack.api.response; -import java.util.List; - -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseResponse; - +import com.cloud.network.vpc.NetworkACL; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; -@SuppressWarnings("unused") +import java.util.List; + +@EntityReference(value = NetworkACL.class) public class NetworkACLResponse extends BaseResponse { @SerializedName(ApiConstants.ID) @Param(description="the ID of the ACL") private String id; - @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the ACL") - private String protocol; + @SerializedName(ApiConstants.NAME) @Param(description="the Name of the ACL") + private String name; - @SerializedName(ApiConstants.START_PORT) @Param(description="the starting port of ACL's port range") - private String startPort; + @SerializedName(ApiConstants.DESCRIPTION) @Param(description="Description of the ACL") + private String description; - @SerializedName(ApiConstants.END_PORT) @Param(description = "the ending port of ACL's port range") - private String endPort; - - @SerializedName(ApiConstants.TRAFFIC_TYPE) @Param(description="the traffic type for the ACL") - private String trafficType; - - @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule") - private String state; - - @SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from") - private String cidrList; - - @SerializedName(ApiConstants.ICMP_TYPE) @Param(description= "type of the icmp message being sent") - private Integer icmpType; - - @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message") - private Integer icmpCode; - - @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the network ACLs", - responseObject = ResourceTagResponse.class) - private List tags; + @SerializedName(ApiConstants.VPC_ID) @Param(description="Id of the VPC this ACL is associated with") + private String vpcId; public void setId(String id) { this.id = id; } - public void setProtocol(String protocol) { - this.protocol = protocol; + public void setName(String name) { + this.name = name; } - public void setStartPort(String startPort) { - this.startPort = startPort; + public void setDescription(String description) { + this.description = description; } - public void setEndPort(String endPort) { - this.endPort = endPort; - } - - public void setState(String state) { - this.state = state; - } - - public void setCidrList(String cidrList) { - this.cidrList = cidrList; - } - - public void setIcmpType(Integer icmpType) { - this.icmpType = icmpType; - } - - public void setIcmpCode(Integer icmpCode) { - this.icmpCode = icmpCode; - } - - public void setTrafficType(String trafficType) { - this.trafficType = trafficType; - } - - public void setTags(List tags) { - this.tags = tags; + public void setVpcId(String vpcId) { + this.vpcId = vpcId; } } diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 60509920492..cdce3f9164b 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -247,6 +247,7 @@ + diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 2078c8da72d..cb7965bef68 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -437,6 +437,7 @@ deleteNetworkACL=15 listNetworkACLs=15 createNetworkACLList=15 deleteNetworkACLList=15 +replaceNetworkACLList=15 listNetworkACLLists=15 diff --git a/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java b/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java index dba7354c8f2..d876c61fb4b 100644 --- a/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java +++ b/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java @@ -17,6 +17,9 @@ package com.cloud.agent.api.routing; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -42,11 +45,17 @@ public class SetNetworkACLCommand extends NetworkElementCommand{ public String[][] generateFwRules() { String [][] result = new String [2][]; Set toAdd = new HashSet(); + List aclList = Arrays.asList(rules); + Collections.sort(aclList, new Comparator() { + @Override + public int compare(NetworkACLTO acl1, NetworkACLTO acl2) { + return acl1.getNumber() > acl2.getNumber() ? 1 : -1; + } + }); - - for (NetworkACLTO aclTO: rules) { - /* example : Ingress:tcp:80:80:0.0.0.0/0:,Egress:tcp:220:220:0.0.0.0/0:, - * each entry format Ingress/Egress:protocol:start port: end port:scidrs: + for (NetworkACLTO aclTO: aclList) { + /* example : Ingress:tcp:80:80:0.0.0.0/0:ACCEPT:,Egress:tcp:220:220:0.0.0.0/0:DROP:, + * each entry format Ingress/Egress:protocol:start port: end port:scidrs:action: * reverted entry format Ingress/Egress:reverted:0:0:0: */ if (aclTO.revoked() == true) @@ -80,7 +89,7 @@ public class SetNetworkACLCommand extends NetworkElementCommand{ firstEntry = false; } } - sb.append(":"); + sb.append(":").append(aclTO.getAction()).append(":"); String aclRuleEntry = sb.toString(); toAdd.add(aclRuleEntry); diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java index 1d3f0b84aa6..43cabe751f6 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java @@ -111,4 +111,6 @@ public interface NetworkDao extends GenericDao , StateDao listNetworksByAccount(long accountId, long zoneId, Network.GuestType type, boolean isSystem); List listRedundantNetworks(); + + List listByAclId(long aclId); } diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java index 1bc8973bc50..5b3b526b640 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -104,6 +104,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N AllFieldsSearch.and("physicalNetwork", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); + AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getNetworkACLId(), Op.EQ); SearchBuilder join1 = _ntwkOffDao.createSearchBuilder(); join1.and("isSystem", join1.entity().isSystemOnly(), Op.EQ); join1.and("isRedundant", join1.entity().getRedundantRouter(), Op.EQ); @@ -618,4 +619,12 @@ public class NetworkDaoImpl extends GenericDaoBase implements N sc.setJoinParameters("offerings", "isRedundant", true); return listBy(sc, null); } + + @Override + public List listByAclId(long aclId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("aclId", aclId); + + return listBy(sc, null); + } } diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java index 8e728abd984..7241f1c7f95 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkVO.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkVO.java @@ -160,6 +160,9 @@ public class NetworkVO implements Network { @Column(name="ip6_cidr") String ip6Cidr; + @Column(name="network_acl_id") + Long networkACLId; + public NetworkVO() { this.uuid = UUID.randomUUID().toString(); } @@ -537,4 +540,13 @@ public class NetworkVO implements Network { public void setIp6Gateway(String ip6Gateway) { this.ip6Gateway = ip6Gateway; } + + public void setNetworkACLId(Long networkACLId) { + this.networkACLId = networkACLId; + } + + @Override + public Long getNetworkACLId() { + return networkACLId; + } } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index fce1f719086..4264c9391c6 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -25,6 +25,20 @@ import java.util.Set; import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.network.vpc.VpcGatewayVO; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.network.vpc.VpcProvisioningService; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.dao.StaticRouteDao; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcGatewayDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; @@ -187,16 +201,6 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.StaticRouteVO; -import com.cloud.network.vpc.VpcGatewayVO; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.VpcOffering; -import com.cloud.network.vpc.VpcProvisioningService; -import com.cloud.network.vpc.VpcVO; -import com.cloud.network.vpc.dao.StaticRouteDao; -import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.network.vpc.dao.VpcGatewayDao; -import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -397,6 +401,7 @@ public class ApiDBUtils { static AffinityGroupDao _affinityGroupDao; static AffinityGroupJoinDao _affinityGroupJoinDao; static GlobalLoadBalancingRulesService _gslbService; + static NetworkACLDao _networkACLDao; @Inject private ManagementServer ms; @Inject public AsyncJobManager asyncMgr; @@ -506,6 +511,7 @@ public class ApiDBUtils { @Inject private AffinityGroupDao affinityGroupDao; @Inject private AffinityGroupJoinDao affinityGroupJoinDao; @Inject private GlobalLoadBalancingRulesService gslbService; + @Inject private NetworkACLDao networkACLDao; @PostConstruct void init() { @@ -615,6 +621,7 @@ public class ApiDBUtils { _gslbService = gslbService; // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); + _networkACLDao = networkACLDao; } // /////////////////////////////////////////////////////////// @@ -1290,6 +1297,9 @@ public class ApiDBUtils { return _vpcOfferingDao.findById(offeringId); } + public static NetworkACL findByNetworkACLId(long aclId){ + return _networkACLDao.findById(aclId); + } public static AsyncJob findAsyncJobById(long jobId){ return _asyncJobDao.findById(jobId); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 494ca8e9df8..c1236c6fbd1 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -34,6 +34,13 @@ import java.util.TimeZone; import javax.inject.Inject; +import com.cloud.network.vpc.NetworkACL; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.vm.*; import com.cloud.network.vpc.NetworkACL; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRoute; @@ -89,7 +96,7 @@ import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; import org.apache.cloudstack.api.response.LBStickinessResponse; import org.apache.cloudstack.api.response.LDAPConfigResponse; import org.apache.cloudstack.api.response.LoadBalancerResponse; -import org.apache.cloudstack.api.response.NetworkACLListResponse; +import org.apache.cloudstack.api.response.NetworkACLItemResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkOfferingResponse; import org.apache.cloudstack.api.response.NetworkResponse; @@ -2549,8 +2556,8 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public NetworkACLResponse createNetworkACLItemResponse(FirewallRule networkACL) { - NetworkACLResponse response = new NetworkACLResponse(); + public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem networkACL) { + NetworkACLItemResponse response = new NetworkACLItemResponse(); response.setId(networkACL.getUuid()); response.setProtocol(networkACL.getProtocol()); @@ -2567,9 +2574,9 @@ public class ApiResponseHelper implements ResponseGenerator { response.setTrafficType(networkACL.getTrafficType().toString()); - FirewallRule.State state = networkACL.getState(); + NetworkACLItem.State state = networkACL.getState(); String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { + if (state.equals(NetworkACLItem.State.Revoke)) { stateToSet = "Deleting"; } @@ -2578,6 +2585,11 @@ public class ApiResponseHelper implements ResponseGenerator { response.setState(stateToSet); + NetworkACL acl = ApiDBUtils.findByNetworkACLId(networkACL.getACLId()); + if(acl != null){ + response.setAclId(acl.getUuid()); + } + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); List tagResponses = new ArrayList(); @@ -3835,8 +3847,8 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } - public NetworkACLListResponse createNetworkACLResponse(NetworkACL networkACL) { - NetworkACLListResponse response = new NetworkACLListResponse(); + public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) { + NetworkACLResponse response = new NetworkACLResponse(); response.setId(networkACL.getUuid()); response.setName(networkACL.getName()); response.setDescription(networkACL.getDescription()); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c91243095da..c6fb6b8b41a 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2686,7 +2686,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } //apply network ACLs - if (!_networkACLMgr.applyNetworkACLs(networkId, caller)) { + if (!_networkACLMgr.applyNetworkACL(networkId, caller)) { s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart"); success = false; } @@ -3157,7 +3157,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L //revoke all network ACLs for network try { - if (_networkACLMgr.revokeAllNetworkACLsForNetwork(networkId, callerUserId, caller)) { + if (_networkACLMgr.revokeACLItemsForNetwork(networkId, callerUserId, caller)) { s_logger.debug("Successfully cleaned up NetworkACLs for network id=" + networkId); } else { success = false; diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index 08443698ea0..8b0c58ae86b 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -25,6 +25,7 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.network.vpc.*; import org.apache.log4j.Logger; import com.cloud.dc.DataCenter; @@ -48,11 +49,6 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.StaticRouteProfile; -import com.cloud.network.vpc.Vpc; -import com.cloud.network.vpc.VpcGateway; -import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; @@ -390,7 +386,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc } @Override - public boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException { + public boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException { if (canHandle(config, Service.NetworkACL)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index def4c1ed06f..334a5a108e6 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -579,7 +579,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, break; } break; - case NetworkACL: +/* case NetworkACL: for (NetworkACLServiceProvider element: _networkAclElements) { Network.Provider provider = element.getProvider(); boolean isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider); @@ -590,7 +590,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, if (handled) break; } - break; + break;*/ default: assert(false): "Unexpected fall through in applying rules to the network elements"; s_logger.error("FirewallManager cannot process rules of type " + purpose); diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java index 76c8aa89173..306b1a8fea7 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -25,10 +25,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VpcVirtualNetworkApplianceService; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.StaticRouteProfile; -import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.*; import com.cloud.user.Account; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.VirtualMachineProfile.Param; @@ -57,7 +54,7 @@ public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplian * @return * @throws ResourceUnavailableException */ - boolean applyNetworkACLs(Network network, List rules, List routers) + boolean applyNetworkACLs(Network network, List rules, List routers) throws ResourceUnavailableException; /** diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 611100955e7..dbfd88cb429 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -27,6 +27,7 @@ import java.util.TreeSet; import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.network.vpc.*; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -93,16 +94,6 @@ import com.cloud.network.dao.Site2SiteVpnGatewayVO; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.vpc.NetworkACLManager; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.PrivateIpAddress; -import com.cloud.network.vpc.PrivateIpVO; -import com.cloud.network.vpc.StaticRoute; -import com.cloud.network.vpc.StaticRouteProfile; -import com.cloud.network.vpc.Vpc; -import com.cloud.network.vpc.VpcGateway; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.PrivateIpDao; import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; @@ -704,7 +695,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian } @Override - public boolean applyNetworkACLs(Network network, final List rules, List routers) + public boolean applyNetworkACLs(Network network, final List rules, List routers) throws ResourceUnavailableException { if (rules == null || rules.isEmpty()) { s_logger.debug("No network ACLs to be applied for network " + network.getId()); @@ -719,14 +710,14 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian } - protected boolean sendNetworkACLs(VirtualRouter router, List rules, long guestNetworkId) + protected boolean sendNetworkACLs(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); createNetworkACLsCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - private void createNetworkACLsCommands(List rules, VirtualRouter router, Commands cmds, + private void createNetworkACLsCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; String guestVlan = null; @@ -739,11 +730,11 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian if (rules != null) { rulesTO = new ArrayList(); - for (FirewallRule rule : rules) { - if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) { - _firewallDao.loadSourceCidrs((FirewallRuleVO)rule); - } - NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType()); + for (NetworkACLItem rule : rules) { +// if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) { +// _firewallDao.loadSourceCidrs((FirewallRuleVO)rule); +// } + NetworkACLTO ruleTO = new NetworkACLTO((NetworkACLItemVO)rule, guestVlan, rule.getTrafficType()); rulesTO.add(ruleTO); } } @@ -929,7 +920,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian if (router.getVpcId() != null) { if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.NetworkACL, Provider.VPCVirtualRouter)) { - List networkACLs = _networkACLMgr.listNetworkACLs(guestNetworkId); + List networkACLs = _networkACLMgr.listNetworkACLItems(guestNetworkId); s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + router + " start for guest network id=" + guestNetworkId); if (!networkACLs.isEmpty()) { diff --git a/server/src/com/cloud/network/vpc/NetworkACLItemDao.java b/server/src/com/cloud/network/vpc/NetworkACLItemDao.java new file mode 100644 index 00000000000..739aa8cb741 --- /dev/null +++ b/server/src/com/cloud/network/vpc/NetworkACLItemDao.java @@ -0,0 +1,44 @@ +// 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.utils.db.GenericDao; + +import java.util.List; + +/* + * Data Access Object for network_acl_item table + */ +public interface NetworkACLItemDao extends GenericDao { + + List listByACLAndNotRevoked(long aclId); + + boolean setStateToAdd(NetworkACLItemVO rule); + + boolean revoke(NetworkACLItemVO rule); + + boolean releasePorts(long ipAddressId, String protocol, int[] ports); + + List listByACL(long aclId); + + List listSystemRules(); + + List listByACLTrafficTypeAndNotRevoked(long aclId, NetworkACLItemVO.TrafficType trafficType); + List listByACLTrafficType(long aclId, NetworkACLItemVO.TrafficType trafficType); + + void loadSourceCidrs(NetworkACLItemVO rule); +} 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 00000000000..9b2463187a9 --- /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 sourceCidrs; + + @Column(name="uuid") + String uuid; + + public void setSourceCidrList(List sourceCidrs) { + this.sourceCidrs=sourceCidrs; + } + + @Override + public List 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 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 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; + } +} diff --git a/server/src/com/cloud/network/vpc/NetworkACLManager.java b/server/src/com/cloud/network/vpc/NetworkACLManager.java index 515c2511773..dba91b2f254 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 listNetworkACLs(long guestNtwkId); + List listNetworkACLItems(long guestNtwkId); + boolean applyNetworkACL(long networkId, Account caller) throws ResourceUnavailableException; + + @DB + void revokeRule(NetworkACLItemVO rule, Account caller, long userId, boolean needUsageEvent); } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index b00f8a15a31..a345cc680f0 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 _networkAclElements; + @Inject + NetworkModel _networkModel; + @Inject + NetworkDao _networkDao; + @Override - public boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException { - List rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL); - return _firewallMgr.applyFirewallRules(rules, false, caller); + public boolean revokeACLItemsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException { + Network network = _networkDao.findById(networkId); + List 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 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 FirewallRule createNetworkACLItem(FirewallRule acl) throws NetworkRuleConflictException { - if (acl.getSourceCidrList() == null && (acl.getPurpose() == Purpose.Firewall || acl.getPurpose() == Purpose.NetworkACL)) { - _firewallDao.loadSourceCidrs((FirewallRuleVO)acl); + public List listNetworkACLItems(long guestNtwkId) { + Network network = _networkMgr.getNetwork(guestNtwkId); + return _networkACLItemDao.listByACL(network.getNetworkACLId()); + } + + @Override + public NetworkACLItem getNetworkACLItem(long ruleId) { + return _networkACLItemDao.findById(ruleId); + } + + @Override + public boolean applyNetworkACLtoNetworks(long aclId, Account caller) throws ResourceUnavailableException { + boolean handled = false; + List rules = _networkACLItemDao.listByACL(aclId); + //Find all networks using this ACL + List 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; + } + + @Override + public boolean applyNetworkACL(long networkId, Account caller) throws ResourceUnavailableException { + Network network = _networkDao.findById(networkId); + boolean handled = false; + List 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); + } + 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_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true) - protected FirewallRule createNetworkACL(Account caller, String xId, Integer portStart, - Integer portEnd, String protocol, List 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"); + @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 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"); + } } - - if (network.getVpcId() == null) { - throw new UnsupportedOperationException("Network ACL rules are supported just for VPC networks"); - } - - 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 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 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 ruleCidrList = rule.getSourceCidrList(); - List 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 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,Integer> listNetworkACLItems(ListNetworkACLsCmd cmd) { + public Pair, 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 permittedAccounts = new ArrayList(); - Ternary domainIdRecursiveListProject = + Ternary domainIdRecursiveListProject = new Ternary(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 sb = _firewallDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder 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 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 sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + SearchCriteria 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, Integer> result = _firewallDao.searchAndCount(sc, filter); - return new Pair, Integer>(result.first(), result.second()); - } - - - @Override - public List listNetworkACLs(long guestNtwkId) { - return _firewallDao.listByNetworkAndPurpose(guestNtwkId, Purpose.NetworkACL); - } - - - @Override - public boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException { - - List 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 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, Integer> result = _networkACLItemDao.searchAndCount(sc, filter); + return new Pair, 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, 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(); + } } diff --git a/server/src/com/cloud/network/vpc/NetworkACLVO.java b/server/src/com/cloud/network/vpc/NetworkACLVO.java index 29afc006f46..374ba15142b 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. + } } 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 00000000000..69810e021f0 --- /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 implements NetworkACLItemDao { + + protected final SearchBuilder AllFieldsSearch; + protected final SearchBuilder NotRevokedSearch; + protected final SearchBuilder ReleaseSearch; + protected SearchBuilder VmSearch; + protected final SearchBuilder SystemRuleSearch; + protected final GenericSearchBuilder 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 listByACLAndNotRevoked(long aclId) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean setStateToAdd(NetworkACLItemVO rule) { + SearchCriteria 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 listByACL(long aclId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("aclId", aclId); + + return listBy(sc); + } + + @Override + public List listSystemRules() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List listByACLTrafficTypeAndNotRevoked(long aclId, NetworkACLItem.TrafficType trafficType) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public List 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. + } +} diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index ec19942e054..b7085afb7a8 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; } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index f641993f637..6c8a3dd7870 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;