mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-15 18:12:35 +01:00
Added 2 new api commands for 1-1 nat feauture: enable/disableOneToOneNat. Here is the 1-1 nat api summary:
* to enable 1-1 nat for ip/vm use enalbeOneToOneNat api * to open port range (or multiple port ranges) use createIpForwardingRule api. * to delete one port range use deleteIpForwardingRule api. * to disable 1-1 nat use disableOneToOneNat api.
This commit is contained in:
parent
c70113835d
commit
731e78937f
@ -28,7 +28,9 @@ import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.response.FirewallRuleResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.rules.PortForwardingRule;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
@ -46,9 +48,6 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
|
||||
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the public IP address of the forwarding rule, already associated via associateIp")
|
||||
private String ipAddress;
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for the forwarding rule")
|
||||
private Long virtualMachineId;
|
||||
|
||||
@Parameter(name=ApiConstants.START_PORT, type=CommandType.INTEGER, required=true, description="the start port for the rule")
|
||||
private Integer startPort;
|
||||
@ -58,6 +57,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
|
||||
@Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, required=true, description="the protocol for the rule. Valid values are TCP or UDP.")
|
||||
private String protocol;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
@ -66,10 +66,6 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public long getVirtualMachineId() {
|
||||
return virtualMachineId;
|
||||
}
|
||||
|
||||
public int getStartPort() {
|
||||
return startPort;
|
||||
@ -113,7 +109,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
public void create() {
|
||||
PortForwardingRule rule;
|
||||
try {
|
||||
rule = _rulesService.createPortForwardingRule(this, virtualMachineId, true);
|
||||
rule = _rulesService.createPortForwardingRule(this, getVirtualMachineId(), true);
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.info("Unable to create Port Forwarding Rule due to " + e.getMessage());
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
@ -140,7 +136,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return ("Creating an ipforwarding 1:1 NAT rule for "+ipAddress+" with virtual machine:"+virtualMachineId);
|
||||
return ("Creating an ipforwarding 1:1 NAT rule for "+ipAddress+" with virtual machine:"+ getVirtualMachineId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,5 +221,16 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Por
|
||||
public boolean isOneToOneNat() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVirtualMachineId() {
|
||||
IpAddress ip = _networkService.getIp(new Ip(ipAddress));
|
||||
if (ip == null) {
|
||||
throw new InvalidParameterValueException("Ip address " + ipAddress + " doesn't exist in the system");
|
||||
} else {
|
||||
return _networkService.getIp(new Ip(ipAddress)).getVmId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ 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.network.rules.PortForwardingRule;
|
||||
|
||||
@Implementation(description="Deletes an ip forwarding rule", responseObject=SuccessResponse.class)
|
||||
@ -79,7 +80,12 @@ public class DeleteIpForwardingRuleCmd extends BaseAsyncCmd {
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
if (ownerId == null) {
|
||||
ownerId = _entityMgr.findById(PortForwardingRule.class, id).getAccountId();
|
||||
PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, id);
|
||||
if (rule == null) {
|
||||
throw new InvalidParameterValueException("Unable to find firewall rule by id: " + id);
|
||||
} else {
|
||||
ownerId = rule.getAccountId();
|
||||
}
|
||||
}
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
88
api/src/com/cloud/api/commands/DisableOneToOneNat.java
Normal file
88
api/src/com/cloud/api/commands/DisableOneToOneNat.java
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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.ResourceUnavailableException;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
@Implementation(description="Disables one to one nat rule", responseObject=SuccessResponse.class)
|
||||
public class DisableOneToOneNat extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeletePortForwardingRuleCmd.class.getName());
|
||||
private static final String s_name = "disableonetoonenatresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the public IP address for which one-to-one nat feature is being disableed")
|
||||
private String ipAddress;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_DISABLE_ONE_TO_ONE_NAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return ("Disabling one to one nat for ip=" + ipAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return _entityMgr.findById(IpAddress.class, ipAddress).getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
boolean result = _rulesService.disableOneToOneNat(new Ip(ipAddress));
|
||||
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to disable oneToOne nat rule");
|
||||
}
|
||||
}
|
||||
}
|
||||
86
api/src/com/cloud/api/commands/EnableOneToOneNat.java
Normal file
86
api/src/com/cloud/api/commands/EnableOneToOneNat.java
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* 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.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.exception.NetworkRuleConflictException;
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
@Implementation(description="Enables one to one nat for the ip address", responseObject=SuccessResponse.class)
|
||||
public class EnableOneToOneNat extends BaseCmd{
|
||||
public static final Logger s_logger = Logger.getLogger(CreateIpForwardingRuleCmd.class.getName());
|
||||
|
||||
private static final String s_name = "enableonetoonenatresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the public IP address for which one-to-one nat feature is being enabled")
|
||||
private String ipAddress;
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for enabling one-to-one nat feature")
|
||||
private Long virtualMachineId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public Long getVirtualMachineId() {
|
||||
return virtualMachineId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
try {
|
||||
boolean result = _rulesService.enableOneToOneNat(new Ip(ipAddress), virtualMachineId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to enable one-to-one nat");
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -183,4 +183,9 @@ public class EventTypes {
|
||||
|
||||
//Custom certificates
|
||||
public static final String EVENT_UPLOAD_CUSTOM_CERTIFICATE = "UPLOAD.CUSTOM.CERTIFICATE";
|
||||
|
||||
//OneToOnenat
|
||||
public static final String EVENT_ENABLE_ONE_TO_ONE_NAT = "ONETOONENAT.ENABLE";
|
||||
public static final String EVENT_DISABLE_ONE_TO_ONE_NAT = "ONETOONENAT.DISABLE";
|
||||
|
||||
}
|
||||
|
||||
@ -66,4 +66,6 @@ public interface IpAddress extends ControlledEntity {
|
||||
boolean readyToUse();
|
||||
|
||||
Long getAssociatedWithNetworkId();
|
||||
|
||||
Long getVmId();
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
|
||||
public interface NetworkService {
|
||||
@ -58,4 +59,6 @@ public interface NetworkService {
|
||||
|
||||
Network getNetwork(long networkId);
|
||||
|
||||
IpAddress getIp(Ip ip);
|
||||
|
||||
}
|
||||
|
||||
@ -54,4 +54,9 @@ public interface RulesService {
|
||||
public List<? extends PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesCmd cmd);
|
||||
|
||||
boolean applyPortForwardingRules(Ip ip, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
boolean enableOneToOneNat(Ip ipAddress, long vmId) throws NetworkRuleConflictException;
|
||||
|
||||
boolean disableOneToOneNat(Ip ipAddress);
|
||||
|
||||
}
|
||||
|
||||
@ -111,9 +111,11 @@ deletePortForwardingRule=com.cloud.api.commands.DeletePortForwardingRuleCmd;15
|
||||
#### updatePortForwardingRule=com.cloud.api.commands.UpdatePortForwardingRuleCmd;15
|
||||
|
||||
#### NAT commands
|
||||
enableOneToOneNat=com.cloud.api.commands.EnableOneToOneNat;15
|
||||
createIpForwardingRule=com.cloud.api.commands.CreateIpForwardingRuleCmd;15
|
||||
deleteIpForwardingRule=com.cloud.api.commands.DeleteIpForwardingRuleCmd;15
|
||||
listIpForwardingRules=com.cloud.api.commands.ListIpForwardingRulesCmd;15
|
||||
disableOneToOneNat=com.cloud.api.commands.DisableOneToOneNat;15
|
||||
|
||||
#### load balancer commands
|
||||
createLoadBalancerRule=com.cloud.api.commands.CreateLoadBalancerRuleCmd;15
|
||||
|
||||
@ -65,6 +65,9 @@ public class IPAddressVO implements IpAddress {
|
||||
@Column(name="one_to_one_nat")
|
||||
private boolean oneToOneNat;
|
||||
|
||||
@Column(name="vm_id")
|
||||
private Long associatedWithVmId;
|
||||
|
||||
@Column(name="state")
|
||||
private State state;
|
||||
|
||||
@ -121,6 +124,15 @@ public class IPAddressVO implements IpAddress {
|
||||
public void setAssociatedWithNetworkId(Long networkId) {
|
||||
this.associatedWithNetworkId = networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVmId() {
|
||||
return associatedWithVmId;
|
||||
}
|
||||
|
||||
public void setAssociatedWithVmId(Long vmId) {
|
||||
this.associatedWithVmId = vmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getAllocatedInDomainId() {
|
||||
@ -193,5 +205,6 @@ public class IPAddressVO implements IpAddress {
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("Ip[").append(address).append("-").append(dataCenterId).append("]").toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1979,4 +1979,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
assert vos.size() <= 1 : "If we have multiple networks of the same type, then this method should no longer be used.";
|
||||
return vos.size() == 1 ? vos.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpAddress getIp(Ip ip) {
|
||||
return _ipAddressDao.findById(ip);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +79,11 @@ public class PublicIp implements PublicIpAddress {
|
||||
return _addr.isOneToOneNat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVmId() {
|
||||
return _addr.getVmId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getAllocatedTime() {
|
||||
return _addr.getAllocatedTime();
|
||||
|
||||
@ -29,7 +29,7 @@ import com.cloud.utils.net.Ip;
|
||||
* Data Access Object for user_ip_address and ip_forwarding tables
|
||||
*/
|
||||
public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
|
||||
List<FirewallRuleVO> listByIpAndNotRevoked(Ip ip);
|
||||
List<FirewallRuleVO> listByIpAndNotRevoked(Ip ip, Boolean isOneToOneNat);
|
||||
|
||||
boolean setStateToAdd(FirewallRuleVO rule);
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
IpNotRevokedSearch = createSearchBuilder();
|
||||
IpNotRevokedSearch.and("ip", IpNotRevokedSearch.entity().getSourceIpAddress(), Op.EQ);
|
||||
IpNotRevokedSearch.and("state", IpNotRevokedSearch.entity().getState(), Op.NEQ);
|
||||
IpNotRevokedSearch.and("oneToOneNat", IpNotRevokedSearch.entity().isOneToOneNat(), Op.EQ);
|
||||
IpNotRevokedSearch.done();
|
||||
|
||||
ReleaseSearch = createSearchBuilder();
|
||||
@ -91,10 +92,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIpAndNotRevoked(Ip ip) {
|
||||
public List<FirewallRuleVO> listByIpAndNotRevoked(Ip ip, Boolean isOneToOneNat) {
|
||||
SearchCriteria<FirewallRuleVO> sc = IpNotRevokedSearch.create();
|
||||
sc.setParameters("ip", ip);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
if (isOneToOneNat != null) {
|
||||
sc.setParameters("oneToOneNat", isOneToOneNat);
|
||||
}
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@ -152,6 +152,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Ip> implements
|
||||
address.setAllocatedTime(null);
|
||||
address.setSourceNat(false);
|
||||
address.setOneToOneNat(false);
|
||||
address.setAssociatedWithVmId(null);
|
||||
address.setState(State.Free);
|
||||
address.setAssociatedWithNetworkId(null);
|
||||
update(ipAddress, address);
|
||||
|
||||
@ -36,7 +36,6 @@ import com.cloud.api.commands.UpdateLoadBalancerRuleCmd;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.EventVO;
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
@ -399,7 +398,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
|
||||
@Override
|
||||
public boolean removeAllLoadBalanacers(Ip ip) {
|
||||
List<FirewallRuleVO> rules = _rulesDao.listByIpAndNotRevoked(ip);
|
||||
List<FirewallRuleVO> rules = _rulesDao.listByIpAndNotRevoked(ip, null);
|
||||
if (rules != null)
|
||||
s_logger.debug("Found " + rules.size() + " lb rules to cleanup");
|
||||
for (FirewallRule rule : rules) {
|
||||
|
||||
@ -83,7 +83,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException {
|
||||
assert newRule.getSourceIpAddress().equals(ipAddress.getAddress()) : "You passed in an ip address that doesn't match the address in the new rule";
|
||||
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(newRule.getSourceIpAddress());
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(newRule.getSourceIpAddress(), 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) {
|
||||
@ -92,9 +92,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
if (rule.isOneToOneNat() && !newRule.isOneToOneNat()) {
|
||||
throw new NetworkRuleConflictException("There is already port forwarding rule specified for the " + newRule.getSourceIpAddress());
|
||||
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the " + newRule.getSourceIpAddress());
|
||||
} else if (!rule.isOneToOneNat() && newRule.isOneToOneNat()) {
|
||||
throw new NetworkRuleConflictException("There is already 1 to 1 Nat rule specified for the " + newRule.getSourceIpAddress());
|
||||
throw new NetworkRuleConflictException("There is already firewall rule specified for the " + newRule.getSourceIpAddress());
|
||||
}
|
||||
|
||||
if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
|
||||
@ -133,6 +133,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, ipAddress);
|
||||
_accountMgr.checkAccess(caller, userVm);
|
||||
|
||||
// validate that IP address and userVM belong to the same account
|
||||
@ -193,13 +194,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
long accountId = network.getAccountId();
|
||||
long domainId = network.getDomainId();
|
||||
|
||||
checkIpAndUserVm(ipAddress, vm, caller);
|
||||
if (isNat && (ipAddress.isSourceNat())) {
|
||||
if (isNat && (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getVmId() == null)) {
|
||||
throw new NetworkRuleConflictException("Can't do one to one NAT on ip address: " + ipAddress.getAddress());
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
PortForwardingRuleVO newRule =
|
||||
new PortForwardingRuleVO(rule.getXid(),
|
||||
rule.getSourceIpAddress(),
|
||||
@ -213,12 +211,6 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
accountId,
|
||||
domainId, vmId, isNat);
|
||||
newRule = _forwardingDao.persist(newRule);
|
||||
|
||||
if (isNat && !ipAddress.isOneToOneNat()) {
|
||||
ipAddress.setOneToOneNat(true);
|
||||
_ipAddressDao.update(ipAddress.getAddress(), ipAddress);
|
||||
}
|
||||
txn.commit();
|
||||
|
||||
try {
|
||||
detectRulesConflict(newRule, ipAddress);
|
||||
@ -230,21 +222,48 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
_usageEventDao.persist(usageEvent);
|
||||
return newRule;
|
||||
} catch (Exception e) {
|
||||
txn.start();
|
||||
_forwardingDao.remove(newRule.getId());
|
||||
if (isNat) {
|
||||
ipAddress.setOneToOneNat(false);
|
||||
_ipAddressDao.update(ipAddress.getAddress(), ipAddress);
|
||||
}
|
||||
txn.commit();
|
||||
if (e instanceof NetworkRuleConflictException) {
|
||||
throw (NetworkRuleConflictException)e;
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("Unable to add rule for " + newRule.getSourceIpAddress(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enableOneToOneNat(Ip ip, long vmId) throws NetworkRuleConflictException{
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ip);
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
UserVmVO vm = null;
|
||||
vm = _vmDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new InvalidParameterValueException("Can't enable one-to-one nat for the address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ").");
|
||||
}
|
||||
|
||||
checkIpAndUserVm(ipAddress, vm, caller);
|
||||
|
||||
if (ipAddress.isSourceNat()) {
|
||||
throw new InvalidParameterValueException("Can't enable one to one nat, ip address: " + ip.addr() + " is a sourceNat ip address");
|
||||
}
|
||||
|
||||
if (!ipAddress.isOneToOneNat()) {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(ip, false);
|
||||
if (rules != null && !rules.isEmpty()) {
|
||||
throw new NetworkRuleConflictException("Failed to enable one to one nat for the ip address " + ipAddress.getAddress() + " as it already has firewall rules assigned");
|
||||
}
|
||||
} else {
|
||||
if (ipAddress.getVmId() != null && ipAddress.getVmId().longValue() != vmId) {
|
||||
throw new NetworkRuleConflictException("Failed to enable one to one nat for the ip address " + ipAddress.getAddress() + " and vm id=" + vmId + " as it's already assigned to antoher vm");
|
||||
}
|
||||
}
|
||||
|
||||
ipAddress.setOneToOneNat(true);
|
||||
ipAddress.setAssociatedWithVmId(vmId);
|
||||
return _ipAddressDao.update(ipAddress.getAddress(), ipAddress);
|
||||
|
||||
}
|
||||
|
||||
protected Pair<Network, Ip> getUserVmGuestIpAddress(UserVm vm) {
|
||||
Ip dstIp = null;
|
||||
List<? extends Nic> nics = _networkMgr.getNics(vm);
|
||||
@ -276,14 +295,6 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
rule.setState(State.Revoke);
|
||||
_firewallDao.update(rule.getId(), rule);
|
||||
}
|
||||
if (rule.isOneToOneNat()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Removing one to one nat so setting the ip back to one to one nat is false: " + rule.getSourceIpAddress());
|
||||
}
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(rule.getSourceIpAddress());
|
||||
ipAddress.setOneToOneNat(false);
|
||||
_ipAddressDao.update(ipAddress.getAddress(), ipAddress);
|
||||
}
|
||||
|
||||
// Save and create the event
|
||||
String ruleName = rule.getPurpose() == Purpose.Firewall ? "Firewall" : (rule.isOneToOneNat() ? "ip forwarding" : "port forwarding");
|
||||
@ -339,7 +350,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
}
|
||||
|
||||
public List<? extends FirewallRule> listFirewallRules(Ip ip) {
|
||||
return _firewallDao.listByIpAndNotRevoked(ip);
|
||||
return _firewallDao.listByIpAndNotRevoked(ip, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -557,5 +568,53 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
public List<? extends PortForwardingRule> listByNetworkId(long networkId) {
|
||||
return _forwardingDao.listByNetworkId(networkId);
|
||||
}
|
||||
|
||||
public boolean isLastOneToOneNatRule(FirewallRule ruleToCheck) {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(ruleToCheck.getSourceIpAddress(), false);
|
||||
if (rules != null && !rules.isEmpty()) {
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
if (ruleToCheck.getId() == rule.getId()) {
|
||||
continue;
|
||||
}
|
||||
if (rule.isOneToOneNat()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableOneToOneNat(Ip ip){
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ip);
|
||||
checkIpAndUserVm(ipAddress, null, caller);
|
||||
|
||||
if (!ipAddress.isOneToOneNat()) {
|
||||
throw new InvalidParameterValueException("One to one nat is not enabled for the ip: " + ip.addr());
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(ip, true);
|
||||
if (rules != null) {
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
rule.setState(State.Revoke);
|
||||
_firewallDao.update(rule.getId(), rule);
|
||||
}
|
||||
}
|
||||
|
||||
if (applyPortForwardingRules(ip, true)) {
|
||||
ipAddress.setOneToOneNat(false);
|
||||
ipAddress.setAssociatedWithVmId(null);
|
||||
_ipAddressDao.update(ipAddress.getAddress(), ipAddress);
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to disable one to one nat for the ip address " + ip.addr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -682,6 +682,7 @@ CREATE TABLE `cloud`.`user_ip_address` (
|
||||
`allocated` datetime NULL COMMENT 'Date this ip was allocated to someone',
|
||||
`vlan_db_id` bigint unsigned NOT NULL,
|
||||
`one_to_one_nat` int(1) unsigned NOT NULL default '0',
|
||||
`vm_id` bigint unsigned COMMENT 'vm id the one_to_one nat ip is assigned to',
|
||||
`state` char(32) NOT NULL default 'Free' COMMENT 'state of the ip address',
|
||||
`mac_address` bigint unsigned NOT NULL COMMENT 'mac address of this ip',
|
||||
`network_id` bigint unsigned COMMENT 'network this public ip address is associated with',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user