diff --git a/api/src/com/cloud/agent/api/to/NetworkACLTO.java b/api/src/com/cloud/agent/api/to/NetworkACLTO.java index bd91f778278..398591b120d 100644 --- a/api/src/com/cloud/agent/api/to/NetworkACLTO.java +++ b/api/src/com/cloud/agent/api/to/NetworkACLTO.java @@ -92,7 +92,7 @@ public class NetworkACLTO implements InternalIdentity { } public String getSrcVlanTag() { - return vlanTag; + return vlanTag; } public String getProtocol() { @@ -104,18 +104,18 @@ public class NetworkACLTO implements InternalIdentity { } public Integer getIcmpType(){ - return icmpType; + return icmpType; } public Integer getIcmpCode(){ - return icmpCode; + return icmpCode; } public String getStringPortRange() { - if (portRange == null || portRange.length < 2) - return "0:0"; - else - return NetUtils.portRangeToString(portRange); + if (portRange == null || portRange.length < 2) + return "0:0"; + else + return NetUtils.portRangeToString(portRange); } public boolean revoked() { diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java index 779e54ebd0b..5f068a3828b 100644 --- a/api/src/com/cloud/network/firewall/NetworkACLService.java +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -32,33 +32,85 @@ import com.cloud.user.Account; import com.cloud.utils.Pair; public interface NetworkACLService { - NetworkACLItem getNetworkACLItem(long ruleId); - boolean applyNetworkACL(long aclId, Account caller) throws ResourceUnavailableException; + /** + * Creates Network ACL for the specified VPC + * @param name + * @param description + * @param vpcId + * @return + */ + NetworkACL createNetworkACL(String name, String description, long vpcId); /** + * Get Network ACL with specified Id + * @param id + * @return + */ + NetworkACL getNetworkACL(long id); + + /** + * List NeetworkACLs by Id/Name/Network or Vpc it belongs to + * @param id + * @param name + * @param networkId + * @param vpcId + * @return + */ + Pair,Integer> listNetworkACLs(Long id, String name, Long networkId, Long vpcId); + + /** + * Delete specified network ACL. Deletion fails if the list is not empty + * @param id + * @return + */ + boolean deleteNetworkACL(long id); + + /** + * Associates ACL with specified Network + * @param aclId + * @param networkId + * @return + * @throws ResourceUnavailableException + */ + boolean replaceNetworkACL(long aclId, long networkId) throws ResourceUnavailableException; + + /** + * Applied ACL to associated networks + * @param aclId + * @return + * @throws ResourceUnavailableException + */ + boolean applyNetworkACL(long aclId) throws ResourceUnavailableException; + + /** + * Creates a Network ACL Item within an ACL and applies the ACL to associated networks * @param createNetworkACLCmd * @return */ - NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd) throws NetworkRuleConflictException; + NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd); + /** + * Return ACL item with specified Id * @param ruleId - * @param apply * @return */ - boolean revokeNetworkACLItem(long ruleId, boolean apply); + NetworkACLItem getNetworkACLItem(long ruleId); + /** + * Lists Network ACL Items by Id, Network, ACLId, Traffic Type, protocol * @param listNetworkACLsCmd * @return */ Pair, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd); - NetworkACL createNetworkACL(CreateNetworkACLListCmd cmd); + /** + * Revoked ACL Item with specified Id + * @param ruleId + * @param apply + * @return + */ + boolean revokeNetworkACLItem(long ruleId); - NetworkACL getNetworkACL(long id); - boolean deleteNetworkACL(long id); - Pair,Integer> listNetworkACLs(ListNetworkACLListsCmd listNetworkACLListsCmd); - - boolean replaceNetworkACL(long aclId, long networkId); } diff --git a/api/src/com/cloud/network/vpc/NetworkACLItem.java b/api/src/com/cloud/network/vpc/NetworkACLItem.java index 308696c5024..312fa7390b2 100644 --- a/api/src/com/cloud/network/vpc/NetworkACLItem.java +++ b/api/src/com/cloud/network/vpc/NetworkACLItem.java @@ -64,7 +64,7 @@ public interface NetworkACLItem extends InternalIdentity { State getState(); - long getACLId(); + long getAclId(); Integer getIcmpCode(); 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 b806a598cb9..984ed575156 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 @@ -111,30 +111,6 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { } } - public long getVpcId() { - 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(); - } - - if (vpcId == null) { - throw new InvalidParameterValueException("Can create network ACL only for the ACL belonging to the VPC"); - } - - return vpcId; - } - public NetworkACLItem.TrafficType getTrafficType() { if (trafficType == null) { return NetworkACLItem.TrafficType.Ingress; @@ -164,44 +140,17 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { return number; } - @Override - public void execute() throws ResourceUnavailableException { - UserContext callerContext = UserContext.current(); - boolean success = false; - NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId()); - try { - UserContext.current().setEventDetails("Rule Id: " + getEntityId()); - success = _networkACLService.applyNetworkACL(rule.getACLId(), callerContext.getCaller()); - - // State is different after the rule is applied, so get new object here - NetworkACLItemResponse aclResponse = new NetworkACLItemResponse(); - if (rule != null) { - aclResponse = _responseGenerator.createNetworkACLItemResponse(rule); - setResponseObject(aclResponse); - } - aclResponse.setResponseName(getCommandName()); - } finally { - if (!success || rule == null) { - _networkACLService.revokeNetworkACLItem(getEntityId(), true); - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network ACL"); - } - } - } - public Integer getSourcePortStart() { - if (publicStartPort != null) { - return publicStartPort.intValue(); - } - return null; + return publicStartPort; } public Integer getSourcePortEnd() { if (publicEndPort == null) { if (publicStartPort != null) { - return publicStartPort.intValue(); + return publicStartPort; } } else { - return publicEndPort.intValue(); + return publicEndPort; } return null; @@ -213,39 +162,8 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { @Override public long getEntityOwnerId() { - Vpc vpc = _vpcService.getVpc(getVpcId()); - if (vpc == null) { - throw new InvalidParameterValueException("Invalid vpcId is given"); - } - - Account account = _accountService.getAccount(vpc.getAccountId()); - return account.getId(); - } - - public long getDomainId() { - Vpc vpc = _vpcService.getVpc(getVpcId()); - return vpc.getDomainId(); - } - - @Override - public void create() { - if (getSourceCidrList() != null) { - for (String cidr: getSourceCidrList()){ - if (!NetUtils.isValidCIDR(cidr)){ - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr); - } - } - } - - try { - NetworkACLItem result = _networkACLService.createNetworkACLItem(this); - setEntityId(result.getId()); - setEntityUuid(result.getUuid()); - } catch (NetworkRuleConflictException ex) { - s_logger.info("Network rule conflict: " + ex.getMessage()); - s_logger.trace("Network Rule Conflict: ", ex); - throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage()); - } + Account caller = UserContext.current().getCaller(); + return caller.getAccountId(); } @Override @@ -255,23 +173,7 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { @Override public String getEventDescription() { - //Network network = _networkService.getNetwork(networkId); - return ("Creating Network ACL Item for protocol:" + this.getProtocol()); - } - - public long getAccountId() { - Vpc vpc = _vpcService.getVpc(getVpcId()); - return vpc.getAccountId(); - } - - @Override - public String getSyncObjType() { - return BaseAsyncCmd.networkSyncObject; - } - - @Override - public Long getSyncObjId() { - return getNetworkId(); + return "Creating Network ACL Item"; } public Integer getIcmpCode() { @@ -293,12 +195,40 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd { return null; } - @Override - public AsyncJob.Type getInstanceType() { - return AsyncJob.Type.FirewallRule; - } - public Long getACLId() { return aclId; } + + @Override + public void create() { + NetworkACLItem result = _networkACLService.createNetworkACLItem(this); + setEntityId(result.getId()); + setEntityUuid(result.getUuid()); + } + + @Override + public void execute() throws ResourceUnavailableException { + boolean success = false; + NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId()); + try { + UserContext.current().setEventDetails("Rule Id: " + getEntityId()); + success = _networkACLService.applyNetworkACL(rule.getAclId()); + + // State is different after the rule is applied, so get new object here + rule = _networkACLService.getNetworkACLItem(getEntityId()); + NetworkACLItemResponse aclResponse = new NetworkACLItemResponse(); + if (rule != null) { + aclResponse = _responseGenerator.createNetworkACLItemResponse(rule); + setResponseObject(aclResponse); + } + aclResponse.setResponseName(getCommandName()); + } finally { + if (!success || rule == null) { + _networkACLService.revokeNetworkACLItem(getEntityId()); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network ACL Item"); + } + } + } + } + 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 0cc460d2b78..591a3541a53 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 @@ -23,7 +23,12 @@ import com.cloud.network.vpc.NetworkACL; 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.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.log4j.Logger; @@ -75,15 +80,13 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd { @Override public void create() { - NetworkACL result = _networkACLService.createNetworkACL(this); + NetworkACL result = _networkACLService.createNetworkACL(getName(), getDescription(), getVpcId()); setEntityId(result.getId()); setEntityUuid(result.getUuid()); } @Override public void execute() throws ResourceUnavailableException { - UserContext callerContext = UserContext.current(); - boolean success = false; NetworkACL acl = _networkACLService.getNetworkACL(getEntityId()); if(acl != null){ NetworkACLResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl); 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 faf46308d92..d35b22c532a 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 @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.user.network; import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.user.Account; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -49,10 +50,6 @@ public class DeleteNetworkACLCmd extends BaseAsyncCmd { required=true, description="the ID of the network ACL") private Long id; - // unexposed parameter needed for events logging - @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType = AccountResponse.class, - expose=false) - private Long ownerId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -81,31 +78,20 @@ public class DeleteNetworkACLCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - return 2L; -/* if (ownerId == null) { - NetworkACLItem rule = _networkACLService.getNetworkACLItem(id); - if (rule == null) { - throw new InvalidParameterValueException("Unable to find network ACL by id=" + id); - } else { - - NetworkACL acl = _networkACLService - rule.getACLId(); - - } - } - return ownerId;*/ + Account caller = UserContext.current().getCaller(); + return caller.getAccountId(); } @Override public void execute() throws ResourceUnavailableException { - UserContext.current().setEventDetails("Network ACL Id: " + id); - boolean result = _networkACLService.revokeNetworkACLItem(id, true); + UserContext.current().setEventDetails("Network ACL Item Id: " + id); + boolean result = _networkACLService.revokeNetworkACLItem(id); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete network ACL Item"); } } 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 42ecd8d155d..379b44a0d50 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 @@ -23,6 +23,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpc.NetworkACL; 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.AccountResponse; @@ -48,7 +49,7 @@ public class DeleteNetworkACLListCmd extends BaseAsyncCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public Long getId() { + public long getId() { return id; } @@ -72,18 +73,8 @@ public class DeleteNetworkACLListCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - NetworkACL acl = _networkACLService.getNetworkACL(id); - if (acl == null) { - throw new InvalidParameterValueException("Unable to find network ACL by id=" + id); - } 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=" + id); - } - } + Account caller = UserContext.current().getCaller(); + return caller.getAccountId(); } @Override 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 55d61477ece..bb825d9f9f9 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 @@ -16,23 +16,23 @@ // under the License. package org.apache.cloudstack.api.command.user.network; -import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpc.NetworkACL; import com.cloud.utils.Pair; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; +import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.NetworkACLResponse; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.VpcResponse; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.List; @APICommand(name = "listNetworkACLLists", description="Lists all network ACLs", responseObject=NetworkACLResponse.class) -public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { +public class ListNetworkACLListsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListNetworkACLListsCmd.class.getName()); private static final String s_name = "listnetworkacllistsresponse"; @@ -48,6 +48,14 @@ public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { description="list network ACLs by network Id") private Long networkId; + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.UUID, entityType = VpcResponse.class, + description="list network ACLs by Vpc Id") + private Long vpcId; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list network ACLs by specified name") + private String name; + + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -60,6 +68,14 @@ public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { return id; } + public Long getVpcId() { + return vpcId; + } + + public String getName(){ + return name; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -71,7 +87,7 @@ public class ListNetworkACLListsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - Pair,Integer> result = _networkACLService.listNetworkACLs(this); + Pair,Integer> result = _networkACLService.listNetworkACLs(getId(), getName(), getNetworkId(), getVpcId()); ListResponse response = new ListResponse(); List aclResponses = new ArrayList(); 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 53e19d72f71..df21a722408 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 @@ -24,10 +24,7 @@ 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.NetworkACLItemResponse; -import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.*; import org.apache.log4j.Logger; import com.cloud.network.rules.FirewallRule; @@ -43,16 +40,26 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = FirewallRuleResponse.class, - description="Lists network ACL with the specified ID.") + description="Lists network ACL Item with the specified ID") private Long id; @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, - description="list network ACLs by network Id") + description="list network ACL Items by network Id") private Long networkId; - @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list network ACLs by traffic type - Ingress or Egress") + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list network ACL Items by traffic type - Ingress or Egress") private String trafficType; + @Parameter(name=ApiConstants.ACL_ID, type=CommandType.UUID, entityType = NetworkACLResponse.class, + description="list network ACL Items by ACL Id") + private Long aclId; + + @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="list network ACL Items by Protocol") + private String protocol; + + @Parameter(name=ApiConstants.ACTION, type=CommandType.STRING, description="list network ACL Items by Action") + private String action; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -69,6 +76,18 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { return trafficType; } + public Long getAclId(){ + return aclId; + } + + public String getProtocol() { + return protocol; + } + + public String getAction() { + return action; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// 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 index 78e0b1a61f3..b8abc788b8b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java @@ -21,6 +21,7 @@ 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.Account; import com.cloud.user.UserContext; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.response.NetworkACLResponse; @@ -77,18 +78,8 @@ public class ReplaceNetworkACLListCmd extends BaseAsyncCmd { @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); - } - } + Account caller = UserContext.current().getCaller(); + return caller.getAccountId(); } @Override diff --git a/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java index 177c42b0412..400a4db7631 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java @@ -62,6 +62,12 @@ public class NetworkACLItemResponse extends BaseResponse { @SerializedName(ApiConstants.ACL_ID) @Param(description="the ID of the ACL this item belongs to") private String aclId; + @SerializedName(ApiConstants.NUMBER) @Param(description= "Number of the ACL Item") + private Integer number; + + @SerializedName(ApiConstants.ACTION) @Param(description="Action of ACL Item. Allow/Deny") + private String action; + public void setId(String id) { this.id = id; } @@ -105,4 +111,12 @@ public class NetworkACLItemResponse extends BaseResponse { public void setAclId(String aclId) { this.aclId = aclId; } + + public void setNumber(Integer number) { + this.number = number; + } + + public void setAction(String action) { + this.action = action; + } } diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index cdce3f9164b..a41797ec41c 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -690,6 +690,7 @@ + diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index c1236c6fbd1..7b4c1f9c921 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2556,42 +2556,43 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem networkACL) { + public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem aclItem) { NetworkACLItemResponse response = new NetworkACLItemResponse(); - response.setId(networkACL.getUuid()); - response.setProtocol(networkACL.getProtocol()); - if (networkACL.getSourcePortStart() != null) { - response.setStartPort(Integer.toString(networkACL.getSourcePortStart())); + response.setId(aclItem.getUuid()); + response.setProtocol(aclItem.getProtocol()); + if (aclItem.getSourcePortStart() != null) { + response.setStartPort(Integer.toString(aclItem.getSourcePortStart())); } - if (networkACL.getSourcePortEnd() != null) { - response.setEndPort(Integer.toString(networkACL.getSourcePortEnd())); + if (aclItem.getSourcePortEnd() != null) { + response.setEndPort(Integer.toString(aclItem.getSourcePortEnd())); } - List cidrs = ApiDBUtils.findFirewallSourceCidrs(networkACL.getId()); - response.setCidrList(StringUtils.join(cidrs, ",")); + response.setCidrList(StringUtils.join(aclItem.getSourceCidrList(), ",")); - response.setTrafficType(networkACL.getTrafficType().toString()); + response.setTrafficType(aclItem.getTrafficType().toString()); - NetworkACLItem.State state = networkACL.getState(); + NetworkACLItem.State state = aclItem.getState(); String stateToSet = state.toString(); if (state.equals(NetworkACLItem.State.Revoke)) { stateToSet = "Deleting"; } - response.setIcmpCode(networkACL.getIcmpCode()); - response.setIcmpType(networkACL.getIcmpType()); + response.setIcmpCode(aclItem.getIcmpCode()); + response.setIcmpType(aclItem.getIcmpType()); response.setState(stateToSet); + response.setNumber(aclItem.getNumber()); + response.setAction(aclItem.getAction().toString()); - NetworkACL acl = ApiDBUtils.findByNetworkACLId(networkACL.getACLId()); + NetworkACL acl = ApiDBUtils.findByNetworkACLId(aclItem.getAclId()); if(acl != null){ response.setAclId(acl.getUuid()); } //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, aclItem.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 666777159b9..29c04ed8304 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.applyACLToNetwork(networkId, caller)) { + if (!_networkACLMgr.applyACLToNetwork(networkId)) { s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart"); success = false; } @@ -3310,28 +3310,26 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L success = false; } - //revoke all Network ACLs for the network w/o applying them in the DB - List networkACLs = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Releasing " + networkACLs.size() + " Network ACLs for network id=" + networkId + - " as a part of shutdownNetworkRules"); - } + if(network.getVpcId() != null){ + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing Network ACL Items for network id=" + networkId + + " as a part of shutdownNetworkRules"); + } - for (FirewallRuleVO networkACL : networkACLs) { - s_logger.trace("Marking network ACL " + networkACL + " with Revoke state"); - networkACL.setState(FirewallRule.State.Revoke); - } - - try { - if (!_firewallMgr.applyRules(networkACLs, true, false)) { - s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules"); + try { + //revoke all Network ACLs for the network w/o applying them in the DB + if (!_networkACLMgr.revokeACLItemsForNetwork(networkId, callerUserId, caller)) { + s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules"); + success = false; + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules due to ", ex); success = false; } - } catch (ResourceUnavailableException ex) { - s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules due to ", ex); - success = false; + } + //release all static nats for the network if (!_rulesMgr.applyStaticNatForNetwork(networkId, false, caller, true)) { s_logger.warn("Failed to disable static nats as part of shutdownNetworkRules for network id " + networkId); diff --git a/server/src/com/cloud/network/vpc/NetworkACLItemDao.java b/server/src/com/cloud/network/vpc/NetworkACLItemDao.java index d24f082b5be..8f70ac768c9 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLItemDao.java +++ b/server/src/com/cloud/network/vpc/NetworkACLItemDao.java @@ -25,15 +25,12 @@ import java.util.List; */ public interface NetworkACLItemDao extends GenericDao { - List listByACLAndNotRevoked(long aclId); - boolean setStateToAdd(NetworkACLItemVO rule); boolean revoke(NetworkACLItemVO rule); List listByACL(long aclId); - List listByACLTrafficTypeAndNotRevoked(long aclId, NetworkACLItemVO.TrafficType trafficType); - List listByACLTrafficType(long aclId, NetworkACLItemVO.TrafficType trafficType); - + int getMaxNumberByACL(long aclId); + } diff --git a/server/src/com/cloud/network/vpc/NetworkACLItemVO.java b/server/src/com/cloud/network/vpc/NetworkACLItemVO.java index 5df97a96098..71ccebf0796 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLItemVO.java +++ b/server/src/com/cloud/network/vpc/NetworkACLItemVO.java @@ -49,7 +49,7 @@ public class NetworkACLItemVO implements NetworkACLItem { Date created; @Column(name="acl_id") - Long ACLId; + long aclId; @Column(name="icmp_code") Integer icmpCode; @@ -74,6 +74,27 @@ public class NetworkACLItemVO implements NetworkACLItem { @Enumerated(value=EnumType.STRING) Action action; + 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, Action action, int number) { + this.sourcePortStart = portStart; + this.sourcePortEnd = portEnd; + this.protocol = protocol; + this.aclId = aclId; + this.state = State.Staged; + this.icmpCode = icmpCode; + this.icmpType = icmpType; + setSourceCidrList(sourceCidrs); + this.uuid = UUID.randomUUID().toString(); + this.trafficType = trafficType; + this.action = action; + this.number = number; + } + public void setSourceCidrList(List sourceCidrs) { if(sourceCidrs == null){ this.sourceCidrs = null; @@ -133,39 +154,15 @@ public class NetworkACLItemVO implements NetworkACLItem { } @Override - public long getACLId() { - return ACLId; + public long getAclId() { + return aclId; } 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, Action action, int number) { - this.sourcePortStart = portStart; - this.sourcePortEnd = portEnd; - this.protocol = protocol; - this.ACLId = aclId; - this.state = State.Staged; - this.icmpCode = icmpCode; - this.icmpType = icmpType; - setSourceCidrList(sourceCidrs); - this.uuid = UUID.randomUUID().toString(); - this.trafficType = trafficType; - this.action = action; - this.number = number; - } - - - public NetworkACLItemVO(int port, String protocol, long aclId, List sourceCidrs, Integer icmpCode, Integer icmpType, Action action, int number) { - this(port, port, protocol, aclId, sourceCidrs, icmpCode, icmpType, null, action, number); - } @Override public String toString() { diff --git a/server/src/com/cloud/network/vpc/NetworkACLManager.java b/server/src/com/cloud/network/vpc/NetworkACLManager.java index 3be15fadbe9..1b1e958231e 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManager.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManager.java @@ -19,6 +19,7 @@ package com.cloud.network.vpc; import java.util.List; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.firewall.NetworkACLService; import com.cloud.network.rules.FirewallRule; import com.cloud.user.Account; @@ -26,9 +27,81 @@ import com.cloud.utils.db.DB; import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd; -public interface NetworkACLManager extends NetworkACLService{ - +public interface NetworkACLManager{ + /** + * Creates Network ACL for the specified VPC + * @param name + * @param description + * @param vpcId + * @return + */ + NetworkACL createNetworkACL(String name, String description, long vpcId); + + /** + * Fetches Network ACL with specified Id + * @param id + * @return + */ + NetworkACL getNetworkACL(long id); + + /** + * Applies the items in the ACL to all associated networks + * @param aclId + * @return + * @throws ResourceUnavailableException + */ + boolean applyNetworkACL(long aclId) throws ResourceUnavailableException; + + /** + * Deletes the specified Network ACL + * @param id + * @return + */ + boolean deleteNetworkACL(NetworkACL acl); + + /** + * Associates acl with a network and applies the ACLItems + * @param acl + * @param network + * @return + */ + boolean replaceNetworkACL(NetworkACL acl, NetworkVO network) throws ResourceUnavailableException; + + /** + * Creates a Network ACL Item within an ACL and applies it to associated networks + * @param sourcePortStart + * @param sourcePortEnd + * @param protocol + * @param sourceCidrList + * @param icmpCode + * @param icmpType + * @param trafficType + * @param aclId + * @param action + * @param number + * @return + */ + NetworkACLItem createNetworkACLItem(Integer sourcePortStart, Integer sourcePortEnd, String protocol, + List sourceCidrList, Integer icmpCode, Integer icmpType, + NetworkACLItem.TrafficType trafficType, Long aclId, String action, Integer number); + + /** + * Returns Network ACL Item with specified Id + * @param ruleId + * @return + */ + NetworkACLItem getNetworkACLItem(long ruleId); + + /** + * Revoke ACL Item and apply changes + * @param ruleId + * @return + */ + boolean revokeNetworkACLItem(long ruleId); + + /** + * Revoke ACL Items for network and remove them in back-end. Db is not updated * @param networkId * @param userId * @param caller @@ -39,9 +112,6 @@ public interface NetworkACLManager extends NetworkACLService{ List listNetworkACLItems(long guestNtwkId); - boolean applyNetworkACL(long aclId, Account caller) throws ResourceUnavailableException; + boolean applyACLToNetwork(long networkId) throws ResourceUnavailableException; - void removeRule(NetworkACLItem rule); - - boolean applyACLToNetwork(long networkId, Account caller) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index 8c6cf35f341..20fd5866524 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -16,62 +16,36 @@ // under the License. package com.cloud.network.vpc; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -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; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import org.apache.cloudstack.acl.SecurityChecker.AccessType; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -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.firewall.NetworkACLService; -import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.tags.ResourceTagVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.vpc.NetworkACLItem.State; +import com.cloud.network.vpc.dao.NetworkACLDao; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.UserContext; -import com.cloud.utils.Pair; -import com.cloud.utils.Ternary; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.util.List; @Component -@Local(value = { NetworkACLService.class, NetworkACLManager.class}) +@Local(value = { NetworkACLManager.class}) public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLManager{ private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class); @@ -94,62 +68,22 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana @Inject NetworkDao _networkDao; - @Override - 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); - if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) { - aclItem.setState(State.Revoke); - } - } - - //List ACLsToRevoke = _networkACLItemDao.listByNetwork(networkId); - - // now send everything to the backend - boolean success = applyACLItemsToNetwork(network.getId(), aclItems, caller); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " - + aclItems.size()); - } - - return success; + public NetworkACL createNetworkACL(String name, String description, long vpcId) { + NetworkACLVO acl = new NetworkACLVO(name, description, vpcId); + _networkACLDao.persist(acl); + return acl; } @Override - 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 applyNetworkACL(long aclId, Account caller) throws ResourceUnavailableException { + public boolean applyNetworkACL(long aclId) 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){ //Failure case?? - handled = applyACLItemsToNetwork(network.getId(), rules, caller); + handled = applyACLItemsToNetwork(network.getId(), rules); } if(handled){ for (NetworkACLItem rule : rules) { @@ -166,19 +100,151 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana } @Override - public void removeRule(NetworkACLItem rule) { + public NetworkACL getNetworkACL(long id) { + return _networkACLDao.findById(id); + } + + @Override + public boolean deleteNetworkACL(NetworkACL acl) { + List aclItems = _networkACLItemDao.listByACL(acl.getId()); + if(aclItems.size() > 0){ + throw new CloudRuntimeException("ACL is not empty. Cannot delete network ACL: "+acl.getUuid()); + } + return _networkACLDao.remove(acl.getId()); + } + + @Override + public boolean replaceNetworkACL(NetworkACL acl, NetworkVO network) throws ResourceUnavailableException { + if(network.getVpcId() != acl.getVpcId()){ + throw new InvalidParameterValueException("Network: "+network.getUuid()+" and ACL: "+acl.getUuid()+" do not belong to the same VPC"); + } + network.setNetworkACLId(acl.getId()); + if(_networkDao.update(network.getId(), network)){ + return applyACLToNetwork(network.getId()); + } + return false; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "creating network ACL Item", create = true) + public NetworkACLItem createNetworkACLItem(Integer portStart, Integer portEnd, String protocol, List sourceCidrList, + Integer icmpCode, Integer icmpType, NetworkACLItem.TrafficType trafficType, Long aclId, + String action, Integer number) { + NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow; + if("deny".equals(action)){ + ruleAction = NetworkACLItem.Action.Deny; + } + // If number is null, set it to currentMax + 1 + if(number == null){ + number = _networkACLItemDao.getMaxNumberByACL(aclId) + 1; + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + NetworkACLItemVO newRule = new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(), aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, number); + newRule = _networkACLItemDao.persist(newRule); + + //ToDo: Is this required now with number?? + //detectNetworkACLConflict(newRule); + + if (!_networkACLItemDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + UserContext.current().setEventDetails("ACL Item Id: " + newRule.getId()); + + txn.commit(); + + return getNetworkACLItem(newRule.getId()); + } + + @Override + public NetworkACLItem getNetworkACLItem(long ruleId) { + return _networkACLItemDao.findById(ruleId); + } + + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "revoking network acl", async = true) + public boolean revokeNetworkACLItem(long ruleId) { + + NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId); + + revokeRule(rule); + + boolean success = false; + + try { + applyNetworkACL(rule.getAclId()); + success = true; + } catch (ResourceUnavailableException e) { + return false; + } + + return success; + } + + @DB + private void revokeRule(NetworkACLItemVO rule) { + 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()); + } else if (rule.getState() == State.Add || rule.getState() == State.Active) { + rule.setState(State.Revoke); + _networkACLItemDao.update(rule.getId(), rule); + } + } + + @Override + 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 update in DB + if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) { + aclItem.setState(State.Revoke); + } + } + + boolean success = applyACLItemsToNetwork(network.getId(), aclItems); + + if (s_logger.isDebugEnabled() && success) { + s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " + + aclItems.size()); + } + + return success; + } + + @Override + public List listNetworkACLItems(long guestNtwkId) { + Network network = _networkMgr.getNetwork(guestNtwkId); + return _networkACLItemDao.listByACL(network.getNetworkACLId()); + } + + private void removeRule(NetworkACLItem rule) { //remove the rule _networkACLItemDao.remove(rule.getId()); } @Override - public boolean applyACLToNetwork(long networkId, Account caller) throws ResourceUnavailableException { + public boolean applyACLToNetwork(long networkId) throws ResourceUnavailableException { Network network = _networkDao.findById(networkId); List rules = _networkACLItemDao.listByACL(network.getNetworkACLId()); - return applyACLItemsToNetwork(networkId, rules, caller); + return applyACLItemsToNetwork(networkId, rules); } - public boolean applyACLItemsToNetwork(long networkId, List rules, Account caller) throws ResourceUnavailableException { + public boolean applyACLItemsToNetwork(long networkId, List rules) throws ResourceUnavailableException { Network network = _networkDao.findById(networkId); boolean handled = false; for (NetworkACLServiceProvider element: _networkAclElements) { @@ -194,284 +260,4 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana return handled; } - @Override - public NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd) throws NetworkRuleConflictException { - return createNetworkACLItem(UserContext.current().getCaller(), aclItemCmd.getSourcePortStart(), - aclItemCmd.getSourcePortEnd(), aclItemCmd.getProtocol(), aclItemCmd.getSourceCidrList(), aclItemCmd.getIcmpCode(), - aclItemCmd.getIcmpType(), aclItemCmd.getNetworkId(), aclItemCmd.getTrafficType(), aclItemCmd.getACLId(), aclItemCmd.getAction(), aclItemCmd.getNumber()); - } - - @DB - @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "creating network ACL Item", create = true) - protected NetworkACLItem createNetworkACLItem(Account caller, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, - Integer icmpCode, Integer icmpType, Long networkId, NetworkACLItem.TrafficType trafficType, Long aclId, - String action, Integer number) 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"); - } - } - - 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.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"); - } - - 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())) { - throw new InvalidParameterValueException("Invalid icmp type; should belong to [0-255] range"); - } - if (icmpCode != null) { - if (icmpCode.longValue() != -1 && !NetUtils.validateIcmpCode(icmpCode.longValue())) { - throw new InvalidParameterValueException("Invalid icmp code; should belong to [0-15] range and can" + - " be defined when icmpType belongs to [0-40] range"); - } - } - } - - NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow; - if("deny".equals(action)){ - ruleAction = NetworkACLItem.Action.Deny; - } - // If number is null, set it to currentMax + 1 - validateNetworkACLItem(caller, portStart, portEnd, protocol); - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - - NetworkACLItemVO newRule = new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(), aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, number); - newRule = _networkACLItemDao.persist(newRule); - - //ToDo: Is this required now with?? - //detectNetworkACLConflict(newRule); - - if (!_networkACLItemDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); - } - UserContext.current().setEventDetails("ACL Item Id: " + newRule.getId()); - - txn.commit(); - - return getNetworkACLItem(newRule.getId()); - } - - 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); - } - if (portEnd != null && !NetUtils.isValidPort(portEnd)) { - throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd); - } - - // start port can't be bigger than end port - if (portStart != null && portEnd != null && portStart > portEnd) { - throw new InvalidParameterValueException("Start port can't be bigger than end port"); - } - } - - @Override - public boolean revokeNetworkACLItem(long ruleId, boolean apply) { - Account caller = UserContext.current().getCaller(); - long userId = UserContext.current().getCallerUserId(); - return revokeNetworkACLItem(ruleId, apply, caller, userId); - } - - @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); - - revokeRule(rule, caller, userId, false); - - boolean success = false; - - if (apply) { - try { - applyNetworkACL(rule.getACLId(), caller); - success = true; - } catch (ResourceUnavailableException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } else { - success = true; - } - - return success; - } - - - @Override - public Pair, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd) { - Long networkId = cmd.getNetworkId(); - Long id = cmd.getId(); - String trafficType = cmd.getTrafficType(); - Map tags = cmd.getTags(); - - Account caller = UserContext.current().getCaller(); - List permittedAccounts = new ArrayList(); - - Ternary domainIdRecursiveListProject = - new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, - domainIdRecursiveListProject, cmd.listAll(), false); - Long domainId = domainIdRecursiveListProject.first(); - Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - - 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("aclId", sb.entity().getACLId(), 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++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); - } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); - } - - SearchCriteria sc = sb.create(); - // _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - if (id != null) { - sc.setParameters("id", id); - } - - if (networkId != null) { - Network network = _networkDao.findById(networkId); - sc.setParameters("aclId", network.getNetworkACLId()); - } - - if (trafficType != null) { - sc.setParameters("trafficType", trafficType); - } - - if (tags != null && !tags.isEmpty()) { - int count = 0; - sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.NetworkACL.toString()); - for (String key : tags.keySet()) { - sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); - sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); - count++; - } - } - - Pair, Integer> result = _networkACLItemDao.searchAndCount(sc, filter); - return new Pair, Integer>(result.first(), result.second()); - } - - @Override - public NetworkACL createNetworkACL(CreateNetworkACLListCmd cmd) { - NetworkACLVO acl = new NetworkACLVO(cmd.getName(), cmd.getDescription(), cmd.getVpcId()); - _networkACLDao.persist(acl); - return acl; - } - - @Override - public NetworkACL getNetworkACL(long id) { - return _networkACLDao.findById(id); - } - - @Override - public boolean deleteNetworkACL(long id) { - return _networkACLDao.remove(id); - } - - @Override - public Pair, Integer> listNetworkACLs(ListNetworkACLListsCmd listNetworkACLListsCmd) { - SearchBuilder sb = _networkACLDao.createSearchBuilder(); - SearchCriteria sc = sb.create(); - Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null); - Pair, Integer> acls = _networkACLDao.searchAndCount(sc, filter); - return new Pair, Integer>(acls.first(), acls.second()); - } - - @Override - public boolean replaceNetworkACL(long aclId, long networkId) { - NetworkVO network = _networkDao.findById(networkId); - if(network == null){ - throw new InvalidParameterValueException("Unable to find Network: " +networkId); - } - NetworkACL acl = _networkACLDao.findById(aclId); - if(acl == null){ - throw new InvalidParameterValueException("Unable to find NetworkACL: " +aclId); - } - if(network.getVpcId() == null){ - throw new InvalidParameterValueException("Network does not belong to VPC: " +networkId); - } - if(network.getVpcId() != acl.getVpcId()){ - throw new InvalidParameterValueException("Network: "+networkId+" and ACL: "+aclId+" do not belong to the same VPC"); - } - network.setNetworkACLId(aclId); - return _networkDao.update(networkId, network); - } - - @DB - private 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/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java new file mode 100644 index 00000000000..381bc6a35d1 --- /dev/null +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -0,0 +1,372 @@ +// 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.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.firewall.NetworkACLService; +import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.UserContext; +import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.net.NetUtils; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +@Component +@Local(value = { NetworkACLService.class}) +public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLService{ + private static final Logger s_logger = Logger.getLogger(NetworkACLServiceImpl.class); + + @Inject + AccountManager _accountMgr; + @Inject + NetworkModel _networkMgr; + @Inject + VpcManager _vpcMgr; + @Inject + ResourceTagDao _resourceTagDao; + @Inject + NetworkACLDao _networkACLDao; + @Inject + NetworkACLItemDao _networkACLItemDao; + @Inject + List _networkAclElements; + @Inject + NetworkModel _networkModel; + @Inject + NetworkDao _networkDao; + @Inject + NetworkACLManager _networkAclMgr; + + @Override + public NetworkACL createNetworkACL(String name, String description, long vpcId) { + Account caller = UserContext.current().getCaller(); + Vpc vpc = _vpcMgr.getVpc(vpcId); + if(vpc == null){ + throw new InvalidParameterValueException("Unable to find VPC"); + } + _accountMgr.checkAccess(caller, null, true, vpc); + return _networkAclMgr.createNetworkACL(name, description, vpcId); + } + + @Override + public NetworkACL getNetworkACL(long id) { + return _networkAclMgr.getNetworkACL(id); + } + + @Override + public Pair, Integer> listNetworkACLs(Long id, String name, Long networkId, Long vpcId) { + SearchBuilder sb = _networkACLDao.createSearchBuilder(); + sb.and("id", sb.entity().getId(), Op.EQ); + sb.and("name", sb.entity().getName(), Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), Op.EQ); + + if(networkId != null){ + SearchBuilder network = _networkDao.createSearchBuilder(); + network.and("networkId", network.entity().getId(), Op.EQ); + sb.join("networkJoin", network, sb.entity().getId(), network.entity().getNetworkACLId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + if(id != null){ + sc.setParameters("id", id); + } + + if(name != null){ + sc.setParameters("name", name); + } + + if(vpcId != null){ + sc.setParameters("vpcId", name); + } + + if(networkId != null){ + sc.setJoinParameters("networkJoin", "networkId", networkId); + } + + Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null); + Pair, Integer> acls = _networkACLDao.searchAndCount(sc, filter); + return new Pair, Integer>(acls.first(), acls.second()); + } + + @Override + public boolean deleteNetworkACL(long id) { + Account caller = UserContext.current().getCaller(); + NetworkACL acl = _networkACLDao.findById(id); + if(acl == null) { + throw new InvalidParameterValueException("Unable to find specified ACL"); + } + Vpc vpc = _vpcMgr.getVpc(acl.getVpcId()); + if(vpc == null){ + throw new InvalidParameterValueException("Unable to find specified VPC associated with the ACL"); + } + _accountMgr.checkAccess(caller, null, true, vpc); + return _networkAclMgr.deleteNetworkACL(acl); + } + + @Override + public boolean replaceNetworkACL(long aclId, long networkId) throws ResourceUnavailableException { + Account caller = UserContext.current().getCaller(); + + NetworkVO network = _networkDao.findById(networkId); + if(network == null){ + throw new InvalidParameterValueException("Unable to find specified Network"); + } + + NetworkACL acl = _networkACLDao.findById(aclId); + if(acl == null){ + throw new InvalidParameterValueException("Unable to find specified NetworkACL"); + } + + if(network.getVpcId() == null){ + throw new InvalidParameterValueException("Network is not part of a VPC: "+ network.getUuid()); + } + + Vpc vpc = _vpcMgr.getVpc(acl.getVpcId()); + if(vpc == null){ + throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL"); + } + _accountMgr.checkAccess(caller, null, true, vpc); + if(network.getVpcId() != acl.getVpcId()){ + throw new InvalidParameterValueException("Network: "+networkId+" and ACL: "+aclId+" do not belong to the same VPC"); + } + return _networkAclMgr.replaceNetworkACL(acl, network); + } + + @Override + public NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd){ + Account caller = UserContext.current().getCaller(); + Long aclId = aclItemCmd.getACLId(); + if(aclId == null){ + //ACL id is not specified. Get the ACL details from network + if(aclItemCmd.getNetworkId() == null){ + throw new InvalidParameterValueException("Cannot create Network ACL Item. ACL Id or network Id is required"); + } + Network network = _networkMgr.getNetwork(aclItemCmd.getNetworkId()); + if(network.getVpcId() == null){ + throw new InvalidParameterValueException("Network: "+network.getUuid()+" does not belong to VPC"); + } + aclId = network.getNetworkACLId(); + } + + NetworkACL acl = _networkAclMgr.getNetworkACL(aclId); + if(acl == null){ + throw new InvalidParameterValueException("Unable to find specified ACL"); + } + + Vpc vpc = _vpcMgr.getVpc(acl.getVpcId()); + if(vpc == null){ + throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL"); + } + _accountMgr.checkAccess(caller, null, true, vpc); + + Account aclOwner = _accountMgr.getAccount(vpc.getAccountId()); + _accountMgr.checkAccess(aclOwner, SecurityChecker.AccessType.ModifyEntry, false, acl); + + validateNetworkACLItem(aclItemCmd.getSourcePortStart(), aclItemCmd.getSourcePortEnd(), aclItemCmd.getSourceCidrList(), + aclItemCmd.getProtocol(), aclItemCmd.getIcmpCode(), aclItemCmd.getIcmpType(), aclItemCmd.getAction()); + + return _networkAclMgr.createNetworkACLItem(aclItemCmd.getSourcePortStart(), + aclItemCmd.getSourcePortEnd(), aclItemCmd.getProtocol(), aclItemCmd.getSourceCidrList(), aclItemCmd.getIcmpCode(), + aclItemCmd.getIcmpType(), aclItemCmd.getTrafficType(), aclId, aclItemCmd.getAction(), aclItemCmd.getNumber()); + } + + private void validateNetworkACLItem(Integer portStart, Integer portEnd, List sourceCidrList, String protocol, Integer icmpCode, + Integer icmpType, String action) { + + if (portStart != null && !NetUtils.isValidPort(portStart)) { + throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart); + } + if (portEnd != null && !NetUtils.isValidPort(portEnd)) { + throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd); + } + + // start port can't be bigger than end port + if (portStart != null && portEnd != null && portStart > portEnd) { + throw new InvalidParameterValueException("Start port can't be bigger than end port"); + } + + if (sourceCidrList != null) { + for (String cidr: sourceCidrList){ + if (!NetUtils.isValidCIDR(cidr)){ + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr); + } + } + } + + // 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"); + } + + 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())) { + throw new InvalidParameterValueException("Invalid icmp type; should belong to [0-255] range"); + } + if (icmpCode != null) { + if (icmpCode.longValue() != -1 && !NetUtils.validateIcmpCode(icmpCode.longValue())) { + throw new InvalidParameterValueException("Invalid icmp code; should belong to [0-15] range and can" + + " be defined when icmpType belongs to [0-40] range"); + } + } + } + + if(action != null){ + try { + NetworkACLItem.Action.valueOf(action); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException("Invalid action. Allowed actions are Aloow and Deny"); + } + } + } + + @Override + public NetworkACLItem getNetworkACLItem(long ruleId) { + return _networkAclMgr.getNetworkACLItem(ruleId); + } + + @Override + public boolean applyNetworkACL(long aclId) throws ResourceUnavailableException { + return _networkAclMgr.applyNetworkACL(aclId); + } + + @Override + public Pair, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd) { + Long networkId = cmd.getNetworkId(); + Long id = cmd.getId(); + Long aclId = cmd.getAclId(); + String trafficType = cmd.getTrafficType(); + String protocol = cmd.getProtocol(); + String action = cmd.getAction(); + Map tags = cmd.getTags(); + + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = + new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + 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("aclId", sb.entity().getAclId(), Op.EQ); + sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); + sb.and("protocol", sb.entity().getProtocol(), Op.EQ); + sb.and("action", sb.entity().getAction(), Op.EQ); + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + // _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (id != null) { + sc.setParameters("id", id); + } + + if (networkId != null) { + Network network = _networkDao.findById(networkId); + aclId = network.getNetworkACLId(); + } + + if (trafficType != null) { + sc.setParameters("trafficType", trafficType); + } + + if(aclId != null){ + sc.setParameters("aclId", aclId); + } + + if(protocol != null){ + sc.setParameters("protocol", protocol); + } + + if(action != null){ + sc.setParameters("action", action); + } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.NetworkACL.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + + Pair, Integer> result = _networkACLItemDao.searchAndCount(sc, filter); + return new Pair, Integer>(result.first(), result.second()); + } + + @Override + public boolean revokeNetworkACLItem(long ruleId) { + return _networkAclMgr.revokeNetworkACLItem(ruleId); + } + +} \ No newline at end of file diff --git a/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java b/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java index 98f5d6f8527..a433e0cd8ec 100644 --- a/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java +++ b/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java @@ -16,14 +16,10 @@ // under the License. package com.cloud.network.vpc.dao; -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.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; import org.springframework.stereotype.Component; @@ -38,6 +34,7 @@ public class NetworkACLItemDaoImpl extends GenericDaoBase AllFieldsSearch; protected final SearchBuilder NotRevokedSearch; protected final SearchBuilder ReleaseSearch; + protected final GenericSearchBuilder MaxNumberSearch; protected NetworkACLItemDaoImpl() { super(); @@ -46,7 +43,7 @@ public class NetworkACLItemDaoImpl extends GenericDaoBase 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(); @@ -98,13 +94,11 @@ public class NetworkACLItemDaoImpl extends GenericDaoBase 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. + public int getMaxNumberByACL(long aclId) { + SearchCriteria sc = MaxNumberSearch.create(); + sc.setParameters("aclId", aclId); + Integer max = customSearch(sc, null).get(0); + return (max == null) ? 0 : max; } } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 20fccee2cc0..daffe93c851 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.network.vpc.NetworkACLItemDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -117,6 +118,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso StaticRouteDao _staticRouteDao; @Inject VMSnapshotDao _vmSnapshotDao; + @Inject + NetworkACLItemDao _networkACLItemDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -133,7 +136,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); _daoMap.put(TaggedResourceType.Project, _projectDao); _daoMap.put(TaggedResourceType.Vpc, _vpcDao); - _daoMap.put(TaggedResourceType.NetworkACL, _firewallDao); + _daoMap.put(TaggedResourceType.NetworkACL, _networkACLItemDao); _daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao); _daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao); _daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 31ac75dfe6b..d5eb27737e3 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1209,3 +1209,6 @@ CREATE TABLE `cloud`.`network_acl_item` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `cloud`.`networks` add column `network_acl_id` bigint unsigned COMMENT 'network acl id'; +INSERT INTO `cloud`.`network_acl` values (1, UUID(), 0, "Default Network ACL", "default"); +INSERT INTO `cloud`.`network_acl_item` (id, uuid, acl_id, state, protocol, created, traffic_type, cidr, number, action) values (1, UUID(), 1, "Active", "tcp", now(), "Ingress", "0.0.0.0/0", 1, "Deny"); +INSERT INTO `cloud`.`network_acl_item` (id, uuid, acl_id, state, protocol, created, traffic_type, cidr, number, action) values (2, UUID(), 1, "Active", "tcp", now(), "Egress", "0.0.0.0/0", 2, "Deny");