mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
bug 10561: intermidiate checkin for FirewallRuleFeature
1) Added new apis: createFirewallRule, deleteFirewallRule, listFirewallRules 2) Modified existing apis - added boolean openFirewall parameter to createPortForwardingRule/createIpForwardingRule/createRemoteAccessVpn. If parameter is set to true, open firewall on the domR before creating an actual PF rule there Modified backend calls appropriately. 3) Schema changes for firewall_rules table: * startPort/endPort can be null now * added icmp_type, icmp_code fields (can be not null only when protocol is icmp) 4) Added new manager - FirewallManagerImpl Conflicts: api/src/com/cloud/api/BaseCmd.java client/tomcatconf/commands.properties.in server/src/com/cloud/api/ApiResponseHelper.java server/src/com/cloud/configuration/DefaultComponentLibrary.java server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java server/src/com/cloud/network/rules/RulesManagerImpl.java
This commit is contained in:
parent
adfb6a1f03
commit
6b9603bc4c
@ -17,6 +17,9 @@
|
||||
*/
|
||||
package com.cloud.agent.api.to;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.State;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
@ -53,10 +56,25 @@ public class FirewallRuleTO {
|
||||
protected FirewallRuleTO() {
|
||||
}
|
||||
|
||||
public FirewallRuleTO(long id, String srcIp, String protocol, int srcPortStart, int srcPortEnd, boolean revoked, boolean alreadyAdded, FirewallRule.Purpose purpose) {
|
||||
public FirewallRuleTO(long id, String srcIp, String protocol, Integer srcPortStart, Integer srcPortEnd, boolean revoked, boolean alreadyAdded, FirewallRule.Purpose purpose) {
|
||||
this.srcIp = srcIp;
|
||||
this.protocol = protocol;
|
||||
this.srcPortRange = new int[] {srcPortStart, srcPortEnd};
|
||||
|
||||
if (srcPortStart != null) {
|
||||
List<Integer> portRange = new ArrayList<Integer>();
|
||||
portRange.add(srcPortStart);
|
||||
if (srcPortEnd != null) {
|
||||
portRange.add(srcPortEnd);
|
||||
}
|
||||
|
||||
srcPortRange = new int[portRange.size()];
|
||||
int i = 0;
|
||||
for (Integer port : portRange) {
|
||||
srcPortRange[i] = port.intValue();
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
|
||||
this.revoked = revoked;
|
||||
this.alreadyAdded = alreadyAdded;
|
||||
this.purpose = purpose;
|
||||
|
||||
@ -254,4 +254,5 @@ public class ApiConstants {
|
||||
public static final String REDUNDANT_ROUTER = "redundantrouter";
|
||||
public static final String IP_NETWORK_LIST = "iptonetworklist";
|
||||
public static final String KEYBOARD="keyboard";
|
||||
public static final String OPEN_FIREWALL="openfirewall";
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
<<<<<<< HEAD
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -56,6 +57,39 @@ import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.vm.BareMetalVmService;
|
||||
import com.cloud.vm.UserVmService;
|
||||
=======
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.ConfigurationService;
|
||||
import com.cloud.consoleproxy.ConsoleProxyService;
|
||||
import com.cloud.dao.EntityManager;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.NetworkService;
|
||||
import com.cloud.network.VirtualNetworkApplianceService;
|
||||
import com.cloud.network.firewall.FirewallService;
|
||||
import com.cloud.network.lb.LoadBalancingRulesService;
|
||||
import com.cloud.network.rules.RulesService;
|
||||
import com.cloud.network.security.SecurityGroupService;
|
||||
import com.cloud.network.vpn.RemoteAccessVpnService;
|
||||
import com.cloud.resource.ResourceService;
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.storage.StorageService;
|
||||
import com.cloud.storage.snapshot.SnapshotService;
|
||||
import com.cloud.template.TemplateService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import com.cloud.vm.BareMetalVmService;
|
||||
>>>>>>> 32445e6... bug 10561: intermidiate checkin for FirewallRuleFeature
|
||||
|
||||
public abstract class BaseCmd {
|
||||
private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
|
||||
@ -117,7 +151,8 @@ public abstract class BaseCmd {
|
||||
public static LoadBalancingRulesService _lbService;
|
||||
public static RemoteAccessVpnService _ravService;
|
||||
public static BareMetalVmService _bareMetalVmService;
|
||||
public static ProjectService _projectService;
|
||||
public static ProjectService _projectService;
|
||||
public static FirewallService _firewallService;
|
||||
|
||||
static void setComponents(ResponseGenerator generator) {
|
||||
ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
|
||||
@ -139,7 +174,8 @@ public abstract class BaseCmd {
|
||||
_ravService = locator.getManager(RemoteAccessVpnService.class);
|
||||
_responseGenerator = generator;
|
||||
_bareMetalVmService = locator.getManager(BareMetalVmService.class);
|
||||
_projectService = locator.getManager(ProjectService.class);
|
||||
_projectService = locator.getManager(ProjectService.class);
|
||||
_firewallService = locator.getManager(FirewallService.class);
|
||||
}
|
||||
|
||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException;
|
||||
|
||||
@ -32,6 +32,7 @@ import com.cloud.api.response.DomainResponse;
|
||||
import com.cloud.api.response.DomainRouterResponse;
|
||||
import com.cloud.api.response.EventResponse;
|
||||
import com.cloud.api.response.ExtractResponse;
|
||||
import com.cloud.api.response.FirewallResponse;
|
||||
import com.cloud.api.response.FirewallRuleResponse;
|
||||
import com.cloud.api.response.HostResponse;
|
||||
import com.cloud.api.response.IPAddressResponse;
|
||||
@ -76,6 +77,7 @@ import com.cloud.network.Network;
|
||||
import com.cloud.network.RemoteAccessVpn;
|
||||
import com.cloud.network.VpnUser;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.LoadBalancer;
|
||||
import com.cloud.network.rules.PortForwardingRule;
|
||||
import com.cloud.network.rules.StaticNatRule;
|
||||
@ -207,5 +209,7 @@ public interface ResponseGenerator {
|
||||
List<TemplateResponse> createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly);
|
||||
|
||||
List<TemplateResponse> createTemplateResponses(long templateId, Long vmId);
|
||||
|
||||
FirewallResponse createFirewallResponse(FirewallRule fwRule);
|
||||
|
||||
}
|
||||
|
||||
283
api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
Normal file
283
api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
Normal file
@ -0,0 +1,283 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseAsyncCreateCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.response.FirewallResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@Implementation(description = "Creates a firewall rule for a given ip address", responseObject = FirewallResponse.class)
|
||||
public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule {
|
||||
public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName());
|
||||
|
||||
private static final String s_name = "createfirewallruleresponse";
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ////////////// API parameters /////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.LONG, required = true, description = "the IP address id of the port forwarding rule")
|
||||
private Long ipAddressId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the firewall rule. Valid values are TCP/UDP/ICMP.")
|
||||
private String protocol;
|
||||
|
||||
@Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of firewall rule")
|
||||
private Integer publicStartPort;
|
||||
|
||||
@Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of firewall rule")
|
||||
private Integer publicEndPort;
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
@Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the icmp message being sent")
|
||||
private Integer icmpType;
|
||||
|
||||
@Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message")
|
||||
private Integer icmpCode;
|
||||
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
public Long getIpAddressId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol.trim();
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
if (cidrlist != null) {
|
||||
return cidrlist;
|
||||
} else {
|
||||
List<String> oneCidrList = new ArrayList<String>();
|
||||
oneCidrList.add(NetUtils.ALL_CIDRS);
|
||||
return oneCidrList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> cidrs){
|
||||
cidrlist = cidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
UserContext callerContext = UserContext.current();
|
||||
boolean success = false;
|
||||
FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
success = _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
|
||||
// State is different after the rule is applied, so get new object here
|
||||
rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
FirewallResponse fwResponse = new FirewallResponse();
|
||||
if (rule != null) {
|
||||
fwResponse = _responseGenerator.createFirewallResponse(rule);
|
||||
setResponseObject(fwResponse);
|
||||
}
|
||||
fwResponse.setResponseName(getCommandName());
|
||||
} finally {
|
||||
if (!success || rule == null) {
|
||||
_firewallService.revokeFirewallRule(getEntityId(), true);
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create firewall rule");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
throw new UnsupportedOperationException("database id can only provided by VO objects");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getXid() {
|
||||
// FIXME: We should allow for end user to specify Xid.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceIpAddressId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSourcePortStart() {
|
||||
if (publicStartPort != null) {
|
||||
return publicStartPort.intValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSourcePortEnd() {
|
||||
if (publicEndPort == null) {
|
||||
if (publicStartPort != null) {
|
||||
return publicStartPort.intValue();
|
||||
}
|
||||
} else {
|
||||
return publicEndPort.intValue();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Purpose getPurpose() {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
throw new UnsupportedOperationException("Should never call me to find the state");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = UserContext.current().getCaller();
|
||||
|
||||
if (account != null) {
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
IpAddress ip = _networkService.getIp(ipAddressId);
|
||||
return ip.getDomainId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
if (getSourceCidrList() != null) {
|
||||
for (String cidr: getSourceCidrList()){
|
||||
if (!NetUtils.isValidCIDR(cidr)){
|
||||
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Source cidrs formatting error " + cidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
FirewallRule result = _firewallService.createFirewallRule(this);
|
||||
setEntityId(result.getId());
|
||||
} catch (NetworkRuleConflictException ex) {
|
||||
s_logger.info("Network rule conflict: " + ex.getMessage());
|
||||
s_logger.trace("Network Rule Conflict: ", ex);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_FIREWALL_OPEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
IpAddress ip = _networkService.getIp(ipAddressId);
|
||||
return ("Createing firewall rule for Ip: " + ip.getAddress() + " for protocol:" + this.getProtocol());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
IpAddress ip = _networkService.getIp(ipAddressId);
|
||||
return ip.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return BaseAsyncCmd.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return getIp().getAssociatedWithNetworkId();
|
||||
}
|
||||
|
||||
private IpAddress getIp() {
|
||||
IpAddress ip = _networkService.getIp(ipAddressId);
|
||||
if (ip == null) {
|
||||
throw new InvalidParameterValueException("Unable to find ip address by id " + ipAddressId);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
if (icmpCode != null) {
|
||||
return icmpCode;
|
||||
} else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
|
||||
return -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
if (icmpType != null) {
|
||||
return icmpType;
|
||||
} else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
|
||||
return -1;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
@ -61,6 +63,9 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
@Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, required=true, description="the protocol for the rule. Valid values are TCP or UDP.")
|
||||
private String protocol;
|
||||
|
||||
@Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default")
|
||||
private Boolean openFirewall;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
@ -77,6 +82,14 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
public int getEndPort() {
|
||||
return endPort;
|
||||
}
|
||||
|
||||
public Boolean getOpenFirewall() {
|
||||
if (openFirewall != null) {
|
||||
return openFirewall;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
@ -89,11 +102,16 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException{
|
||||
boolean result = false;
|
||||
boolean result = true;
|
||||
FirewallRule rule = null;
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: "+ getEntityId());
|
||||
result = _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
result = result && _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), UserContext.current().getCaller());
|
||||
}
|
||||
|
||||
result = result && _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());
|
||||
rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule);
|
||||
IpForwardingRuleResponse fwResponse = _responseGenerator.createIpForwardingRuleResponse(staticNatRule);
|
||||
@ -111,7 +129,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
public void create() {
|
||||
StaticNatRule rule;
|
||||
try {
|
||||
rule = _rulesService.createStaticNatRule(this);
|
||||
rule = _rulesService.createStaticNatRule(this, getOpenFirewall());
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.info("Unable to create Static Nat Rule due to " + e.getMessage());
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
@ -167,12 +185,12 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return startPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
if (endPort == null) {
|
||||
return startPort;
|
||||
} else {
|
||||
@ -235,4 +253,19 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.LoadBalancerResponse;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
@ -65,6 +64,9 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
@Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default")
|
||||
private Boolean openFirewall;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@ -109,6 +111,14 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer
|
||||
public List<String> getSourceCidrList() {
|
||||
return cidrlist;
|
||||
}
|
||||
|
||||
public Boolean getOpenFirewall() {
|
||||
if (openFirewall != null) {
|
||||
return openFirewall;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
@ -131,7 +141,7 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer
|
||||
|
||||
LoadBalancer result = null;
|
||||
try {
|
||||
result = _lbService.createLoadBalancerRule(this);
|
||||
result = _lbService.createLoadBalancerRule(this, getOpenFirewall());
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
@ -158,12 +168,12 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return publicPort.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
return publicPort.intValue();
|
||||
}
|
||||
|
||||
@ -210,5 +220,16 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return getAccountId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,7 +29,6 @@ import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.FirewallRuleResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -75,6 +74,9 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
@Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default")
|
||||
private Boolean openFirewall;
|
||||
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -98,6 +100,14 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
public List<String> getSourceCidrList() {
|
||||
return cidrlist;
|
||||
}
|
||||
|
||||
public Boolean getOpenFirewall() {
|
||||
if (openFirewall != null) {
|
||||
return openFirewall;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
@ -115,11 +125,16 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
UserContext callerContext = UserContext.current();
|
||||
boolean success = false;
|
||||
boolean success = true;
|
||||
PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
success = _rulesService.applyPortForwardingRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
success = success && _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
}
|
||||
|
||||
success = success && _rulesService.applyPortForwardingRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
|
||||
// State is different after the rule is applied, so get new object here
|
||||
rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
|
||||
@ -154,12 +169,12 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return publicStartPort.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
return (publicEndPort == null)? publicStartPort.intValue() : publicEndPort.intValue();
|
||||
}
|
||||
|
||||
@ -219,7 +234,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
}
|
||||
}
|
||||
try {
|
||||
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId);
|
||||
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, getOpenFirewall());
|
||||
setEntityId(result.getId());
|
||||
} catch (NetworkRuleConflictException ex) {
|
||||
s_logger.info("Network rule conflict: " + ex.getMessage());
|
||||
@ -262,5 +277,15 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.RemoteAccessVpnResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -58,6 +59,9 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
|
||||
@Parameter(name="domainid", type=CommandType.LONG, description="an optional domainId for the VPN. If the account parameter is used, domainId must also be used.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default")
|
||||
private Boolean openFirewall;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -82,13 +86,20 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
|
||||
this.ipRange = ipRange;
|
||||
}
|
||||
|
||||
public Boolean getOpenFirewall() {
|
||||
if (openFirewall != null) {
|
||||
return openFirewall;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
@ -125,7 +136,7 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
|
||||
@Override
|
||||
public void create() {
|
||||
try {
|
||||
RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange);
|
||||
RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall());
|
||||
if (vpn != null) {
|
||||
this.setEntityId(vpn.getServerAddressId());
|
||||
} else {
|
||||
@ -141,7 +152,7 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd {
|
||||
@Override
|
||||
public void execute(){
|
||||
try {
|
||||
RemoteAccessVpn result = _ravService.startRemoteAccessVpn(publicIpId);
|
||||
RemoteAccessVpn result = _ravService.startRemoteAccessVpn(publicIpId, getOpenFirewall());
|
||||
if (result != null) {
|
||||
RemoteAccessVpnResponse response = _responseGenerator.createRemoteAccessVpnResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
112
api/src/com/cloud/api/commands/DeleteFirewallRuleCmd.java
Normal file
112
api/src/com/cloud/api/commands/DeleteFirewallRuleCmd.java
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.response.SuccessResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.UserContext;
|
||||
|
||||
@Implementation(description="Deletes a firewall rule", responseObject=SuccessResponse.class)
|
||||
public class DeleteFirewallRuleCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeleteFirewallRuleCmd.class.getName());
|
||||
private static final String s_name = "deletefirewallruleresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the firewall rule")
|
||||
private Long id;
|
||||
|
||||
// unexposed parameter needed for events logging
|
||||
@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 firewall rule id=" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
if (ownerId == null) {
|
||||
FirewallRule rule = _entityMgr.findById(FirewallRule.class, id);
|
||||
if (rule == null) {
|
||||
throw new InvalidParameterValueException("Unable to find firewall rule by id=" + id);
|
||||
} else {
|
||||
ownerId = _entityMgr.findById(FirewallRule.class, id).getAccountId();
|
||||
}
|
||||
}
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
UserContext.current().setEventDetails("Rule Id: " + id);
|
||||
boolean result = _firewallService.revokeFirewallRule(id, true);
|
||||
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete firewall rule");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return BaseAsyncCmd.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _firewallService.getFirewallRule(id).getNetworkId();
|
||||
}
|
||||
}
|
||||
98
api/src/com/cloud/api/commands/ListFirewallRulesCmd.java
Normal file
98
api/src/com/cloud/api/commands/ListFirewallRulesCmd.java
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseListCmd;
|
||||
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.network.rules.FirewallRule;
|
||||
|
||||
@Implementation(description="Lists all firewall rules for an IP address.", responseObject=FirewallResponse.class)
|
||||
public class ListFirewallRulesCmd extends BaseListCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListPortForwardingRulesCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listfirewallrulesresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="Lists rule with the specified ID.")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.IP_ADDRESS_ID, type=CommandType.LONG, description="the id of IP address of the firwall services")
|
||||
private Long ipAddressId;
|
||||
|
||||
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account. Must be used with the domainId parameter.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID. If used with the account parameter, lists port forwarding rules for the specified account in this domain.")
|
||||
private Long domainId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getIpAddressId() {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
List<? extends FirewallRule> result = _firewallService.listFirewallRules(this);
|
||||
ListResponse<FirewallResponse> response = new ListResponse<FirewallResponse>();
|
||||
List<FirewallResponse> fwResponses = new ArrayList<FirewallResponse>();
|
||||
|
||||
for (FirewallRule fwRule : result) {
|
||||
FirewallResponse ruleData = _responseGenerator.createFirewallResponse(fwRule);
|
||||
ruleData.setObjectName("firewallrule");
|
||||
fwResponses.add(ruleData);
|
||||
}
|
||||
response.setResponses(fwResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
}
|
||||
97
api/src/com/cloud/api/response/FirewallResponse.java
Normal file
97
api/src/com/cloud/api/response/FirewallResponse.java
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.api.response;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class FirewallResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID) @Param(description="the ID of the firewall rule")
|
||||
private Long id;
|
||||
|
||||
@SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the firewall rule")
|
||||
private String protocol;
|
||||
|
||||
@SerializedName(ApiConstants.START_PORT) @Param(description="the starting port of firewall rule's port range")
|
||||
private String startPort;
|
||||
|
||||
@SerializedName(ApiConstants.END_PORT) @Param(description = "the ending port of firewall rule's port range")
|
||||
private String endPort;
|
||||
|
||||
@SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the port forwarding rule")
|
||||
private Long publicIpAddressId;
|
||||
|
||||
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the port forwarding rule")
|
||||
private String publicIpAddress;
|
||||
|
||||
@SerializedName(ApiConstants.STATE) @Param(description="the state of the rule")
|
||||
private String state;
|
||||
|
||||
@SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from")
|
||||
private String cidrList;
|
||||
|
||||
@SerializedName(ApiConstants.ICMP_TYPE) @Param(description= "type of the icmp message being sent")
|
||||
private Integer icmpType;
|
||||
|
||||
@SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message")
|
||||
private Integer icmpCode;
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setStartPort(String startPort) {
|
||||
this.startPort = startPort;
|
||||
}
|
||||
|
||||
public void setEndPort(String endPort) {
|
||||
this.endPort = endPort;
|
||||
}
|
||||
|
||||
public void setPublicIpAddressId(Long publicIpAddressId) {
|
||||
this.publicIpAddressId = publicIpAddressId;
|
||||
}
|
||||
|
||||
public void setPublicIpAddress(String publicIpAddress) {
|
||||
this.publicIpAddress = publicIpAddress;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void setCidrList(String cidrList) {
|
||||
this.cidrList = cidrList;
|
||||
}
|
||||
|
||||
public void setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
}
|
||||
|
||||
public void setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -18,8 +18,6 @@
|
||||
package com.cloud.api.response;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
||||
@ -61,6 +61,8 @@ public class EventTypes {
|
||||
public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE";
|
||||
public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE";
|
||||
public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE";
|
||||
public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN";
|
||||
public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
|
||||
|
||||
// Load Balancers
|
||||
public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE";
|
||||
|
||||
25
api/src/com/cloud/network/firewall/FirewallService.java
Normal file
25
api/src/com/cloud/network/firewall/FirewallService.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.cloud.network.firewall;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.api.commands.ListFirewallRulesCmd;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
public interface FirewallService {
|
||||
FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
|
||||
List<? extends FirewallRule> listFirewallRules(ListFirewallRulesCmd cmd);
|
||||
|
||||
/**
|
||||
* Revokes a firewall rule
|
||||
* @param ruleId the id of the rule to revoke.
|
||||
* @return
|
||||
*/
|
||||
boolean revokeFirewallRule(long ruleId, boolean apply);
|
||||
|
||||
boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
FirewallRule getFirewallRule(long ruleId);
|
||||
}
|
||||
@ -88,12 +88,12 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return lb.getSourcePortStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
return lb.getSourcePortEnd();
|
||||
}
|
||||
|
||||
@ -159,4 +159,14 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{
|
||||
return revoked;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,10 +30,11 @@ import com.cloud.uservm.UserVm;
|
||||
public interface LoadBalancingRulesService {
|
||||
/**
|
||||
* Create a load balancer rule from the given ipAddress/port to the given private port
|
||||
* @param openFirewall TODO
|
||||
* @param cmd the command specifying the ip address, public port, protocol, private port, and algorithm
|
||||
* @return the newly created LoadBalancerVO if successful, null otherwise
|
||||
*/
|
||||
LoadBalancer createLoadBalancerRule(LoadBalancer lb) throws NetworkRuleConflictException;
|
||||
LoadBalancer createLoadBalancerRule(LoadBalancer lb, boolean openFirewall) throws NetworkRuleConflictException;
|
||||
|
||||
LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd);
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
*/
|
||||
package com.cloud.network.rules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.acl.ControlledEntity;
|
||||
|
||||
public interface FirewallRule extends ControlledEntity {
|
||||
@ -48,12 +50,12 @@ public interface FirewallRule extends ControlledEntity {
|
||||
/**
|
||||
* @return first port of the source port range.
|
||||
*/
|
||||
int getSourcePortStart();
|
||||
Integer getSourcePortStart();
|
||||
|
||||
/**
|
||||
* @return last port of the source prot range. If this is null, that means only one port is mapped.
|
||||
*/
|
||||
int getSourcePortEnd();
|
||||
Integer getSourcePortEnd();
|
||||
|
||||
/**
|
||||
* @return protocol to open these ports for.
|
||||
@ -67,4 +69,10 @@ public interface FirewallRule extends ControlledEntity {
|
||||
long getNetworkId();
|
||||
|
||||
long getSourceIpAddressId();
|
||||
|
||||
Integer getIcmpCode();
|
||||
|
||||
Integer getIcmpType();
|
||||
|
||||
List<String> getSourceCidrList();
|
||||
}
|
||||
|
||||
@ -35,6 +35,4 @@ public interface LoadBalancer extends FirewallRule {
|
||||
|
||||
String getAlgorithm();
|
||||
|
||||
public List<String> getSourceCidrList();
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
*/
|
||||
package com.cloud.network.rules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
/**
|
||||
@ -45,8 +43,4 @@ public interface PortForwardingRule extends FirewallRule {
|
||||
*/
|
||||
long getVirtualMachineId();
|
||||
|
||||
/**
|
||||
* @return source cidr to forward
|
||||
*/
|
||||
List<String> getSourceCidrList();
|
||||
}
|
||||
|
||||
@ -32,10 +32,11 @@ public interface RulesService {
|
||||
* an ip address and a virtual machine.
|
||||
* @param rule rule to be created.
|
||||
* @param vmId vm to be linked to. If specified the destination ip address is ignored.
|
||||
* @param openFirewall TODO
|
||||
* @return PortForwardingRule if created.
|
||||
* @throws NetworkRuleConflictException if conflicts in the network rules are detected.
|
||||
*/
|
||||
PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId) throws NetworkRuleConflictException;
|
||||
PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException;
|
||||
|
||||
/**
|
||||
* Revokes a port forwarding rule
|
||||
@ -60,7 +61,7 @@ public interface RulesService {
|
||||
PortForwardingRule getPortForwardigRule(long ruleId);
|
||||
FirewallRule getFirewallRule(long ruleId);
|
||||
|
||||
StaticNatRule createStaticNatRule(StaticNatRule rule) throws NetworkRuleConflictException;
|
||||
StaticNatRule createStaticNatRule(StaticNatRule rule, boolean openFirewall) throws NetworkRuleConflictException;
|
||||
|
||||
boolean revokeStaticNatRule(long ruleId, boolean apply);
|
||||
|
||||
@ -69,5 +70,5 @@ public interface RulesService {
|
||||
StaticNatRule buildStaticNatRule(FirewallRule rule);
|
||||
|
||||
List<String> getSourceCidrs(long ruleId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -28,9 +28,9 @@ public interface StaticNatRule extends ControlledEntity, FirewallRule{
|
||||
|
||||
String getProtocol();
|
||||
|
||||
int getSourcePortStart();
|
||||
Integer getSourcePortStart();
|
||||
|
||||
int getSourcePortEnd();
|
||||
Integer getSourcePortEnd();
|
||||
|
||||
Purpose getPurpose();
|
||||
|
||||
|
||||
@ -28,9 +28,9 @@ import com.cloud.network.VpnUser;
|
||||
|
||||
public interface RemoteAccessVpnService {
|
||||
|
||||
RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange) throws NetworkRuleConflictException;
|
||||
RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException;
|
||||
void destroyRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException;
|
||||
RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException;
|
||||
RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException;
|
||||
|
||||
VpnUser addVpnUser(long vpnOwnerId, String userName, String password);
|
||||
boolean removeVpnUser(long vpnOwnerId, String userName);
|
||||
|
||||
@ -262,8 +262,14 @@ registerSSHKeyPair=com.cloud.api.commands.RegisterSSHKeyPairCmd;15
|
||||
createSSHKeyPair=com.cloud.api.commands.CreateSSHKeyPairCmd;15
|
||||
deleteSSHKeyPair=com.cloud.api.commands.DeleteSSHKeyPairCmd;15
|
||||
listSSHKeyPairs=com.cloud.api.commands.ListSSHKeyPairsCmd;15
|
||||
|
||||
|
||||
#### Projects commands
|
||||
createProject=com.cloud.api.commands.CreateProjectCmd;15
|
||||
deleteProject=com.cloud.api.commands.DeleteProjectCmd;15
|
||||
listProjects=com.cloud.api.commands.ListProjectsCmd;15
|
||||
listProjects=com.cloud.api.commands.ListProjectsCmd;15
|
||||
|
||||
####
|
||||
createFirewallRule=com.cloud.api.commands.CreateFirewallRuleCmd;15
|
||||
deleteFirewallRule=com.cloud.api.commands.DeleteFirewallRuleCmd;15
|
||||
listFirewallRules=com.cloud.api.commands.ListFirewallRulesCmd;15
|
||||
|
||||
|
||||
@ -134,12 +134,14 @@ import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
|
||||
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
|
||||
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
|
||||
import com.cloud.agent.api.routing.DhcpEntryCommand;
|
||||
import com.cloud.agent.api.routing.IpAssocCommand;
|
||||
import com.cloud.agent.api.routing.IpAssocAnswer;
|
||||
import com.cloud.agent.api.routing.IpAssocCommand;
|
||||
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
|
||||
import com.cloud.agent.api.routing.SavePasswordCommand;
|
||||
import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
|
||||
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
|
||||
import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
|
||||
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
|
||||
import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
|
||||
@ -154,8 +156,8 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.DestroyCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.FirewallRuleTO;
|
||||
import com.cloud.agent.api.to.IpAddressTO;
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||
import com.cloud.agent.api.to.StaticNatRuleTO;
|
||||
@ -496,6 +498,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return execute((UpdateHostPasswordCommand)cmd);
|
||||
} else if (cmd instanceof CheckRouterCommand) {
|
||||
return execute((CheckRouterCommand)cmd);
|
||||
} else if (cmd instanceof SetFirewallRulesCommand) {
|
||||
return execute((SetFirewallRulesCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -6504,4 +6508,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
|
||||
return new Answer(cmd, success, "");
|
||||
}
|
||||
|
||||
protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
int i = 0;
|
||||
for (FirewallRuleTO rule : cmd.getRules()) {
|
||||
//FIXME - Jana, add implementation here
|
||||
}
|
||||
|
||||
return new SetFirewallRulesAnswer(cmd, results);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -592,7 +592,7 @@ public class ApiDBUtils {
|
||||
return _consoleProxyDao.findById(id);
|
||||
}
|
||||
|
||||
public static List<String> findPortForwardingSourceCidrs(long id){
|
||||
public static List<String> findFirewallSourceCidrs(long id){
|
||||
return _firewallCidrsDao.getSourceCidrs(id);
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ import com.cloud.api.response.DomainResponse;
|
||||
import com.cloud.api.response.DomainRouterResponse;
|
||||
import com.cloud.api.response.EventResponse;
|
||||
import com.cloud.api.response.ExtractResponse;
|
||||
import com.cloud.api.response.FirewallResponse;
|
||||
import com.cloud.api.response.FirewallRuleResponse;
|
||||
import com.cloud.api.response.HostResponse;
|
||||
import com.cloud.api.response.IPAddressResponse;
|
||||
@ -720,7 +721,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
lbResponse.setId(loadBalancer.getId());
|
||||
lbResponse.setName(loadBalancer.getName());
|
||||
lbResponse.setDescription(loadBalancer.getDescription());
|
||||
List<String> cidrs = ApiDBUtils.findPortForwardingSourceCidrs(loadBalancer.getId());
|
||||
List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId());
|
||||
lbResponse.setCidrList(StringUtils.join(cidrs, ","));
|
||||
|
||||
IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId());
|
||||
@ -989,7 +990,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
response.setProtocol(fwRule.getProtocol());
|
||||
response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart()));
|
||||
response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd()));
|
||||
List<String> cidrs = ApiDBUtils.findPortForwardingSourceCidrs(fwRule.getId());
|
||||
List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
|
||||
response.setCidrList(StringUtils.join(cidrs, ","));
|
||||
|
||||
IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
|
||||
@ -2147,4 +2148,37 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
response.setObjectName("project");
|
||||
return response;
|
||||
}
|
||||
public FirewallResponse createFirewallResponse(FirewallRule fwRule) {
|
||||
FirewallResponse response = new FirewallResponse();
|
||||
|
||||
response.setId(fwRule.getId());
|
||||
response.setProtocol(fwRule.getProtocol());
|
||||
if (fwRule.getSourcePortStart() != null) {
|
||||
response.setStartPort(Integer.toString(fwRule.getSourcePortStart()));
|
||||
}
|
||||
|
||||
if (fwRule.getSourcePortEnd() != null) {
|
||||
response.setEndPort(Integer.toString(fwRule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
|
||||
response.setCidrList(StringUtils.join(cidrs, ","));
|
||||
|
||||
IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
|
||||
response.setPublicIpAddressId(ip.getId());
|
||||
response.setPublicIpAddress(ip.getAddress().addr());
|
||||
|
||||
FirewallRule.State state = fwRule.getState();
|
||||
String stateToSet = state.toString();
|
||||
if (state.equals(FirewallRule.State.Revoke)) {
|
||||
stateToSet = "Deleting";
|
||||
}
|
||||
|
||||
response.setIcmpCode(fwRule.getIcmpCode());
|
||||
response.setIcmpType(fwRule.getIcmpType());
|
||||
|
||||
response.setState(stateToSet);
|
||||
response.setObjectName("firewallrule");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ import com.cloud.network.dao.NetworkDomainDaoImpl;
|
||||
import com.cloud.network.dao.NetworkRuleConfigDaoImpl;
|
||||
import com.cloud.network.dao.RemoteAccessVpnDaoImpl;
|
||||
import com.cloud.network.dao.VpnUserDaoImpl;
|
||||
import com.cloud.network.firewall.FirewallManagerImpl;
|
||||
import com.cloud.network.lb.LoadBalancingRulesManagerImpl;
|
||||
import com.cloud.network.ovs.OvsNetworkManagerImpl;
|
||||
import com.cloud.network.ovs.OvsTunnelManagerImpl;
|
||||
@ -316,6 +317,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
|
||||
addManager("ClusterFenceManager", ClusterFenceManagerImpl.class);
|
||||
addManager("ResourceManager", ResourceManagerImpl.class);
|
||||
addManager("OCFS2Manager", OCFS2ManagerImpl.class);
|
||||
addManager("FirewallManager", FirewallManagerImpl.class);
|
||||
ComponentInfo<? extends Manager> info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class);
|
||||
info.addParameter("consoleproxy.sslEnabled", "true");
|
||||
addManager("ClusteredAgentManager", ClusteredAgentManagerImpl.class);
|
||||
|
||||
@ -53,13 +53,13 @@ public class FirewallRulesCidrsVO {
|
||||
public long getFirewallRuleId() {
|
||||
return firewallRuleId;
|
||||
}
|
||||
|
||||
public void setFirewallRuleId(long firewallRuleId){
|
||||
this.firewallRuleId = firewallRuleId;
|
||||
}
|
||||
|
||||
public String getCidr() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
public String getSourceCidrList() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
|
||||
package com.cloud.network;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
@ -26,7 +25,6 @@ import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.LoadBalancer;
|
||||
@ -52,21 +50,17 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer {
|
||||
|
||||
@Column(name="default_port_end")
|
||||
private int defaultPortEnd;
|
||||
|
||||
@Transient
|
||||
List<String> sourceCidrs;
|
||||
|
||||
public LoadBalancerVO() {
|
||||
}
|
||||
|
||||
public LoadBalancerVO(String xId, String name, String description, long srcIpId, int srcPort, int dstPort, List<String> sourceCidrs, String algorithm, long networkId, long accountId, long domainId) {
|
||||
super(xId, srcIpId, srcPort, NetUtils.TCP_PROTO, networkId, accountId, domainId, Purpose.LoadBalancing);
|
||||
super(xId, srcIpId, srcPort, NetUtils.TCP_PROTO, networkId, accountId, domainId, Purpose.LoadBalancing, sourceCidrs, null, null);
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.algorithm = algorithm;
|
||||
this.defaultPortStart = dstPort;
|
||||
this.defaultPortEnd = dstPort;
|
||||
this.sourceCidrs = sourceCidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -77,14 +71,6 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrs) {
|
||||
this.sourceCidrs=sourceCidrs;
|
||||
}
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -94,13 +94,17 @@ import com.cloud.network.Networks.AddressFormat;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.addr.PublicIp;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkDomainDao;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.guru.NetworkGuru;
|
||||
import com.cloud.network.lb.LoadBalancingRulesManager;
|
||||
import com.cloud.network.rules.FirewallManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
import com.cloud.network.vpn.PasswordResetElement;
|
||||
import com.cloud.network.vpn.RemoteAccessVpnElement;
|
||||
@ -214,6 +218,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
NetworkDomainDao _networkDomainDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmDao;
|
||||
@Inject
|
||||
FirewallManager _firewallMgr;
|
||||
@Inject
|
||||
FirewallRulesDao _firewallDao;
|
||||
|
||||
@Inject DomainRouterDao _routerDao;
|
||||
|
||||
@ -2207,6 +2215,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
success = false;
|
||||
s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
|
||||
}
|
||||
|
||||
//revoke all firewall rules for the network
|
||||
try {
|
||||
if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, callerUserId, caller)) {
|
||||
s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
|
||||
} else {
|
||||
success = false;
|
||||
s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup");
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
success = false;
|
||||
// shouldn't even come here as network is being cleaned up after all network elements are shutdown
|
||||
s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
|
||||
}
|
||||
|
||||
// release all ip addresses
|
||||
List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null);
|
||||
@ -2399,6 +2421,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
s_logger.warn("Failed to apply ip addresses as a part of network id" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
|
||||
// apply firewall rules
|
||||
List<FirewallRuleVO> firewallRulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
|
||||
if (!_firewallMgr.applyFirewallRules(firewallRulesToApply, false, caller)) {
|
||||
s_logger.warn("Failed to reapply firewall rule(s) as a part of network id=" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
|
||||
// apply port forwarding rules
|
||||
if (!_rulesMgr.applyPortForwardingRulesForNetwork(networkId, false, caller)) {
|
||||
@ -2423,7 +2452,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
if (vpnsToReapply != null) {
|
||||
for (RemoteAccessVpn vpn : vpnsToReapply) {
|
||||
// Start remote access vpn per ip
|
||||
if (_vpnMgr.startRemoteAccessVpn(vpn.getServerAddressId()) == null) {
|
||||
if (_vpnMgr.startRemoteAccessVpn(vpn.getServerAddressId(), false) == null) {
|
||||
s_logger.warn("Failed to reapply vpn rules as a part of network id=" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
@ -2767,9 +2796,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
private boolean cleanupIpResources(long ipId, long userId, Account caller) {
|
||||
boolean success = true;
|
||||
|
||||
|
||||
//Revoke all PF/Static nat rules for the ip
|
||||
try {
|
||||
s_logger.debug("Revoking all PF/StaticNat rules as a part of public IP id=" + ipId + " release...");
|
||||
if (!_rulesMgr.revokeAllRulesForIp(ipId, userId, caller)) {
|
||||
s_logger.debug("Revoking all " + Purpose.PortForwarding + "/" + Purpose.StaticNat + " rules as a part of public IP id=" + ipId + " release...");
|
||||
if (!_rulesMgr.revokeAllPFAndStaticNatRulesForIp(ipId, userId, caller)) {
|
||||
s_logger.warn("Unable to revoke all the port forwarding rules for ip id=" + ipId + " as a part of ip release");
|
||||
success = false;
|
||||
}
|
||||
@ -2778,7 +2809,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
success = false;
|
||||
}
|
||||
|
||||
s_logger.debug("Revoking all LB rules as a part of public IP id=" + ipId + " release...");
|
||||
s_logger.debug("Revoking all " + Purpose.LoadBalancing + " rules as a part of public IP id=" + ipId + " release...");
|
||||
if (!_lbMgr.removeAllLoadBalanacersForIp(ipId, caller, userId)) {
|
||||
s_logger.warn("Unable to revoke all the load balancer rules for ip id=" + ipId + " as a part of ip release");
|
||||
success = false;
|
||||
@ -2795,6 +2826,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
s_logger.warn("Unable to destroy remote access vpn for ip id=" + ipId + " as a part of ip release", e);
|
||||
success = false;
|
||||
}
|
||||
|
||||
//Revoke all firewall rules for the ip
|
||||
try {
|
||||
s_logger.debug("Revoking all " + Purpose.Firewall + "rules as a part of public IP id=" + ipId + " release...");
|
||||
if (!_firewallMgr.revokeFirewallRulesForIp(ipId, userId, caller)) {
|
||||
s_logger.warn("Unable to revoke all the firewall rules for ip id=" + ipId + " as a part of ip release");
|
||||
success = false;
|
||||
}
|
||||
} catch (ResourceUnavailableException e) {
|
||||
s_logger.warn("Unable to revoke all firewall rules for ip id=" + ipId + " as a part of ip release", e);
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -39,10 +39,12 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
|
||||
|
||||
boolean releasePorts(long ipAddressId, String protocol, FirewallRule.Purpose purpose, int[] ports);
|
||||
|
||||
List<? extends FirewallRule> listByIpAndPurpose(long ipAddressId, FirewallRule.Purpose purpose);
|
||||
List<FirewallRuleVO> listByIpAndPurpose(long ipAddressId, FirewallRule.Purpose purpose);
|
||||
|
||||
List<FirewallRuleVO> listByNetworkAndPurpose(long networkId, FirewallRule.Purpose purpose);
|
||||
|
||||
List<FirewallRuleVO> listStaticNatByVmId(long vmId);
|
||||
|
||||
List<FirewallRuleVO> listByIpPurposeAndProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol, FirewallRule.Purpose purpose);
|
||||
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ 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;
|
||||
|
||||
@Local(value=FirewallRulesDao.class) @DB(txn=false)
|
||||
public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> implements FirewallRulesDao {
|
||||
@ -46,6 +47,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
protected final SearchBuilder<FirewallRuleVO> ReleaseSearch;
|
||||
protected SearchBuilder<FirewallRuleVO> VmSearch;
|
||||
|
||||
protected final FirewallRulesCidrsDaoImpl _firewallRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class);
|
||||
|
||||
protected FirewallRulesDaoImpl() {
|
||||
super();
|
||||
|
||||
@ -64,6 +67,9 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
NotRevokedSearch.and("ipId", NotRevokedSearch.entity().getSourceIpAddressId(), Op.EQ);
|
||||
NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ);
|
||||
NotRevokedSearch.and("purpose", NotRevokedSearch.entity().getPurpose(), Op.EQ);
|
||||
NotRevokedSearch.and("protocol", NotRevokedSearch.entity().getProtocol(), Op.EQ);
|
||||
NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(), Op.EQ);
|
||||
NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(), Op.EQ);
|
||||
NotRevokedSearch.and("networkId", NotRevokedSearch.entity().getNetworkId(), Op.EQ);
|
||||
NotRevokedSearch.done();
|
||||
|
||||
@ -167,6 +173,49 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
sc.setParameters("purpose", Purpose.StaticNat);
|
||||
sc.setJoinParameters("ipSearch", "associatedWithVmId", vmId);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override @DB
|
||||
public FirewallRuleVO persist(FirewallRuleVO firewallRule) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
FirewallRuleVO dbfirewallRule = super.persist(firewallRule);
|
||||
saveSourceCidrs(firewallRule);
|
||||
|
||||
txn.commit();
|
||||
return dbfirewallRule;
|
||||
}
|
||||
|
||||
|
||||
public void saveSourceCidrs(FirewallRuleVO firewallRule) {
|
||||
List<String> cidrlist = firewallRule.getSourceCidrList();
|
||||
if (cidrlist == null) {
|
||||
return;
|
||||
}
|
||||
_firewallRulesCidrsDao.persist(firewallRule.getId(), cidrlist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIpPurposeAndProtocolAndNotRevoked(long ipAddressId, Integer startPort, Integer endPort, String protocol, FirewallRule.Purpose purpose) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
sc.setParameters("ipId", ipAddressId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
|
||||
if (purpose != null) {
|
||||
sc.setParameters("purpose", purpose);
|
||||
}
|
||||
|
||||
if (protocol != null) {
|
||||
sc.setParameters("protocol", protocol);
|
||||
}
|
||||
|
||||
sc.setParameters("sourcePortStart", startPort);
|
||||
|
||||
sc.setParameters("sourcePortEnd", endPort);
|
||||
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@ -28,9 +28,7 @@ import javax.ejb.Local;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.network.LoadBalancerVO;
|
||||
import com.cloud.network.rules.PortForwardingRuleVO;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
@ -120,48 +118,5 @@ public class LoadBalancerDaoImpl extends GenericDaoBase<LoadBalancerVO, Long> im
|
||||
sc.setParameters("name", name);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
public void saveSourceCidrs(LoadBalancerVO loadBalancerRule) {
|
||||
List<String> cidrlist = loadBalancerRule.getSourceCidrList();
|
||||
if (cidrlist == null) {
|
||||
return;
|
||||
}
|
||||
_portForwardingRulesCidrsDao.persist(loadBalancerRule.getId(), cidrlist);
|
||||
}
|
||||
|
||||
|
||||
public void loadSourceCidrs(LoadBalancerVO loadBalancerRule){
|
||||
List<String> sourceCidrs = _portForwardingRulesCidrsDao.getSourceCidrs(loadBalancerRule.getId());
|
||||
loadBalancerRule.setSourceCidrList(sourceCidrs);
|
||||
}
|
||||
|
||||
|
||||
@Override @DB
|
||||
public LoadBalancerVO persist(LoadBalancerVO loadBalancerRule) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
LoadBalancerVO dbfirewallRule = super.persist(loadBalancerRule);
|
||||
saveSourceCidrs(loadBalancerRule);
|
||||
|
||||
txn.commit();
|
||||
return dbfirewallRule;
|
||||
}
|
||||
|
||||
|
||||
@Override @DB
|
||||
public boolean update(Long loadBalancerRuleId, LoadBalancerVO loadBalancerRule) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
boolean persisted = super.update(loadBalancerRuleId, loadBalancerRule);
|
||||
if (!persisted) {
|
||||
return persisted;
|
||||
}
|
||||
saveSourceCidrs(loadBalancerRule);
|
||||
|
||||
txn.commit();
|
||||
return persisted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ public class VirtualRouterElement extends DhcpElement implements NetworkElement,
|
||||
firewallCapabilities.put(Capability.PortForwarding, "true");
|
||||
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
|
||||
firewallCapabilities.put(Capability.StaticNat, "true");
|
||||
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp");
|
||||
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
|
||||
firewallCapabilities.put(Capability.MultipleIps, "true");
|
||||
firewallCapabilities.put(Capability.SupportedSourceNatTypes, "per account");
|
||||
|
||||
|
||||
499
server/src/com/cloud/network/firewall/FirewallManagerImpl.java
Normal file
499
server/src/com/cloud/network/firewall/FirewallManagerImpl.java
Normal file
@ -0,0 +1,499 @@
|
||||
package com.cloud.network.firewall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.commands.ListFirewallRulesCmd;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.dao.FirewallRulesCidrsDao;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.rules.FirewallManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRule.State;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.utils.Pair;
|
||||
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.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;
|
||||
|
||||
@Local(value = { FirewallService.class, FirewallManager.class })
|
||||
public class FirewallManagerImpl implements FirewallService, FirewallManager, Manager{
|
||||
private static final Logger s_logger = Logger.getLogger(FirewallManagerImpl.class);
|
||||
String _name;
|
||||
|
||||
@Inject
|
||||
FirewallRulesDao _firewallDao;
|
||||
@Inject
|
||||
IPAddressDao _ipAddressDao;
|
||||
@Inject
|
||||
EventDao _eventDao;
|
||||
@Inject
|
||||
DomainDao _domainDao;
|
||||
@Inject
|
||||
FirewallRulesCidrsDao _firewallCidrsDao;
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
@Inject
|
||||
NetworkManager _networkMgr;
|
||||
@Inject
|
||||
UsageEventDao _usageEventDao;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_name = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart() ,rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType());
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewll rule", create = true)
|
||||
public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart,Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType) throws NetworkRuleConflictException{
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
|
||||
|
||||
// Validate ip address
|
||||
if (ipAddress == null) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
|
||||
} else if (ipAddress.isOneToOneNat()) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
|
||||
}
|
||||
|
||||
validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol);
|
||||
|
||||
if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
|
||||
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
|
||||
}
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAccountId();
|
||||
Long domainId = ipAddress.getDomainId();
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
FirewallRuleVO newRule = new FirewallRuleVO (xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType);
|
||||
newRule = _firewallDao.persist(newRule);
|
||||
|
||||
detectRulesConflict(newRule, ipAddress);
|
||||
if (!_firewallDao.setStateToAdd(newRule)) {
|
||||
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
|
||||
}
|
||||
UserContext.current().setEventDetails("Rule Id: " + newRule.getId());
|
||||
|
||||
txn.commit();
|
||||
|
||||
return newRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends FirewallRule> listFirewallRules(ListFirewallRulesCmd cmd) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
Long ipId = cmd.getIpAddressId();
|
||||
Long id = cmd.getId();
|
||||
String path = null;
|
||||
|
||||
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
|
||||
String accountName = accountDomainPair.first();
|
||||
Long domainId = accountDomainPair.second();
|
||||
|
||||
if (ipId != null) {
|
||||
IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
|
||||
if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
|
||||
throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for firewall rules yet");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, ipAddressVO);
|
||||
}
|
||||
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
|
||||
Domain domain = _accountMgr.getDomain(caller.getDomainId());
|
||||
path = domain.getPath();
|
||||
}
|
||||
|
||||
Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
|
||||
sb.and("id", sb.entity().getId(), Op.EQ);
|
||||
sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
|
||||
sb.and("accountId", sb.entity().getAccountId(), Op.EQ);
|
||||
sb.and("domainId", sb.entity().getDomainId(), Op.EQ);
|
||||
sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
|
||||
|
||||
if (path != null) {
|
||||
// for domain admin we should show only subdomains information
|
||||
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
|
||||
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
|
||||
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
|
||||
}
|
||||
|
||||
SearchCriteria<FirewallRuleVO> sc = sb.create();
|
||||
|
||||
if (id != null) {
|
||||
sc.setParameters("id", id);
|
||||
}
|
||||
|
||||
if (ipId != null) {
|
||||
sc.setParameters("ip", ipId);
|
||||
}
|
||||
|
||||
if (domainId != null) {
|
||||
sc.setParameters("domainId", domainId);
|
||||
if (accountName != null) {
|
||||
Account account = _accountMgr.getActiveAccount(accountName, domainId);
|
||||
sc.setParameters("accountId", account.getId());
|
||||
}
|
||||
}
|
||||
|
||||
sc.setParameters("purpose", Purpose.Firewall);
|
||||
|
||||
if (path != null) {
|
||||
sc.setJoinParameters("domainSearch", "path", path + "%");
|
||||
}
|
||||
|
||||
return _firewallDao.search(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException {
|
||||
assert newRule.getSourceIpAddressId() == ipAddress.getId() : "You passed in an ip address that doesn't match the address in the new rule";
|
||||
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
|
||||
assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for network conflicts so we should at least have one rule at this point.";
|
||||
|
||||
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
if (rule.getId() == newRule.getId()) {
|
||||
continue; // Skips my own rule.
|
||||
}
|
||||
|
||||
if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
|
||||
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
|
||||
} else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
|
||||
throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
|
||||
}
|
||||
|
||||
if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
|
||||
throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
|
||||
}
|
||||
|
||||
boolean allowFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && newRule.getPurpose() != rule.getPurpose());
|
||||
|
||||
boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
|
||||
if (!allowFirewall && notNullPorts && ((rule.getSourcePortStart() <= newRule.getSourcePortStart() && rule.getSourcePortEnd() >= newRule.getSourcePortStart())
|
||||
|| (rule.getSourcePortStart() <= newRule.getSourcePortEnd() && rule.getSourcePortEnd() >= newRule.getSourcePortEnd())
|
||||
|| (newRule.getSourcePortStart() <= rule.getSourcePortStart() && newRule.getSourcePortEnd() >= rule.getSourcePortStart())
|
||||
|| (newRule.getSourcePortStart() <= rule.getSourcePortEnd() && newRule.getSourcePortEnd() >= rule.getSourcePortEnd()))) {
|
||||
|
||||
// we allow port forwarding rules with the same parameters but different protocols
|
||||
boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
|
||||
boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
|
||||
|
||||
if (!(allowPf || allowStaticNat || allowFirewall)) {
|
||||
throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId()
|
||||
+ " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
|
||||
}
|
||||
}
|
||||
|
||||
if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
|
||||
if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() || newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() || newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
|
||||
throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing rules");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto) {
|
||||
// Validate ip address
|
||||
_accountMgr.checkAccess(caller, ipAddress);
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + ipAddress.getId() + " is not associated with any network");
|
||||
|
||||
}
|
||||
|
||||
Network network = _networkMgr.getNetwork(networkId);
|
||||
assert network != null : "Can't create port forwarding rule as network associated with public ip address is null...how is it possible?";
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// Verify that the network guru supports the protocol specified
|
||||
Map<Network.Capability, String> firewallCapabilities = _networkMgr.getServiceCapabilities(network.getDataCenterId(), network.getNetworkOfferingId(), Service.Firewall);
|
||||
String supportedProtocols = firewallCapabilities.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(proto.toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException {
|
||||
if (!_networkMgr.applyRules(rules, continueOnError)) {
|
||||
s_logger.warn("Rules are not completely applied");
|
||||
return false;
|
||||
} else {
|
||||
for (FirewallRule rule : rules) {
|
||||
if (rule.getState() == FirewallRule.State.Revoke) {
|
||||
_firewallDao.remove(rule.getId());
|
||||
} else if (rule.getState() == FirewallRule.State.Add) {
|
||||
FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
|
||||
ruleVO.setState(FirewallRule.State.Active);
|
||||
_firewallDao.update(ruleVO.getId(), ruleVO);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
|
||||
|
||||
if (rules.size() == 0) {
|
||||
s_logger.debug("There are no firewall rules to apply for ip id=" + rules);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (FirewallRuleVO rule: rules){
|
||||
// load cidrs if any
|
||||
rule.setSourceCidrList(_firewallCidrsDao.getSourceCidrs(rule.getId()));
|
||||
}
|
||||
|
||||
|
||||
if (caller != null) {
|
||||
_accountMgr.checkAccess(caller, rules.toArray(new FirewallRuleVO[rules.size()]));
|
||||
}
|
||||
|
||||
try {
|
||||
if (!applyRules(rules, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to apply firewall rules due to ", ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
|
||||
public boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {
|
||||
|
||||
FirewallRuleVO rule = _firewallDao.findById(ruleId);
|
||||
if (rule == null || rule.getPurpose() != Purpose.Firewall) {
|
||||
throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, rule);
|
||||
|
||||
|
||||
revokeRule(rule, caller, userId, false);
|
||||
|
||||
boolean success = false;
|
||||
|
||||
if (apply) {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeFirewallRule(long ruleId, boolean apply) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long userId = UserContext.current().getCallerUserId();
|
||||
return revokeFirewallRule(ruleId, apply, caller, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public void revokeRule(FirewallRuleVO rule, Account caller, long userId, boolean needUsageEvent) {
|
||||
if (caller != null) {
|
||||
_accountMgr.checkAccess(caller, 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);
|
||||
}
|
||||
_firewallDao.remove(rule.getId());
|
||||
generateUsageEvent = true;
|
||||
} else if (rule.getState() == State.Add || rule.getState() == State.Active) {
|
||||
rule.setState(State.Revoke);
|
||||
_firewallDao.update(rule.getId(), rule);
|
||||
generateUsageEvent = true;
|
||||
}
|
||||
|
||||
if (generateUsageEvent && needUsageEvent) {
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), null);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FirewallRule getFirewallRule(long ruleId) {
|
||||
return _firewallDao.findById(ruleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeFirewallRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRule> rules = new ArrayList<FirewallRule>();
|
||||
|
||||
List<FirewallRuleVO> fwRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Releasing " + fwRules.size() + " firewall rules for ip id=" + ipId);
|
||||
}
|
||||
|
||||
for (FirewallRuleVO rule : fwRules) {
|
||||
// Mark all Firewall 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
|
||||
revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
|
||||
}
|
||||
|
||||
// now send everything to the backend
|
||||
List<FirewallRuleVO> rulesToApply = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
|
||||
applyFirewallRules(rulesToApply, true, caller);
|
||||
|
||||
// Now we check again in case more rules have been inserted.
|
||||
rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall));
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully released firewall rules for ip id=" + ipId + " and # of rules now = " + rules.size());
|
||||
}
|
||||
|
||||
return rules.size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType) throws NetworkRuleConflictException{
|
||||
|
||||
//If firwallRule for this port range already exists, return it
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, protocol, Purpose.Firewall);
|
||||
if (!rules.isEmpty()) {
|
||||
return rules.get(0);
|
||||
}
|
||||
|
||||
List<String> oneCidr = new ArrayList<String>();
|
||||
oneCidr.add(NetUtils.ALL_CIDRS);
|
||||
return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRule> rules = new ArrayList<FirewallRule>();
|
||||
|
||||
List<FirewallRuleVO> fwRules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Releasing " + fwRules.size() + " firewall rules for network id=" + networkId);
|
||||
}
|
||||
|
||||
for (FirewallRuleVO rule : fwRules) {
|
||||
// Mark all Firewall 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
|
||||
revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
|
||||
}
|
||||
|
||||
// now send everything to the backend
|
||||
List<FirewallRuleVO> rulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
|
||||
applyFirewallRules(rulesToApply, true, caller);
|
||||
|
||||
// Now we check again in case more rules have been inserted.
|
||||
rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall));
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Successfully released firewall rules for network id=" + networkId + " and # of rules now = " + rules.size());
|
||||
}
|
||||
|
||||
return rules.size() == 0;
|
||||
}
|
||||
}
|
||||
@ -58,11 +58,11 @@ import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.LoadBalancerDao;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapDao;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
|
||||
import com.cloud.network.rules.FirewallManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.LoadBalancer;
|
||||
import com.cloud.network.rules.PortForwardingRuleVO;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
@ -122,6 +122,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
UsageEventDao _usageEventDao;
|
||||
@Inject
|
||||
FirewallRulesCidrsDao _firewallCidrsDao;
|
||||
@Inject
|
||||
FirewallManager _firewallMgr;
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ -346,7 +348,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
|
||||
@Override @DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer")
|
||||
public LoadBalancer createLoadBalancerRule(LoadBalancer lb) throws NetworkRuleConflictException {
|
||||
public LoadBalancer createLoadBalancerRule(LoadBalancer lb, boolean openFirewall) throws NetworkRuleConflictException {
|
||||
UserContext caller = UserContext.current();
|
||||
|
||||
long ipId = lb.getSourceIpAddressId();
|
||||
@ -362,18 +364,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
int defPortStart = lb.getDefaultPortStart();
|
||||
int defPortEnd = lb.getDefaultPortEnd();
|
||||
|
||||
if (!NetUtils.isValidPort(srcPortStart)) {
|
||||
throw new InvalidParameterValueException("publicPort is an invalid value: " + srcPortStart);
|
||||
}
|
||||
if (!NetUtils.isValidPort(srcPortEnd)) {
|
||||
throw new InvalidParameterValueException("Public port range is an invalid value: " + srcPortEnd);
|
||||
}
|
||||
if (srcPortStart > srcPortEnd) {
|
||||
throw new InvalidParameterValueException("Public port range is an invalid value: " + srcPortStart + "-" + srcPortEnd);
|
||||
}
|
||||
if (!NetUtils.isValidPort(defPortStart)) {
|
||||
throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortStart);
|
||||
}
|
||||
_firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol());
|
||||
|
||||
if (!NetUtils.isValidPort(defPortEnd)) {
|
||||
throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortEnd);
|
||||
}
|
||||
@ -384,29 +376,27 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm());
|
||||
}
|
||||
|
||||
Long networkId = ipAddr.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create load balancer rule ; ip id=" + ipId + " is not associated with any network");
|
||||
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller.getCaller(), ipAddr);
|
||||
|
||||
// verify that lb service is supported by the network
|
||||
Network network = _networkMgr.getNetwork(networkId);
|
||||
Network network = _networkMgr.getNetwork(ipAddr.getAssociatedWithNetworkId());
|
||||
if (!_networkMgr.isServiceSupported(network.getNetworkOfferingId(), Service.Lb)) {
|
||||
throw new InvalidParameterValueException("LB service is not supported in network id=" + networkId);
|
||||
throw new InvalidParameterValueException("LB service is not supported in network id=" + network.getId());
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
|
||||
if (openFirewall) {
|
||||
_firewallMgr.createRuleForAllCidrs(ipId, caller.getCaller(), lb.getSourcePortStart(), lb.getSourcePortEnd(), lb.getProtocol(), null, null);
|
||||
}
|
||||
|
||||
LoadBalancerVO newRule = new LoadBalancerVO(lb.getXid(), lb.getName(), lb.getDescription(), lb.getSourceIpAddressId(), lb.getSourcePortEnd(), lb.getDefaultPortStart(),
|
||||
lb.getSourceCidrList(), lb.getAlgorithm(), networkId, ipAddr.getAccountId(), ipAddr.getDomainId());
|
||||
lb.getSourceCidrList(), lb.getAlgorithm(), network.getId(), ipAddr.getAccountId(), ipAddr.getDomainId());
|
||||
|
||||
newRule = _lbDao.persist(newRule);
|
||||
boolean success = true;
|
||||
|
||||
try {
|
||||
_rulesMgr.detectRulesConflict(newRule, ipAddr);
|
||||
_firewallMgr.detectRulesConflict(newRule, ipAddr);
|
||||
if (!_rulesDao.setStateToAdd(newRule)) {
|
||||
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
|
||||
}
|
||||
@ -415,14 +405,26 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
txn.commit();
|
||||
|
||||
// send firewallRule to the backend
|
||||
if (openFirewall) {
|
||||
success = success && _firewallMgr.applyFirewallRules(lb.getSourceIpAddressId(), caller.getCaller());
|
||||
}
|
||||
|
||||
return newRule;
|
||||
} catch (Exception e) {
|
||||
_lbDao.remove(newRule.getId());
|
||||
success = false;
|
||||
if (e instanceof NetworkRuleConflictException) {
|
||||
throw (NetworkRuleConflictException) e;
|
||||
}
|
||||
throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e);
|
||||
} finally {
|
||||
if (!success) {
|
||||
_lbDao.remove(newRule.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -50,10 +50,12 @@ import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
|
||||
import com.cloud.agent.api.routing.SavePasswordCommand;
|
||||
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
|
||||
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
|
||||
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
|
||||
import com.cloud.agent.api.routing.VmDataCommand;
|
||||
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
|
||||
import com.cloud.agent.api.to.FirewallRuleTO;
|
||||
import com.cloud.agent.api.to.IpAddressTO;
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||
@ -2086,7 +2088,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
result = result && applyPortForwardingRules(router, (List<PortForwardingRule>) rules);
|
||||
} else if (rules.get(0).getPurpose() == Purpose.StaticNat) {
|
||||
result = result && applyStaticNatRules(router, (List<StaticNatRule>) rules);
|
||||
} else {
|
||||
} else if (rules.get(0).getPurpose() == Purpose.Firewall) {
|
||||
result = result && applyFirewallRules(router, (List<FirewallRule>) rules);
|
||||
}else {
|
||||
s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose());
|
||||
result = false;
|
||||
}
|
||||
@ -2131,4 +2135,32 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
}
|
||||
return vrs;
|
||||
}
|
||||
|
||||
private void createFirewallRulesCommands(List<? extends FirewallRule> rules, DomainRouterVO router, Commands cmds) {
|
||||
List<FirewallRuleTO> rulesTO = null;
|
||||
if (rules != null) {
|
||||
rulesTO = new ArrayList<FirewallRuleTO>();
|
||||
for (FirewallRule rule : rules) {
|
||||
IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
|
||||
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, sourceIp.getAddress().addr());
|
||||
rulesTO.add(ruleTO);
|
||||
}
|
||||
}
|
||||
|
||||
SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
|
||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
|
||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress());
|
||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
|
||||
DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn());
|
||||
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
|
||||
cmds.addCommand(cmd);
|
||||
}
|
||||
|
||||
|
||||
protected boolean applyFirewallRules(DomainRouterVO router, List<FirewallRule> rules) throws ResourceUnavailableException {
|
||||
Commands cmds = new Commands(OnError.Continue);
|
||||
createFirewallRulesCommands(rules, router, cmds);
|
||||
// Send commands to router
|
||||
return sendCommandsToRouter(router, cmds);
|
||||
}
|
||||
}
|
||||
|
||||
58
server/src/com/cloud/network/rules/FirewallManager.java
Normal file
58
server/src/com/cloud/network/rules/FirewallManager.java
Normal file
@ -0,0 +1,58 @@
|
||||
package com.cloud.network.rules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.firewall.FirewallService;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
public interface FirewallManager extends FirewallService{
|
||||
/**
|
||||
* detectRulesConflict finds conflicts in networking rules. It checks for
|
||||
* conflicts between the following types of netowrking rules;
|
||||
* 1. one to one nat ip forwarding
|
||||
* 2. port forwarding
|
||||
* 3. load balancing
|
||||
*
|
||||
* It is possible for two conflicting rules to be added at the same time
|
||||
* and conflicts are detected between those two rules. In this case, it
|
||||
* is possible for both rules to be rolled back when, technically, we should
|
||||
* only roll back one of the rules. However, the chances of that is low
|
||||
* and the user can simply re-add one of the rules themselves.
|
||||
*
|
||||
* @param newRule the new rule created.
|
||||
* @param ipAddress ip address that back up the new rule.
|
||||
* @throws NetworkRuleConflictException
|
||||
*/
|
||||
void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException;
|
||||
|
||||
void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto);
|
||||
|
||||
boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException;
|
||||
|
||||
boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller);
|
||||
|
||||
public void revokeRule(FirewallRuleVO rule, Account caller, long userId, boolean needUsageEvent);
|
||||
|
||||
boolean revokeFirewallRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Revokes a firewall rule
|
||||
* @param ruleId the id of the rule to revoke.
|
||||
* @param caller TODO
|
||||
* @param userId TODO
|
||||
* @return
|
||||
*/
|
||||
boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId);
|
||||
|
||||
FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType)
|
||||
throws NetworkRuleConflictException;
|
||||
|
||||
FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType) throws NetworkRuleConflictException;
|
||||
|
||||
boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
}
|
||||
@ -18,6 +18,7 @@
|
||||
package com.cloud.network.rules;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
@ -32,6 +33,7 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
@ -60,10 +62,10 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
long sourceIpAddressId;
|
||||
|
||||
@Column(name="start_port", updatable=false)
|
||||
int sourcePortStart;
|
||||
Integer sourcePortStart;
|
||||
|
||||
@Column(name="end_port", updatable=false)
|
||||
int sourcePortEnd;
|
||||
Integer sourcePortEnd;
|
||||
|
||||
@Column(name="protocol", updatable=false)
|
||||
String protocol = NetUtils.TCP_PROTO;
|
||||
@ -81,6 +83,28 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
|
||||
@Column(name="network_id")
|
||||
long networkId;
|
||||
|
||||
@Column(name="icmp_code")
|
||||
Integer icmpCode;
|
||||
|
||||
@Column(name="icmp_type")
|
||||
Integer icmpType;
|
||||
|
||||
// This is a delayed load value. If the value is null,
|
||||
// then this field has not been loaded yet.
|
||||
// Call firewallrules dao to load it.
|
||||
@Transient
|
||||
List<String> sourceCidrs;
|
||||
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrs) {
|
||||
this.sourceCidrs=sourceCidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
@ -108,12 +132,12 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return sourcePortStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
return sourcePortEnd;
|
||||
}
|
||||
|
||||
@ -148,7 +172,7 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
protected FirewallRuleVO() {
|
||||
}
|
||||
|
||||
public FirewallRuleVO(String xId, long ipAddressId, int portStart, int portEnd, String protocol, long networkId, long accountId, long domainId, Purpose purpose) {
|
||||
public FirewallRuleVO(String xId, long ipAddressId, Integer portStart, Integer portEnd, String protocol, long networkId, long accountId, long domainId, Purpose purpose, List<String> sourceCidrs, Integer icmpCode, Integer icmpType) {
|
||||
this.xId = xId;
|
||||
if (xId == null) {
|
||||
this.xId = UUID.randomUUID().toString();
|
||||
@ -162,10 +186,13 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
this.purpose = purpose;
|
||||
this.networkId = networkId;
|
||||
this.state = State.Staged;
|
||||
this.icmpCode = icmpCode;
|
||||
this.icmpType = icmpType;
|
||||
this.sourceCidrs = sourceCidrs;
|
||||
}
|
||||
|
||||
public FirewallRuleVO(String xId, long ipAddressId, int port, String protocol, long networkId, long accountId, long domainId, Purpose purpose) {
|
||||
this(xId, ipAddressId, port, port, protocol, networkId, accountId, domainId, purpose);
|
||||
public FirewallRuleVO(String xId, long ipAddressId, int port, String protocol, long networkId, long accountId, long domainId, Purpose purpose, List<String> sourceCidrs, Integer icmpCode, Integer icmpType) {
|
||||
this(xId, ipAddressId, port, port, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -173,4 +200,14 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
return new StringBuilder("Rule[").append(id).append("-").append(purpose).append("-").append(state).append("]").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return icmpCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return icmpType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
@ -48,35 +47,17 @@ public class PortForwardingRuleVO extends FirewallRuleVO implements PortForwardi
|
||||
private int destinationPortEnd;
|
||||
|
||||
@Column(name="instance_id")
|
||||
private long virtualMachineId;
|
||||
|
||||
// This is a delayed load value. If the value is null,
|
||||
// then this field has not been loaded yet.
|
||||
// Call firewallrules dao to load it.
|
||||
@Transient
|
||||
List<String> sourceCidrs;
|
||||
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrs) {
|
||||
this.sourceCidrs=sourceCidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrs;
|
||||
}
|
||||
|
||||
private long virtualMachineId;
|
||||
|
||||
public PortForwardingRuleVO() {
|
||||
}
|
||||
|
||||
public PortForwardingRuleVO(String xId, long srcIpId, int srcPortStart, int srcPortEnd, Ip dstIp, int dstPortStart, int dstPortEnd, String protocol, List<String> sourceCidrs, long networkId, long accountId, long domainId, long instanceId) {
|
||||
super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding);
|
||||
super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding, sourceCidrs, null, null);
|
||||
this.destinationIpAddress = dstIp;
|
||||
this.virtualMachineId = instanceId;
|
||||
this.destinationPortStart = dstPortStart;
|
||||
this.destinationPortEnd = dstPortEnd;
|
||||
this.sourceCidrs = sourceCidrs;
|
||||
this.destinationPortEnd = dstPortEnd;
|
||||
}
|
||||
|
||||
public PortForwardingRuleVO(String xId, long srcIpId, int srcPort, Ip dstIp, int dstPort, String protocol, List<String> sourceCidrs, long networkId, long accountId, long domainId, long instanceId) {
|
||||
|
||||
@ -39,29 +39,10 @@ public interface RulesManager extends RulesService {
|
||||
|
||||
boolean applyStaticNatRulesForNetwork(long networkId, boolean continueOnError, Account caller);
|
||||
|
||||
/**
|
||||
* detectRulesConflict finds conflicts in networking rules. It checks for
|
||||
* conflicts between the following types of netowrking rules;
|
||||
* 1. one to one nat ip forwarding
|
||||
* 2. port forwarding
|
||||
* 3. load balancing
|
||||
*
|
||||
* It is possible for two conflicting rules to be added at the same time
|
||||
* and conflicts are detected between those two rules. In this case, it
|
||||
* is possible for both rules to be rolled back when, technically, we should
|
||||
* only roll back one of the rules. However, the chances of that is low
|
||||
* and the user can simply re-add one of the rules themselves.
|
||||
*
|
||||
* @param newRule the new rule created.
|
||||
* @param ipAddress ip address that back up the new rule.
|
||||
* @throws NetworkRuleConflictException
|
||||
*/
|
||||
void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException;
|
||||
|
||||
void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller);
|
||||
void checkRuleAndUserVm(FirewallRule rule, UserVm userVm, Account caller);
|
||||
|
||||
boolean revokeAllRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException;
|
||||
boolean revokeAllPFAndStaticNatRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
boolean revokeAllRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
@ -81,7 +62,7 @@ public interface RulesManager extends RulesService {
|
||||
|
||||
boolean revokeStaticNatRulesForVm(long vmId);
|
||||
|
||||
FirewallRule[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, int... ports) throws NetworkRuleConflictException;
|
||||
FirewallRule[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException;
|
||||
boolean releasePorts(long ipId, String protocol, FirewallRule.Purpose purpose, int... ports);
|
||||
|
||||
List<PortForwardingRuleVO> listByNetworkId(long networkId);
|
||||
|
||||
@ -43,14 +43,12 @@ import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.dao.FirewallRulesCidrsDao;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRule.State;
|
||||
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
@ -98,48 +96,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
UsageEventDao _usageEventDao;
|
||||
@Inject
|
||||
DomainDao _domainDao;
|
||||
@Inject
|
||||
FirewallManager _firewallMgr;
|
||||
|
||||
@Override
|
||||
public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException {
|
||||
assert newRule.getSourceIpAddressId() == ipAddress.getId() : "You passed in an ip address that doesn't match the address in the new rule";
|
||||
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
|
||||
assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for network conflicts so we should at least have one rule at this point.";
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
if (rule.getId() == newRule.getId()) {
|
||||
continue; // Skips my own rule.
|
||||
}
|
||||
|
||||
if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
|
||||
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
|
||||
} else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
|
||||
throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
|
||||
}
|
||||
|
||||
if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
|
||||
throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
|
||||
}
|
||||
|
||||
if ((rule.getSourcePortStart() <= newRule.getSourcePortStart() && rule.getSourcePortEnd() >= newRule.getSourcePortStart())
|
||||
|| (rule.getSourcePortStart() <= newRule.getSourcePortEnd() && rule.getSourcePortEnd() >= newRule.getSourcePortEnd())
|
||||
|| (newRule.getSourcePortStart() <= rule.getSourcePortStart() && newRule.getSourcePortEnd() >= rule.getSourcePortStart())
|
||||
|| (newRule.getSourcePortStart() <= rule.getSourcePortEnd() && newRule.getSourcePortEnd() >= rule.getSourcePortEnd())) {
|
||||
|
||||
// we allow port forwarding rules with the same parameters but different protocols
|
||||
boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
|
||||
boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
|
||||
if (!(allowPf || allowStaticNat)) {
|
||||
throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId()
|
||||
+ " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing rules");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) {
|
||||
@ -190,38 +150,29 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
@Override @DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
|
||||
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId) throws NetworkRuleConflictException {
|
||||
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException {
|
||||
UserContext ctx = UserContext.current();
|
||||
Account caller = ctx.getCaller();
|
||||
Long networkId = null;
|
||||
Long accountId = null;
|
||||
Long domainId = null;
|
||||
|
||||
Long ipAddrId = rule.getSourceIpAddressId();
|
||||
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
|
||||
|
||||
|
||||
// Validate ip address
|
||||
if (ipAddress == null) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
|
||||
} else if (ipAddress.isOneToOneNat()) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
|
||||
} else {
|
||||
_accountMgr.checkAccess(caller, ipAddress);
|
||||
|
||||
networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + ipAddrId + " is not associated with any network");
|
||||
|
||||
}
|
||||
// get account/domain info from the ip address (can't get it from the network as the network can be shared between
|
||||
// accounts)
|
||||
accountId = ipAddress.getAccountId();
|
||||
domainId = ipAddress.getDomainId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol());
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAccountId();
|
||||
Long domainId = ipAddress.getDomainId();
|
||||
|
||||
// start port can't be bigger than end port
|
||||
if (rule.getDestinationPortStart() > rule.getDestinationPortEnd() || rule.getSourcePortStart() > rule.getSourcePortEnd()) {
|
||||
if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
|
||||
throw new InvalidParameterValueException("Start port can't be bigger than end port");
|
||||
}
|
||||
|
||||
@ -229,17 +180,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
|
||||
throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
|
||||
}
|
||||
|
||||
Network network = _networkMgr.getNetwork(networkId);
|
||||
assert network != null : "Can't create port forwarding rule as network associated with public ip address is null...how is it possible?";
|
||||
|
||||
// Verify that the network guru supports the protocol specified
|
||||
Map<Network.Capability, String> firewallCapabilities = _networkMgr.getServiceCapabilities(network.getDataCenterId(), network.getNetworkOfferingId(), Service.Firewall);
|
||||
String supportedProtocols = firewallCapabilities.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(rule.getProtocol().toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + rule.getProtocol() + " is not supported in zone " + network.getDataCenterId());
|
||||
}
|
||||
|
||||
|
||||
// validate user VM exists
|
||||
UserVm vm = _vmDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
@ -260,12 +201,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
//create firewallRule for 0.0.0.0/0 cidr
|
||||
if (openFirewall) {
|
||||
_firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null);
|
||||
}
|
||||
|
||||
PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(),
|
||||
rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), rule.getSourceCidrList(), networkId, accountId, domainId, vmId);
|
||||
newRule = _forwardingDao.persist(newRule);
|
||||
|
||||
try {
|
||||
detectRulesConflict(newRule, ipAddress);
|
||||
_firewallMgr.detectRulesConflict(newRule, ipAddress);
|
||||
if (!_firewallDao.setStateToAdd(newRule)) {
|
||||
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
|
||||
}
|
||||
@ -285,64 +231,45 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
@Override @DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true)
|
||||
public StaticNatRule createStaticNatRule(StaticNatRule rule) throws NetworkRuleConflictException {
|
||||
public StaticNatRule createStaticNatRule(StaticNatRule rule, boolean openFirewall) throws NetworkRuleConflictException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
Long networkId = null;
|
||||
Long accountId = null;
|
||||
Long domainId = null;
|
||||
|
||||
Long ipAddrId = rule.getSourceIpAddressId();
|
||||
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
|
||||
|
||||
// Verify ip address existst and if 1-1 nat is enabled for it
|
||||
|
||||
// Validate ip address
|
||||
if (ipAddress == null) {
|
||||
throw new InvalidParameterValueException("Unable to create static nat rule; ip id=" + ipAddrId + " doesn't exist in the system");
|
||||
} else if (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getAssociatedWithVmId() == null) {
|
||||
throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
|
||||
} else {
|
||||
_accountMgr.checkAccess(caller, ipAddress);
|
||||
|
||||
networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create static nat rule ; ip id=" + ipAddrId + " is not associated with any network");
|
||||
|
||||
}
|
||||
// get account/domain info from the ip address (can't get it from the network as the network can be shared between
|
||||
// accounts)
|
||||
accountId = ipAddress.getAccountId();
|
||||
domainId = ipAddress.getDomainId();
|
||||
}
|
||||
|
||||
Network network = _networkMgr.getNetwork(networkId);
|
||||
assert network != null : "Can't create static nat rule as network associated with public ip address is null...how is it possible?";
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol());
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAccountId();
|
||||
Long domainId = ipAddress.getDomainId();
|
||||
|
||||
// Get nic IP4 address
|
||||
Nic guestNic = _networkMgr.getNicInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
|
||||
assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null...how is it possible?";
|
||||
String dstIp = guestNic.getIp4Address();
|
||||
|
||||
// Verify that the network guru supports the protocol specified
|
||||
Map<Network.Capability, String> firewallCapability = _networkMgr.getServiceCapabilities(network.getDataCenterId(), network.getNetworkOfferingId(), Service.Firewall);
|
||||
String supportedProtocols = firewallCapability.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(rule.getProtocol().toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + rule.getProtocol() + " is not supported in zone " + network.getDataCenterId());
|
||||
}
|
||||
|
||||
// start port can't be bigger than end port
|
||||
if (rule.getSourcePortStart() > rule.getSourcePortEnd()) {
|
||||
throw new InvalidParameterValueException("Start port can't be bigger than end port");
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
//create firewallRule for 0.0.0.0/0 cidr
|
||||
if (openFirewall) {
|
||||
_firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null);
|
||||
}
|
||||
|
||||
FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(),
|
||||
networkId, accountId, domainId, rule.getPurpose());
|
||||
networkId, accountId, domainId, rule.getPurpose(), null, null, null);
|
||||
newRule = _firewallDao.persist(newRule);
|
||||
|
||||
try {
|
||||
detectRulesConflict(newRule, ipAddress);
|
||||
_firewallMgr.detectRulesConflict(newRule, ipAddress);
|
||||
if (!_firewallDao.setStateToAdd(newRule)) {
|
||||
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
|
||||
}
|
||||
@ -424,68 +351,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
ipAddress.setOneToOneNat(true);
|
||||
ipAddress.setAssociatedWithVmId(vmId);
|
||||
if ( _ipAddressDao.update(ipAddress.getId(), ipAddress))
|
||||
{
|
||||
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
|
||||
|
||||
FirewallRuleVO ruleVO = new FirewallRuleVO(null, ipAddress.getId(), 0, 0, "icmp",
|
||||
networkId,vm.getAccountId(), vm.getDomainId(), Purpose.StaticNat);
|
||||
|
||||
staticNatRules.add(new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address()));
|
||||
|
||||
try {
|
||||
if (!applyRules(staticNatRules, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to apply icmp firewall rules due to ", ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
return _ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void revokeRule(FirewallRuleVO rule, Account caller, long userId) {
|
||||
if (caller != null) {
|
||||
_accountMgr.checkAccess(caller, 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);
|
||||
}
|
||||
_firewallDao.remove(rule.getId());
|
||||
generateUsageEvent = true;
|
||||
} else if (rule.getState() == State.Add || rule.getState() == State.Active) {
|
||||
rule.setState(State.Revoke);
|
||||
_firewallDao.update(rule.getId(), rule);
|
||||
generateUsageEvent = true;
|
||||
}
|
||||
|
||||
if (generateUsageEvent) {
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), null);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
}
|
||||
|
||||
// Save and create the event
|
||||
String ruleName = rule.getPurpose() == Purpose.Firewall ? "Firewall" : (rule.getPurpose() == FirewallRule.Purpose.StaticNat ? "ip forwarding" : "port forwarding");
|
||||
StringBuilder description = new StringBuilder("deleted ").append(ruleName).append(" rule [ipAddressId=").append(rule.getSourceIpAddressId()).append(":").append(rule.getSourcePortStart())
|
||||
.append("-").append(rule.getSourcePortEnd()).append("]");
|
||||
if (rule.getPurpose() == Purpose.PortForwarding) {
|
||||
PortForwardingRuleVO pfRule = (PortForwardingRuleVO) rule;
|
||||
description.append("->[").append(pfRule.getDestinationIpAddress()).append(":").append(pfRule.getDestinationPortStart()).append("-").append(pfRule.getDestinationPortEnd()).append("]");
|
||||
}
|
||||
description.append(" ").append(rule.getProtocol());
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_DELETE, eventDescription = "revoking forwarding rule", async = true)
|
||||
@ -506,7 +374,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
private boolean revokePortForwardingRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
|
||||
PortForwardingRuleVO rule = _forwardingDao.findById(ruleId);
|
||||
|
||||
revokeRule(rule, caller, userId);
|
||||
_firewallMgr.revokeRule(rule, caller, userId, true);
|
||||
|
||||
boolean success = false;
|
||||
|
||||
@ -538,7 +406,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
private boolean revokeStaticNatRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
|
||||
FirewallRuleVO rule = _firewallDao.findById(ruleId);
|
||||
|
||||
revokeRule(rule, caller, userId);
|
||||
_firewallMgr.revokeRule(rule, caller, userId, true);
|
||||
|
||||
boolean success = false;
|
||||
|
||||
@ -716,7 +584,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
try {
|
||||
if (!applyRules(rules, continueOnError)) {
|
||||
if (!_firewallMgr.applyRules(rules, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
@ -764,7 +632,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
try {
|
||||
if (!applyRules(staticNatRules, continueOnError)) {
|
||||
if (!_firewallMgr.applyRules(staticNatRules, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
@ -788,7 +656,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
try {
|
||||
if (!applyRules(rules, continueOnError)) {
|
||||
if (!_firewallMgr.applyRules(rules, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
@ -818,7 +686,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
try {
|
||||
if (!applyRules(staticNatRules, continueOnError)) {
|
||||
if (!_firewallMgr.applyRules(staticNatRules, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
@ -829,24 +697,6 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException {
|
||||
if (!_networkMgr.applyRules(rules, continueOnError)) {
|
||||
s_logger.warn("Rules are not completely applied");
|
||||
return false;
|
||||
} else {
|
||||
for (FirewallRule rule : rules) {
|
||||
if (rule.getState() == FirewallRule.State.Revoke) {
|
||||
_firewallDao.remove(rule.getId());
|
||||
} else if (rule.getState() == FirewallRule.State.Add) {
|
||||
FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
|
||||
ruleVO.setState(FirewallRule.State.Active);
|
||||
_firewallDao.update(ruleVO.getId(), ruleVO);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends FirewallRule> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
@ -934,7 +784,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeAllRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
|
||||
public boolean revokeAllPFAndStaticNatRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRule> rules = new ArrayList<FirewallRule>();
|
||||
|
||||
List<PortForwardingRuleVO> pfRules = _forwardingDao.listByIpAndNotRevoked(ipId);
|
||||
@ -1048,13 +898,18 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, int... ports) throws NetworkRuleConflictException {
|
||||
public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException {
|
||||
FirewallRuleVO[] rules = new FirewallRuleVO[ports.length];
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
for (int i = 0; i < ports.length; i++) {
|
||||
rules[i] = new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), purpose);
|
||||
|
||||
if (openFirewall) {
|
||||
_firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null);
|
||||
}
|
||||
|
||||
rules[i] = new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), purpose, null, null, null);
|
||||
rules[i] = _firewallDao.persist(rules[i]);
|
||||
}
|
||||
txn.commit();
|
||||
@ -1062,7 +917,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
boolean success = false;
|
||||
try {
|
||||
for (FirewallRuleVO newRule : rules) {
|
||||
detectRulesConflict(newRule, ip);
|
||||
_firewallMgr.detectRulesConflict(newRule, ip);
|
||||
}
|
||||
success = true;
|
||||
return rules;
|
||||
@ -1117,33 +972,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
throw new InvalidParameterValueException("One to one nat is not enabled for the ip id=" + ipId);
|
||||
}
|
||||
|
||||
if (!revokeAllRulesForIp(ipId, UserContext.current().getCallerUserId(), caller)) {
|
||||
if (!revokeAllPFAndStaticNatRulesForIp(ipId, UserContext.current().getCallerUserId(), caller)) {
|
||||
s_logger.warn("Unable to revoke all static nat rules for ip " + ipAddress);
|
||||
success = false;
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
long vmId = ipAddress.getAssociatedWithVmId();
|
||||
Nic guestNic = _networkMgr.getNicInNetwork(vmId, ipAddress.getAssociatedWithNetworkId());
|
||||
if (guestNic == null) {
|
||||
throw new InvalidParameterValueException("Vm doesn't belong to the network " + ipAddress.getAssociatedWithNetworkId());
|
||||
}
|
||||
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
|
||||
FirewallRuleVO ruleVO = new FirewallRuleVO(null, ipAddress.getId(), 0, 0, "icmp",
|
||||
ipAddress.getAssociatedWithNetworkId(),ipAddress.getAccountId(), ipAddress.getDomainId(), Purpose.StaticNat);
|
||||
|
||||
ruleVO.setState(State.Revoke);
|
||||
staticNatRules.add(new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address()));
|
||||
|
||||
try {
|
||||
if (!applyRules(staticNatRules, true)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to apply icmp firewall rules due to ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
ipAddress.setOneToOneNat(false);
|
||||
ipAddress.setAssociatedWithVmId(null);
|
||||
@ -1178,5 +1010,5 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
return new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
package com.cloud.network.rules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class StaticNatRuleImpl implements StaticNatRule{
|
||||
long id;
|
||||
@ -52,7 +54,7 @@ public class StaticNatRuleImpl implements StaticNatRule{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortEnd() {
|
||||
public Integer getSourcePortEnd() {
|
||||
return portEnd;
|
||||
}
|
||||
|
||||
@ -87,7 +89,7 @@ public class StaticNatRuleImpl implements StaticNatRule{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourcePortStart() {
|
||||
public Integer getSourcePortStart() {
|
||||
return portStart;
|
||||
}
|
||||
|
||||
@ -105,4 +107,19 @@ public class StaticNatRuleImpl implements StaticNatRule{
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,17 +24,13 @@ import javax.ejb.Local;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesDaoImpl;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRule.State;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.PortForwardingRuleVO;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
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.Transaction;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
||||
@Local(value=PortForwardingRulesDao.class)
|
||||
@ -153,50 +149,5 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
public void saveSourceCidrs(PortForwardingRuleVO portForwardingRule) {
|
||||
List<String> cidrlist = portForwardingRule.getSourceCidrList();
|
||||
if (cidrlist == null) {
|
||||
return;
|
||||
}
|
||||
_portForwardingRulesCidrsDao.persist(portForwardingRule.getId(), cidrlist);
|
||||
}
|
||||
|
||||
|
||||
public void loadSourceCidrs(PortForwardingRuleVO portForwardingRule){
|
||||
List<String> sourceCidrs = _portForwardingRulesCidrsDao.getSourceCidrs(portForwardingRule.getId());
|
||||
portForwardingRule.setSourceCidrList(sourceCidrs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override @DB
|
||||
public PortForwardingRuleVO persist(PortForwardingRuleVO portForwardingRule) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
PortForwardingRuleVO dbfirewallRule = super.persist(portForwardingRule);
|
||||
saveSourceCidrs(portForwardingRule);
|
||||
|
||||
txn.commit();
|
||||
return dbfirewallRule;
|
||||
}
|
||||
|
||||
|
||||
@Override @DB
|
||||
public boolean update(Long portForwardingRuleId, PortForwardingRuleVO portForwardingRule) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
boolean persisted = super.update(portForwardingRuleId, portForwardingRule);
|
||||
if (!persisted) {
|
||||
return persisted;
|
||||
}
|
||||
saveSourceCidrs(portForwardingRule);
|
||||
|
||||
txn.commit();
|
||||
return persisted;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.RemoteAccessVpnDao;
|
||||
import com.cloud.network.dao.VpnUserDao;
|
||||
import com.cloud.network.router.VirtualNetworkApplianceManager;
|
||||
import com.cloud.network.rules.FirewallManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
@ -87,6 +88,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
@Inject RulesManager _rulesMgr;
|
||||
@Inject DomainDao _domainDao;
|
||||
@Inject FirewallRulesDao _rulesDao;
|
||||
@Inject FirewallManager _firewallMgr;
|
||||
|
||||
int _userLimit;
|
||||
int _pskLength;
|
||||
@ -94,7 +96,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
SearchBuilder<RemoteAccessVpnVO> VpnSearch;
|
||||
|
||||
@Override
|
||||
public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange) throws NetworkRuleConflictException {
|
||||
public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException {
|
||||
UserContext ctx = UserContext.current();
|
||||
Account caller = ctx.getCaller();
|
||||
|
||||
@ -165,7 +167,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
long startIp = NetUtils.ip2Long(range[0]);
|
||||
String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
|
||||
String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
|
||||
_rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
|
||||
_rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
|
||||
vpnVO = new RemoteAccessVpnVO(ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId(), ipAddr.getAssociatedWithNetworkId(),
|
||||
publicIpId, range[0], newIpRange, sharedSecret);
|
||||
return _remoteAccessVpnDao.persist(vpnVO);
|
||||
@ -302,7 +304,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteAccessVpnVO startRemoteAccessVpn(long vpnId) throws ResourceUnavailableException {
|
||||
public RemoteAccessVpnVO startRemoteAccessVpn(long vpnId, boolean openFirewall) throws ResourceUnavailableException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(vpnId);
|
||||
@ -311,18 +313,28 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, vpn);
|
||||
|
||||
|
||||
|
||||
Network network = _networkMgr.getNetwork(vpn.getNetworkId());
|
||||
|
||||
List<? extends RemoteAccessVpnElement> elements = _networkMgr.getRemoteAccessVpnElements();
|
||||
boolean started = false;
|
||||
try {
|
||||
for (RemoteAccessVpnElement element : elements) {
|
||||
if (element.startVpn(network, vpn)) {
|
||||
started = true;
|
||||
break;
|
||||
boolean firewallOpened = true;
|
||||
if (openFirewall) {
|
||||
firewallOpened = _firewallMgr.applyFirewallRules(vpn.getServerAddressId(), caller);
|
||||
}
|
||||
|
||||
if (firewallOpened) {
|
||||
for (RemoteAccessVpnElement element : elements) {
|
||||
if (element.startVpn(network, vpn)) {
|
||||
started = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vpn;
|
||||
} finally {
|
||||
if (started) {
|
||||
|
||||
@ -333,7 +333,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
|
||||
String publicCidr = NetUtils.ipAndNetMaskToCidr(secStorageVm.getPublicIpAddress(), secStorageVm.getPublicNetmask());
|
||||
if (NetUtils.isNetworkAWithinNetworkB(privateCidr, publicCidr) || NetUtils.isNetworkAWithinNetworkB(publicCidr, privateCidr)) {
|
||||
s_logger.info("private and public interface overlaps, add a default route through private interface. privateCidr: " + privateCidr + ", publicCidr: " + publicCidr);
|
||||
allowedCidrs.add("0.0.0.0/0");
|
||||
allowedCidrs.add(NetUtils.ALL_CIDRS);
|
||||
}
|
||||
setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
|
||||
}
|
||||
|
||||
@ -578,8 +578,8 @@ CREATE TABLE `cloud`.`op_dc_vnet_alloc` (
|
||||
CREATE TABLE `cloud`.`firewall_rules` (
|
||||
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
|
||||
`ip_address_id` bigint unsigned NOT NULL COMMENT 'id of the corresponding ip address',
|
||||
`start_port` int(10) NOT NULL COMMENT 'starting port of a port range',
|
||||
`end_port` int(10) NOT NULL COMMENT 'end port of a port range',
|
||||
`start_port` int(10) COMMENT 'starting port of a port range',
|
||||
`end_port` int(10) COMMENT 'end port of a port range',
|
||||
`state` char(32) NOT NULL COMMENT 'current state of this rule',
|
||||
`protocol` char(16) NOT NULL default 'TCP' COMMENT 'protocol to open these ports for',
|
||||
`purpose` char(32) NOT NULL COMMENT 'why are these ports opened?',
|
||||
@ -588,6 +588,8 @@ CREATE TABLE `cloud`.`firewall_rules` (
|
||||
`network_id` bigint unsigned NOT NULL COMMENT 'network id',
|
||||
`xid` char(40) NOT NULL COMMENT 'external id',
|
||||
`created` datetime COMMENT 'Date created',
|
||||
`icmp_code` int(10) COMMENT 'The ICMP code (if protocol=ICMP). A value of -1 means all codes for the given ICMP type.',
|
||||
`icmp_type` int(10) COMMENT 'The ICMP type (if protocol=ICMP). A value of -1 means all types.',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_firewall_rules__ip_address_id` FOREIGN KEY(`ip_address_id`) REFERENCES `user_ip_address`(`id`),
|
||||
CONSTRAINT `fk_firewall_rules__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE,
|
||||
|
||||
@ -54,6 +54,8 @@ public class NetUtils {
|
||||
public final static String ANY_PROTO = "any";
|
||||
public final static String ICMP_PROTO = "icmp";
|
||||
public final static String ALL_PROTO = "all";
|
||||
|
||||
public final static String ALL_CIDRS = "0.0.0.0/0";
|
||||
|
||||
private final static Random _rand = new Random(System.currentTimeMillis());
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user