VPC: implemented delete and list Network ACL(s)

This commit is contained in:
Alena Prokharchyk 2012-06-20 14:24:13 -07:00
parent 374a600746
commit ccec9192a2
10 changed files with 314 additions and 22 deletions

View File

@ -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";

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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<? extends NetworkACL> result = _networkACLService.listNetworkACLs(this);
ListResponse<NetworkACLResponse> response = new ListResponse<NetworkACLResponse>();
List<NetworkACLResponse> aclResponses = new ArrayList<NetworkACLResponse>();
for (NetworkACL acl : result) {
NetworkACLResponse ruleData = _responseGenerator.createNetworkACLResponse(acl);
aclResponses.add(ruleData);
}
response.setResponses(aclResponses);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -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<? extends NetworkACL> listNetworkACLs(ListNetworkACLsCmd cmd);
}

View File

@ -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

View File

@ -281,7 +281,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
capabilities.put(Service.Vpn, vpnCapabilities);
Map<Capability, String> firewallCapabilities = capabilities.get(Service.Firewall);
firewallCapabilities.put(Capability.FirewallType, "percidr");
firewallCapabilities.put(Capability.FirewallType, "networkacl");
capabilities.put(Service.Firewall, firewallCapabilities);
return capabilities;

View File

@ -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<Network.Capability, String> protocolCapabilities = null;
Map<Network.Capability, String> 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) {

View File

@ -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<FirewallRuleVO> 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<Network.Capability, String> protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
Map<Network.Capability, String> 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<? extends NetworkACL> listNetworkACLs(ListNetworkACLsCmd cmd) {
Long networkId = cmd.getNetworkId();
Long id = cmd.getId();
String trafficType = cmd.getTrafficType();
Account caller = UserContext.current().getCaller();
List<Long> permittedAccounts = new ArrayList<Long>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject =
new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
domainIdRecursiveListProject, cmd.listAll(), false);
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<FirewallRuleVO> 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<FirewallRuleVO> 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);
}
}

View File

@ -81,6 +81,7 @@ known_categories = {
'Pod': 'Pod',
'Zone': 'Zone',
'NetworkOffering': 'Network Offering',
'NetworkACL': 'Network ACL',
'Network': 'Network',
'CiscoNexus': 'Network',
'Vpn': 'VPN',