mirror of https://github.com/apache/cloudstack.git
bug 10561: intermediate checkin for enable/disableStaticNat.
1) On enableStaticNat command we actually send the command to the backend (we used to just upgrade the DB in the past). The backend command carries sourceIp and destIp, and creates IP to IP mapping on the domR. 2) On disableStaticNat for the Ip address in addition to cleaning up port ranges, we also delete IP to IP mapping on the domR.
This commit is contained in:
parent
7c2395e684
commit
278f2a401f
|
|
@ -25,8 +25,8 @@ public class SetStaticNatRulesAnswer extends Answer {
|
|||
super();
|
||||
}
|
||||
|
||||
public SetStaticNatRulesAnswer(SetStaticNatRulesCommand cmd, String[] results) {
|
||||
super(cmd, true, null);
|
||||
public SetStaticNatRulesAnswer(SetStaticNatRulesCommand cmd, String[] results, Boolean success) {
|
||||
super(cmd, success, null);
|
||||
|
||||
assert(cmd.getRules().length == results.length) : "Shouldn't the results match the commands?";
|
||||
this.results = results;
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ public class StaticNatRuleTO extends FirewallRuleTO{
|
|||
}
|
||||
|
||||
|
||||
protected StaticNatRuleTO(long id, String srcIp, int srcPortStart, int srcPortEnd, String dstIp, int dstPortStart, int dstPortEnd, String protocol, boolean revoked, boolean brandNew) {
|
||||
super(id, srcIp, protocol, srcPortStart, srcPortEnd, revoked, brandNew, FirewallRule.Purpose.StaticNat, null,0,0);
|
||||
public StaticNatRuleTO(long id, String srcIp, Integer srcPortStart, Integer srcPortEnd, String dstIp, Integer dstPortStart, Integer dstPortEnd, String protocol, boolean revoked, boolean alreadyAdded) {
|
||||
super(id, srcIp, protocol, srcPortStart, srcPortEnd, revoked, alreadyAdded, FirewallRule.Purpose.StaticNat, null,0,0);
|
||||
this.dstIp = dstIp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class DisableStaticNatCmd extends BaseAsyncCmd {
|
|||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
boolean result = _rulesService.disableOneToOneNat(ipAddressId);
|
||||
boolean result = _rulesService.disableStaticNat(ipAddressId);
|
||||
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public class EnableStaticNatCmd extends BaseCmd{
|
|||
@Override
|
||||
public void execute(){
|
||||
try {
|
||||
boolean result = _rulesService.enableOneToOneNat(ipAddressId, virtualMachineId);
|
||||
boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.cloud.network.Network.Provider;
|
|||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.vm.NicProfile;
|
||||
|
|
@ -132,5 +133,14 @@ public interface NetworkElement extends Adapter {
|
|||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Creates static nat rule (public IP to private IP mapping) on the network element
|
||||
* @param config
|
||||
* @param rules
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ public interface RulesService {
|
|||
|
||||
boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException;
|
||||
|
||||
boolean enableOneToOneNat(long ipAddressId, long vmId) throws NetworkRuleConflictException;
|
||||
boolean enableStaticNat(long ipAddressId, long vmId) throws NetworkRuleConflictException;
|
||||
|
||||
boolean disableOneToOneNat(long ipAddressId) throws ResourceUnavailableException;
|
||||
boolean disableStaticNat(long ipAddressId) throws ResourceUnavailableException;
|
||||
|
||||
PortForwardingRule getPortForwardigRule(long ruleId);
|
||||
FirewallRule getFirewallRule(long ruleId);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* 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.network.rules;
|
||||
|
||||
|
||||
public interface StaticNat{
|
||||
|
||||
long getAccountId();
|
||||
|
||||
long getDomainId();
|
||||
|
||||
long getNetworkId();
|
||||
|
||||
long getSourceIpAddressId();
|
||||
|
||||
String getDestIpAddress();
|
||||
|
||||
boolean isForRevoke();
|
||||
}
|
||||
|
|
@ -193,6 +193,7 @@ public class VirtualRoutingResource implements Manager {
|
|||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
int i = 0;
|
||||
boolean endResult = true;
|
||||
for (StaticNatRuleTO rule : cmd.getRules()) {
|
||||
String result = null;
|
||||
final Script command = new Script(_firewallPath, _timeout, s_logger);
|
||||
|
|
@ -207,10 +208,15 @@ public class VirtualRoutingResource implements Manager {
|
|||
command.add(" -G ") ;
|
||||
|
||||
result = command.execute();
|
||||
results[i++] = (!(result == null || result.isEmpty())) ? "Failed" : null;
|
||||
if (result == null || result.isEmpty()) {
|
||||
results[i++] = "Failed";
|
||||
endResult = false;
|
||||
} else {
|
||||
results[i++] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new SetStaticNatRulesAnswer(cmd, results);
|
||||
return new SetStaticNatRulesAnswer(cmd, results, endResult);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
//String args = routerIp;
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
int i = 0;
|
||||
boolean endResult = true;
|
||||
for (StaticNatRuleTO rule : cmd.getRules()) {
|
||||
//1:1 NAT needs instanceip;publicip;domrip;op
|
||||
StringBuilder args = new StringBuilder();
|
||||
|
|
@ -1276,15 +1277,23 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
args.append(rule.revoked() ? " -D " : " -A ");
|
||||
args.append(" -l ").append(rule.getSrcIp());
|
||||
args.append(" -r ").append(rule.getDstIp());
|
||||
args.append(" -P ").append(rule.getProtocol().toLowerCase());
|
||||
if (rule.getProtocol() != null) {
|
||||
args.append(" -P ").append(rule.getProtocol().toLowerCase());
|
||||
}
|
||||
|
||||
args.append(" -d ").append(rule.getStringSrcPortRange());
|
||||
args.append(" -G ");
|
||||
|
||||
String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString());
|
||||
results[i++] = (result == null || result.isEmpty()) ? "Failed" : null;
|
||||
if (result == null || result.isEmpty()) {
|
||||
results[i++] = "Failed";
|
||||
endResult = false;
|
||||
} else {
|
||||
results[i++] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new SetStaticNatRulesAnswer(cmd, results);
|
||||
return new SetStaticNatRulesAnswer(cmd, results, endResult);
|
||||
}
|
||||
|
||||
protected Answer execute(final LoadBalancerConfigCommand cmd) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.cloud.network.Networks.TrafficType;
|
|||
import com.cloud.network.addr.PublicIp;
|
||||
import com.cloud.network.guru.NetworkGuru;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.vpn.PasswordResetElement;
|
||||
import com.cloud.network.vpn.RemoteAccessVpnElement;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
|
|
@ -210,4 +211,6 @@ public interface NetworkManager extends NetworkService {
|
|||
String getGlobalGuestDomainSuffix();
|
||||
|
||||
String getStartIpAddress(long networkId);
|
||||
|
||||
boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ 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.StaticNat;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
|
|
@ -3190,4 +3191,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
|
||||
return startIP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException {
|
||||
if (staticNats == null || staticNats.size() == 0) {
|
||||
s_logger.debug("There are no static nat rules for the network elements");
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean success = true;
|
||||
Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
|
||||
for (NetworkElement ne : _networkElements) {
|
||||
try {
|
||||
boolean handled = ne.applyStaticNats(network, staticNats);
|
||||
s_logger.debug("Static Nat for network " + network.getId() + " were " + (handled ? "" : " not") + " handled by " + ne.getName());
|
||||
} catch (ResourceUnavailableException e) {
|
||||
if (!continueOnError) {
|
||||
throw e;
|
||||
}
|
||||
s_logger.warn("Problems with " + ne.getName() + " but pushing on", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import com.cloud.network.dao.NetworkDao;
|
|||
import com.cloud.network.router.VirtualNetworkApplianceManager;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.vpn.PasswordResetElement;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.AccountManager;
|
||||
|
|
@ -245,4 +246,9 @@ public class DhcpElement extends AdapterBase implements NetworkElement, Password
|
|||
|
||||
return _routerMgr.savePasswordToRouter(network, nic, uservm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import com.cloud.network.PublicIpAddress;
|
|||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.lb.ElasticLoadBalancerManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
|
|
@ -166,4 +167,9 @@ public class ElasticLoadBalancerElement extends AdapterBase implements NetworkEl
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.cloud.network.element.NetworkElement;
|
|||
import com.cloud.network.ovs.OvsNetworkManager;
|
||||
import com.cloud.network.ovs.OvsTunnelManager;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.Inject;
|
||||
|
|
@ -142,5 +143,10 @@ public class OvsElement extends AdapterBase implements NetworkElement {
|
|||
throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import com.cloud.network.router.VirtualNetworkApplianceManager;
|
|||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.vpn.RemoteAccessVpnElement;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
|
|
@ -284,4 +285,21 @@ public class VirtualRouterElement extends DhcpElement implements NetworkElement,
|
|||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
DataCenter dc = _configMgr.getZone(config.getDataCenterId());
|
||||
if (canHandle(config.getGuestType(),dc)) {
|
||||
long networkId = config.getId();
|
||||
List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
|
||||
if (routers == null || routers.isEmpty()) {
|
||||
s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual router doesn't exist in the network " + config.getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
return _routerMgr.applyStaticNats(config, rules);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,6 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -516,4 +515,5 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
|
||||
return rules.size() == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.cloud.network.RemoteAccessVpn;
|
|||
import com.cloud.network.VirtualNetworkApplianceService;
|
||||
import com.cloud.network.VpnUser;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
|
@ -89,4 +90,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
|
|||
VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) throws ConcurrentOperationException, ResourceUnavailableException;
|
||||
|
||||
String getDnsBasicZoneUpdate();
|
||||
|
||||
boolean applyStaticNats(Network network, List<? extends StaticNat> rules) throws ResourceUnavailableException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ import com.cloud.network.rules.FirewallRule;
|
|||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.PortForwardingRule;
|
||||
import com.cloud.network.rules.RulesManager;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.rules.StaticNatRule;
|
||||
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
|
|
@ -2087,8 +2088,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
public boolean applyFirewallRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
|
||||
List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
|
||||
if (routers == null || routers.isEmpty()) {
|
||||
s_logger.warn("Unable to apply lb rules, virtual router doesn't exist in the network " + network.getId());
|
||||
throw new ResourceUnavailableException("Unable to apply lb rules", DataCenter.class, network.getDataCenterId());
|
||||
s_logger.warn("Unable to apply firewall rules, virtual router doesn't exist in the network " + network.getId());
|
||||
throw new ResourceUnavailableException("Unable to apply firewall rules", DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
|
|
@ -2197,4 +2198,62 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
return _dnsBasicZoneUpdates;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNats(Network network, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
|
||||
if (routers == null || routers.isEmpty()) {
|
||||
s_logger.warn("Unable to create static nat, virtual router doesn't exist in the network " + network.getId());
|
||||
throw new ResourceUnavailableException("Unable to create static nat", DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
for (DomainRouterVO router : routers) {
|
||||
if (router.getState() == State.Running) {
|
||||
s_logger.debug("Applying " + rules.size() + " static nat in network " + network);
|
||||
result = applyStaticNat(router, rules);
|
||||
|
||||
//If rules fail to apply on one domR, no need to proceed with the rest
|
||||
if (!result) {
|
||||
throw new ResourceUnavailableException("Unable to apply static nat on router ", VirtualRouter.class, router.getId());
|
||||
}
|
||||
|
||||
} else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
|
||||
s_logger.debug("Router is in " + router.getState() + ", so not sending apply firewall rules commands to the backend");
|
||||
} else {
|
||||
s_logger.warn("Unable to apply static nat, virtual router is not in the right state " + router.getState());
|
||||
throw new ResourceUnavailableException("Unable to apply static nat, virtual router is not in the right state", VirtualRouter.class, router.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected boolean applyStaticNat(DomainRouterVO router, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
Commands cmds = new Commands(OnError.Continue);
|
||||
createApplyStaticNatCommands(rules, router, cmds);
|
||||
// Send commands to router
|
||||
return sendCommandsToRouter(router, cmds);
|
||||
}
|
||||
|
||||
private void createApplyStaticNatCommands(List<? extends StaticNat> rules, DomainRouterVO router, Commands cmds) {
|
||||
List<StaticNatRuleTO> rulesTO = null;
|
||||
if (rules != null) {
|
||||
rulesTO = new ArrayList<StaticNatRuleTO>();
|
||||
for (StaticNat rule : rules) {
|
||||
IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
|
||||
StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
|
||||
rulesTO.add(ruleTO);
|
||||
}
|
||||
}
|
||||
|
||||
SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ public interface RulesManager extends RulesService {
|
|||
boolean releasePorts(long ipId, String protocol, FirewallRule.Purpose purpose, int... ports);
|
||||
|
||||
List<PortForwardingRuleVO> listByNetworkId(long networkId);
|
||||
|
||||
boolean applyStaticNat(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean enableOneToOneNat(long ipId, long vmId) throws NetworkRuleConflictException {
|
||||
public boolean enableStaticNat(long ipId, long vmId) throws NetworkRuleConflictException {
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
|
|
@ -351,7 +351,22 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
|
||||
ipAddress.setOneToOneNat(true);
|
||||
ipAddress.setAssociatedWithVmId(vmId);
|
||||
return _ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||
if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
|
||||
//enable static nat on the backend
|
||||
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
|
||||
if (applyStaticNat(ipId, false, caller, false)) {
|
||||
return true;
|
||||
} else {
|
||||
ipAddress.setOneToOneNat(false);
|
||||
ipAddress.setAssociatedWithVmId(null);
|
||||
_ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||
s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -797,10 +812,14 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
s_logger.debug("Releasing " + staticNatRules.size() + " static nat rules for ip id=" + ipId);
|
||||
}
|
||||
|
||||
|
||||
for (FirewallRuleVO rule : staticNatRules) {
|
||||
// Mark all static nat rules as Revoke, but don't revoke them yet
|
||||
revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
|
||||
}
|
||||
|
||||
//revoke static nat for the ip address
|
||||
boolean staticNatRevoked = applyStaticNat(ipId, false, caller, true);
|
||||
|
||||
// revoke all port forwarding rules
|
||||
applyPortForwardingRules(ipId, true, caller);
|
||||
|
|
@ -816,7 +835,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
s_logger.debug("Successfully released rules for ip id=" + ipId + " and # of rules now = " + rules.size());
|
||||
}
|
||||
|
||||
return rules.size() == 0;
|
||||
return (rules.size() == 0 && staticNatRevoked);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -955,7 +974,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean disableOneToOneNat(long ipId) throws ResourceUnavailableException {
|
||||
public boolean disableStaticNat(long ipId) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
|
@ -1007,4 +1026,50 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
return new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNat(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
|
||||
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
IpAddress sourceIp = _ipAddressDao.findById(sourceIpId);
|
||||
|
||||
Long networkId = sourceIp.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new CloudRuntimeException("Ip address is not associated with any network");
|
||||
}
|
||||
|
||||
UserVmVO vm = _vmDao.findById(sourceIp.getAssociatedWithVmId());
|
||||
Network network = _networkMgr.getNetwork(networkId);
|
||||
if (network == null) {
|
||||
throw new CloudRuntimeException("Unable to find ip address to map to in vm id=" + vm.getId());
|
||||
}
|
||||
|
||||
if (!sourceIp.isOneToOneNat()) {
|
||||
s_logger.debug("Source ip id=" + sourceIpId + " is not one to one nat");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (caller != null) {
|
||||
_accountMgr.checkAccess(caller, sourceIp);
|
||||
}
|
||||
|
||||
//create new static nat rule
|
||||
// Get nic IP4 address
|
||||
Nic guestNic = _networkMgr.getNicInNetwork(sourceIp.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();
|
||||
StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAccountId(), sourceIp.getDomainId(), networkId, sourceIpId, dstIp, forRevoke);
|
||||
staticNats.add(staticNat);
|
||||
|
||||
try {
|
||||
if (!_networkMgr.applyStaticNats(staticNats, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to create static nat rule due to ", ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* 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.network.rules;
|
||||
|
||||
public class StaticNatImpl implements StaticNat{
|
||||
long accountId;
|
||||
long domainId;
|
||||
long networkId;
|
||||
long sourceIpAddressId;
|
||||
String destIpAddress;
|
||||
boolean forRevoke;
|
||||
|
||||
|
||||
|
||||
public StaticNatImpl(long accountId, long domainId, long networkId, long sourceIpAddressId, String destIpAddress, boolean forRevoke) {
|
||||
super();
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.networkId = networkId;
|
||||
this.sourceIpAddressId = sourceIpAddressId;
|
||||
this.destIpAddress = destIpAddress;
|
||||
this.forRevoke = forRevoke;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSourceIpAddressId() {
|
||||
return sourceIpAddressId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDestIpAddress() {
|
||||
return destIpAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForRevoke() {
|
||||
return forRevoke;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1254,7 +1254,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(vmId);
|
||||
try {
|
||||
if (ip != null) {
|
||||
if (_rulesMgr.disableOneToOneNat(ip.getId())) {
|
||||
if (_rulesMgr.disableStaticNat(ip.getId())) {
|
||||
s_logger.debug("Disabled 1-1 nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
|
||||
} else {
|
||||
s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
|
||||
|
|
|
|||
Loading…
Reference in New Issue