diff --git a/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java index ccc092bb08f..2016f29b6e3 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java @@ -31,7 +31,7 @@ import com.cloud.utils.net.NetUtils; @Implementation(description = "Creates a ACL rule the given network (the network has to belong to VPC)", responseObject = NetworkACLResponse.class) public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements NetworkACL { - public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName()); + public static final Logger s_logger = Logger.getLogger(CreateNetworkACLCmd.class.getName()); private static final String s_name = "createnetworkaclresponse"; diff --git a/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java b/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java new file mode 100644 index 00000000000..414822bdb33 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java @@ -0,0 +1,120 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +/** + * @author Alena Prokharchyk + */ +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.NetworkACL; +import com.cloud.user.UserContext; + +@Implementation(description="Deletes a Network ACL", responseObject=SuccessResponse.class) +public class DeleteNetworkACLCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteNetworkACLCmd.class.getName()); + private static final String s_name = "deletenetworkaclresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="firewall_rules") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the network ACL") + private Long id; + + // unexposed parameter needed for events logging + @IdentityMapper(entityTableName="account") + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, expose=false) + private Long ownerId; + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_FIREWALL_CLOSE; + } + + @Override + public String getEventDescription() { + return ("Deleting Network ACL id=" + id); + } + + @Override + public long getEntityOwnerId() { + if (ownerId == null) { + NetworkACL rule = _networkACLService.getNetworkACL(id); + if (rule == null) { + throw new InvalidParameterValueException("Unable to find network ACL by id=" + id); + } else { + ownerId = rule.getAccountId(); + } + } + return ownerId; + } + + @Override + public void execute() throws ResourceUnavailableException { + UserContext.current().setEventDetails("Network ACL Id: " + id); + boolean result = _networkACLService.revokeNetworkACL(id, true); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete network ACL"); + } + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.networkSyncObject; + } + + @Override + public Long getSyncObjId() { + return _firewallService.getFirewallRule(id).getNetworkId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.FirewallRule; + } +} + diff --git a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java index f0bbba66caa..2827f0b2fb8 100644 --- a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java @@ -22,7 +22,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; diff --git a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java new file mode 100644 index 00000000000..c14f06ecb0e --- /dev/null +++ b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java @@ -0,0 +1,93 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +/** + * @author Alena Prokharchyk + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.FirewallResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.NetworkACLResponse; +import com.cloud.network.rules.NetworkACL; + +@Implementation(description="Lists all network ACLs", responseObject=NetworkACLResponse.class) +public class ListNetworkACLsCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListNetworkACLsCmd.class.getName()); + + private static final String s_name = "listnetworkaclsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="firewall_rules") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="Lists network ACL with the specified ID.") + private Long id; + + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK, type=CommandType.LONG, description="list network ACLs by network Id") + private Long networkId; + + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list network ACLs by traffic type - Ingress or Egress") + private String trafficType; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNetworkId() { + return networkId; + } + + public Long getId() { + return id; + } + + public String getTrafficType() { + return trafficType; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List result = _networkACLService.listNetworkACLs(this); + ListResponse response = new ListResponse(); + List aclResponses = new ArrayList(); + + for (NetworkACL acl : result) { + NetworkACLResponse ruleData = _responseGenerator.createNetworkACLResponse(acl); + aclResponses.add(ruleData); + } + response.setResponses(aclResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java index 19b3331e716..73977938a89 100644 --- a/api/src/com/cloud/network/firewall/NetworkACLService.java +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -12,6 +12,9 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network.firewall; +import java.util.List; + +import com.cloud.api.commands.ListNetworkACLsCmd; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.NetworkACL; @@ -35,4 +38,9 @@ public interface NetworkACLService { * @return */ boolean revokeNetworkACL(long ruleId, boolean apply); + /** + * @param listNetworkACLsCmd + * @return + */ + List listNetworkACLs(ListNetworkACLsCmd cmd); } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d36329da658..00392c3b3a3 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -361,5 +361,5 @@ createPrivateNetwork=com.cloud.api.commands.CreatePrivateNetworkCmd;1 #### createNetworkACL=com.cloud.api.commands.CreateNetworkACLCmd;15 -#deleteNetworkACL=com.cloud.api.commands.DeleteNetworkACLCmd;15 -#listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15 +deleteNetworkACL=com.cloud.api.commands.DeleteNetworkACLCmd;15 +listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15 diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index 321e1c0be59..f9acc1289ed 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -281,7 +281,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc capabilities.put(Service.Vpn, vpnCapabilities); Map firewallCapabilities = capabilities.get(Service.Firewall); - firewallCapabilities.put(Capability.FirewallType, "percidr"); + firewallCapabilities.put(Capability.FirewallType, "networkacl"); capabilities.put(Service.Firewall, firewallCapabilities); return capabilities; diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index ea8aec749ea..62901df5022 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -348,7 +348,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma Long networkId = null; if (ipAddress.getAssociatedWithNetworkId() == null) { - throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + + throw new InvalidParameterValueException("Unable to create firewall rule ; ip id=" + ipAddress.getId() + " is not associated with any network"); } else { networkId = ipAddress.getAssociatedWithNetworkId(); @@ -358,20 +358,27 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?"; // Verify that the network guru supports the protocol specified - Map protocolCapabilities = null; + Map caps = null; if (purpose == Purpose.LoadBalancing) { if (!_elbEnabled) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Lb); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Lb); } } else if (purpose == Purpose.Firewall) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + if (caps != null) { + String firewallType = caps.get(Capability.FirewallType); + //regular firewall rules are not supported in networks supporting network ACLs + if (firewallType.equalsIgnoreCase("networkacl")) { + throw new UnsupportedOperationException("Firewall rules are not supported in network " + network); + } + } } else if (purpose == Purpose.PortForwarding) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding); } - if (protocolCapabilities != null) { - String supportedProtocols = protocolCapabilities.get(Capability.SupportedProtocols).toLowerCase(); + if (caps != null) { + String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); if (!supportedProtocols.contains(proto.toLowerCase())) { throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId()); } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) { diff --git a/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java b/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java index 366f6bf92e5..235d2a6119e 100644 --- a/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network.firewall; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -23,6 +24,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.acl.SecurityChecker.AccessType; +import com.cloud.api.commands.ListNetworkACLsCmd; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; @@ -42,16 +44,21 @@ import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.NetworkACL; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcManager; +import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.UserContext; +import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +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 com.cloud.vm.Nic.State; /** * @author Alena Prokharchyk @@ -98,11 +105,6 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{ return _name; } - @Override - public NetworkACL getNetworkACL(long ruleId) { - return _firewallDao.findById(ruleId); - } - @Override public boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException { List rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL); @@ -197,14 +199,21 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{ } // Verify that the network guru supports the protocol specified - Map protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + Map caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); - if (protocolCapabilities != null) { - String supportedProtocols = protocolCapabilities.get(Capability.SupportedProtocols).toLowerCase(); + if (caps != null) { + String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); if (!supportedProtocols.contains(proto.toLowerCase())) { - throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId()); + throw new InvalidParameterValueException("Protocol " + proto + " is not supported by the network " + network); } + + String firewallType = caps.get(Capability.FirewallType); + if (!firewallType.equalsIgnoreCase("networkacl")) { + throw new UnsupportedOperationException("Network ACLS are not supported in network " + network); + } + } else { + throw new InvalidParameterValueException("No capabilities are found for network " + network); } } @@ -298,4 +307,59 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{ return success; } + @Override + public NetworkACL getNetworkACL(long ACLId) { + FirewallRuleVO rule = _firewallDao.findById(ACLId); + if (rule != null && rule.getPurpose() == Purpose.NetworkACL) { + return rule; + } + return null; + } + + @Override + public List listNetworkACLs(ListNetworkACLsCmd cmd) { + Long networkId = cmd.getNetworkId(); + Long id = cmd.getId(); + String trafficType = cmd.getTrafficType(); + + 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(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _firewallDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("id", sb.entity().getId(), Op.EQ); + sb.and("network", sb.entity().getNetworkId(), Op.EQ); + sb.and("purpose", sb.entity().getPurpose(), Op.EQ); + sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (id != null) { + sc.setParameters("id", id); + } + + if (networkId != null) { + sc.setParameters("networkId", networkId); + } + + if (trafficType != null) { + sc.setParameters("trafficType", trafficType); + } + + sc.setParameters("purpose", Purpose.NetworkACL); + + return _firewallDao.search(sc, filter); + } + } diff --git a/setup/apidoc/gen_toc.py b/setup/apidoc/gen_toc.py index 1c2f48c4c09..a20dd196744 100644 --- a/setup/apidoc/gen_toc.py +++ b/setup/apidoc/gen_toc.py @@ -81,6 +81,7 @@ known_categories = { 'Pod': 'Pod', 'Zone': 'Zone', 'NetworkOffering': 'Network Offering', + 'NetworkACL': 'Network ACL', 'Network': 'Network', 'CiscoNexus': 'Network', 'Vpn': 'VPN',