mirror of https://github.com/apache/cloudstack.git
mass merge 2.2.10
This commit is contained in:
commit
51af0db682
|
|
@ -25,7 +25,7 @@ import com.cloud.agent.api.to.LoadBalancerTO;
|
|||
*/
|
||||
public class LoadBalancerConfigCommand extends NetworkElementCommand {
|
||||
LoadBalancerTO[] loadBalancers;
|
||||
public String lbStatsVisibility;
|
||||
public String lbStatsVisibility = "guest-network";
|
||||
public String lbStatsIp; /* load balancer listen on this ip for stats */
|
||||
public String lbStatsPort = "8081"; /*load balancer listen on this port for stats */
|
||||
public String lbStatsSrcCidrs = "0/0" ; /* TODO : currently there is no filtering based on the source ip */
|
||||
|
|
|
|||
|
|
@ -25,9 +25,8 @@ public class SetFirewallRulesAnswer extends Answer {
|
|||
protected SetFirewallRulesAnswer() {
|
||||
}
|
||||
|
||||
public SetFirewallRulesAnswer(SetFirewallRulesCommand cmd, String[] results) {
|
||||
super(cmd, true, null);
|
||||
|
||||
public SetFirewallRulesAnswer(SetFirewallRulesCommand cmd, Boolean success, String[] results) {
|
||||
super(cmd, success, null);
|
||||
assert (cmd.getRules().length == results.length) : "rules and their results should be the same length don't you think?";
|
||||
this.results = results;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,13 @@
|
|||
*/
|
||||
package com.cloud.agent.api.routing;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.agent.api.to.FirewallRuleTO;
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* SetFirewallRulesCommand is the transport for firewall rules.
|
||||
|
|
@ -40,4 +44,59 @@ public class SetFirewallRulesCommand extends NetworkElementCommand {
|
|||
public FirewallRuleTO[] getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
public String[][] generateFwRules() {
|
||||
String [][] result = new String [2][];
|
||||
Set<String> toAdd = new HashSet<String>();
|
||||
|
||||
|
||||
for (FirewallRuleTO fwTO: rules) {
|
||||
/* example : 172.16.92.44:tcp:80:80:0.0.0.0/0:,200.16.92.44:tcp:220:220:0.0.0.0/0:,
|
||||
* each entry format <ip>:protocol:srcport:destport:scidr:
|
||||
* reverted entry format <ip>:reverted:0:0:0:
|
||||
*/
|
||||
if (fwTO.revoked() == true)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
/* This entry is added just to make sure atleast there will one entry in the list to get the ipaddress */
|
||||
sb.append(fwTO.getSrcIp()).append(":reverted:0:0:0:");
|
||||
String fwRuleEntry = sb.toString();
|
||||
toAdd.add(fwRuleEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> cidr;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(fwTO.getSrcIp()).append(":").append(fwTO.getProtocol()).append(":");
|
||||
if ("icmp".compareTo(fwTO.getProtocol()) == 0)
|
||||
{
|
||||
sb.append(fwTO.getIcmpType()).append(":").append(fwTO.getIcmpCode()).append(":");
|
||||
|
||||
}else if (fwTO.getStringSrcPortRange() == null)
|
||||
sb.append("0:0").append(":");
|
||||
else
|
||||
sb.append(fwTO.getStringSrcPortRange()).append(":");
|
||||
|
||||
cidr = fwTO.getSourceCidrList();
|
||||
if (cidr == null || cidr.isEmpty())
|
||||
{
|
||||
sb.append("0.0.0.0/0");
|
||||
}else{
|
||||
Boolean firstEntry = true;
|
||||
for (String tag : cidr) {
|
||||
if (!firstEntry) sb.append("-");
|
||||
sb.append(tag);
|
||||
firstEntry = false;
|
||||
}
|
||||
}
|
||||
sb.append(":");
|
||||
String fwRuleEntry = sb.toString();
|
||||
|
||||
toAdd.add(fwRuleEntry);
|
||||
|
||||
}
|
||||
result[0] = toAdd.toArray(new String[toAdd.size()]);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -51,12 +51,16 @@ public class FirewallRuleTO {
|
|||
int[] srcPortRange;
|
||||
boolean revoked;
|
||||
boolean alreadyAdded;
|
||||
private List<String> sourceCidrList;
|
||||
FirewallRule.Purpose purpose;
|
||||
private Integer icmpType;
|
||||
private Integer icmpCode;
|
||||
|
||||
|
||||
protected FirewallRuleTO() {
|
||||
}
|
||||
|
||||
public FirewallRuleTO(long id, String srcIp, String protocol, Integer srcPortStart, Integer 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, List<String> sourceCidr,Integer icmpType,Integer icmpCode) {
|
||||
this.srcIp = srcIp;
|
||||
this.protocol = protocol;
|
||||
|
||||
|
|
@ -78,10 +82,13 @@ public class FirewallRuleTO {
|
|||
this.revoked = revoked;
|
||||
this.alreadyAdded = alreadyAdded;
|
||||
this.purpose = purpose;
|
||||
this.sourceCidrList = sourceCidr;
|
||||
this.icmpType = icmpType;
|
||||
this.icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
public FirewallRuleTO(FirewallRule rule, String srcIp) {
|
||||
this(rule.getId(), srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose());
|
||||
this(rule.getId(), srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(),rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
|
|
@ -100,14 +107,29 @@ public class FirewallRuleTO {
|
|||
return srcPortRange;
|
||||
}
|
||||
|
||||
public Integer getIcmpType(){
|
||||
return icmpType;
|
||||
}
|
||||
|
||||
public Integer getIcmpCode(){
|
||||
return icmpCode;
|
||||
}
|
||||
|
||||
public String getStringSrcPortRange() {
|
||||
return NetUtils.portRangeToString(srcPortRange);
|
||||
if (srcPortRange == null || srcPortRange.length < 2)
|
||||
return "0:0";
|
||||
else
|
||||
return NetUtils.portRangeToString(srcPortRange);
|
||||
}
|
||||
|
||||
public boolean revoked() {
|
||||
return revoked;
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
public boolean isAlreadyAdded() {
|
||||
return alreadyAdded;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class PortForwardingRuleTO extends FirewallRuleTO {
|
|||
}
|
||||
|
||||
protected PortForwardingRuleTO(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.PortForwarding);
|
||||
super(id, srcIp, protocol, srcPortStart, srcPortEnd, revoked, brandNew, FirewallRule.Purpose.PortForwarding, null,0,0);
|
||||
this.dstIp = dstIp;
|
||||
this.dstPortRange = new int[] { dstPortStart, dstPortEnd };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ public class StaticNatRuleTO extends FirewallRuleTO{
|
|||
}
|
||||
|
||||
public StaticNatRuleTO(StaticNatRule rule, String scrIp, String dstIp) {
|
||||
super(rule.getId(), scrIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(),rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose());
|
||||
super(rule.getId(), scrIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(),rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(), null,0,0);
|
||||
this.dstIp = dstIp;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
|||
@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;
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
|
|
@ -102,13 +105,14 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
|||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException{
|
||||
|
||||
boolean result = true;
|
||||
FirewallRule rule = null;
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: "+ getEntityId());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
result = result && _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), UserContext.current().getCaller());
|
||||
result = result && _firewallService.applyFirewallRules(ipAddressId, UserContext.current().getCaller());
|
||||
}
|
||||
|
||||
result = result && _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());
|
||||
|
|
@ -127,15 +131,19 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
|||
|
||||
@Override
|
||||
public void create() {
|
||||
StaticNatRule rule;
|
||||
|
||||
//cidr list parameter is deprecated
|
||||
if (cidrlist != null) {
|
||||
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
|
||||
}
|
||||
|
||||
try {
|
||||
rule = _rulesService.createStaticNatRule(this, getOpenFirewall());
|
||||
StaticNatRule rule = _rulesService.createStaticNatRule(this, getOpenFirewall());
|
||||
this.setEntityId(rule.getId());
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.info("Unable to create Static Nat Rule due to " + e.getMessage());
|
||||
s_logger.info("Unable to create Static Nat Rule due to ", e);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
this.setEntityId(rule.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -269,4 +277,8 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCmd /*implements LoadBa
|
|||
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID associated with the load balancer")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -125,6 +128,14 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCmd /*implements LoadBa
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
if (cidrlist != null) {
|
||||
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
|
|
@ -137,9 +148,17 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCmd /*implements LoadBa
|
|||
|
||||
@Override
|
||||
public void execute() throws ResourceAllocationException, ResourceUnavailableException {
|
||||
LoadBalancer result = null;
|
||||
|
||||
//cidr list parameter is deprecated
|
||||
if (cidrlist != null) {
|
||||
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
|
||||
}
|
||||
|
||||
try {
|
||||
result = _lbService.createLoadBalancerRule(this, getOpenFirewall());
|
||||
LoadBalancer result = _lbService.createLoadBalancerRule(this, getOpenFirewall());
|
||||
LoadBalancerResponse response = _responseGenerator.createLoadBalancerResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
|
|
@ -147,9 +166,6 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCmd /*implements LoadBa
|
|||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, e.getMessage());
|
||||
}
|
||||
LoadBalancerResponse response = _responseGenerator.createLoadBalancerResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,10 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
|||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return cidrlist;
|
||||
if (cidrlist != null) {
|
||||
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Boolean getOpenFirewall() {
|
||||
|
|
@ -117,24 +120,20 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
|||
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 = true;
|
||||
PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
|
||||
PortForwardingRule rule = null;
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
success = success && _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
success = success && _firewallService.applyFirewallRules(ipAddressId, callerContext.getCaller());
|
||||
}
|
||||
|
||||
success = success && _rulesService.applyPortForwardingRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCaller());
|
||||
|
||||
// State is different after the rule is applied, so get new object here
|
||||
rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
|
||||
|
|
@ -227,17 +226,17 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
|||
|
||||
@Override
|
||||
public void create() {
|
||||
if (cidrlist != null)
|
||||
for (String cidr: cidrlist){
|
||||
if (!NetUtils.isValidCIDR(cidr)){
|
||||
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Source cidrs formatting error " + cidr);
|
||||
}
|
||||
}
|
||||
|
||||
//cidr list parameter is deprecated
|
||||
if (cidrlist != null) {
|
||||
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
|
||||
}
|
||||
|
||||
try {
|
||||
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, getOpenFirewall());
|
||||
setEntityId(result.getId());
|
||||
} catch (NetworkRuleConflictException ex) {
|
||||
s_logger.info("Network rule conflict: " + ex.getMessage());
|
||||
s_logger.info("Network rule conflict: " , ex);
|
||||
s_logger.trace("Network Rule Conflict: ", ex);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ public class CapabilitiesResponse extends BaseResponse {
|
|||
@SerializedName("supportELB") @Param(description="true if region supports elastic load balancer on basic zones")
|
||||
private String supportELB;
|
||||
|
||||
@SerializedName("firewallRuleUiEnabled") @Param(description="true if the firewall rule UI is enabled")
|
||||
private boolean firewallRuleUiEnabled;
|
||||
|
||||
public boolean getSecurityGroupsEnabled() {
|
||||
return securityGroupsEnabled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -52,6 +52,8 @@ import com.cloud.agent.api.routing.IpAssocAnswer;
|
|||
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
|
||||
import com.cloud.agent.api.routing.NetworkElementCommand;
|
||||
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;
|
||||
|
|
@ -121,6 +123,8 @@ public class VirtualRoutingResource implements Manager {
|
|||
return execute ((VmDataCommand)cmd);
|
||||
} else if (cmd instanceof CheckRouterCommand) {
|
||||
return execute ((CheckRouterCommand)cmd);
|
||||
} else if (cmd instanceof SetFirewallRulesCommand) {
|
||||
return execute((SetFirewallRulesCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
|
@ -129,6 +133,40 @@ public class VirtualRoutingResource implements Manager {
|
|||
}
|
||||
}
|
||||
|
||||
private Answer execute(SetFirewallRulesCommand cmd) {
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
for (int i =0; i < cmd.getRules().length; i++) {
|
||||
results[i] = "Failed";
|
||||
}
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
|
||||
if (routerIp == null) {
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
|
||||
String[][] rules = cmd.generateFwRules();
|
||||
final Script command = new Script(_firewallPath, _timeout, s_logger);
|
||||
command.add(routerIp);
|
||||
command.add("-F");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String[] fwRules = rules[0];
|
||||
if (fwRules.length > 0) {
|
||||
for (int i = 0; i < fwRules.length; i++) {
|
||||
sb.append(fwRules[i]).append(',');
|
||||
}
|
||||
command.add("-a", sb.toString());
|
||||
}
|
||||
|
||||
String result = command.execute();
|
||||
if (result != null) {
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
return new SetFirewallRulesAnswer(cmd, true, null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Answer execute(SetPortForwardingRulesCommand cmd) {
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
|
|
@ -155,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);
|
||||
|
|
@ -169,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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ 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.NicTO;
|
||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||
|
|
@ -1270,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();
|
||||
|
|
@ -1277,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());
|
||||
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) {
|
||||
|
|
@ -6456,16 +6464,36 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
|
||||
protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
String callResult;
|
||||
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
|
||||
|
||||
if (routerIp == null) {
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
|
||||
return new SetFirewallRulesAnswer(cmd, results);
|
||||
String[][] rules = cmd.generateFwRules();
|
||||
String args = "";
|
||||
args += routerIp + " -F ";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String[] fwRules = rules[0];
|
||||
if (fwRules.length > 0) {
|
||||
for (int i = 0; i < fwRules.length; i++) {
|
||||
sb.append(fwRules[i]).append(',');
|
||||
}
|
||||
args += " -a " + sb.toString();
|
||||
}
|
||||
|
||||
callResult = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args);
|
||||
|
||||
if (callResult == null || callResult.isEmpty()) {
|
||||
//FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails
|
||||
for (int i=0; i < results.length; i++) {
|
||||
results[i] = "Failed";
|
||||
}
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
return new SetFirewallRulesAnswer(cmd, true, results);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,56 @@ one_to_one_fw_entry() {
|
|||
return $result
|
||||
}
|
||||
|
||||
fw_chain_for_ip() {
|
||||
local pubIp=$1
|
||||
if iptables -t mangle -N FIREWALL_$pubIp &> /dev/null
|
||||
then
|
||||
logger -t cloud "created a fw chain for $pubIp to DROP by default"
|
||||
(sudo iptables -t mangle -A FIREWALL_$pubIp -j DROP) &&
|
||||
(sudo iptables -t mangle -I FIREWALL_$pubIp -m state --state RELATED,ESTABLISHED -j ACCEPT ) &&
|
||||
(sudo iptables -t mangle -I PREROUTING -d $pubIp -j FIREWALL_$pubIp)
|
||||
return $?
|
||||
fi
|
||||
logger -t cloud "fw chain for $pubIp already exists"
|
||||
return 0
|
||||
}
|
||||
|
||||
static_nat() {
|
||||
local publicIp=$1
|
||||
local instIp=$2
|
||||
local op=$3
|
||||
local op2="-D"
|
||||
local rulenum=
|
||||
logger -t cloud "$(basename $0): static nat: public ip=$publicIp \
|
||||
instance ip=$instIp op=$op"
|
||||
|
||||
#TODO check error below
|
||||
fw_chain_for_ip $publicIp
|
||||
|
||||
#if adding, this might be a duplicate, so delete the old one first
|
||||
[ "$op" == "-A" ] && static_nat $publicIp $instIp "-D"
|
||||
# the delete operation may have errored out but the only possible reason is
|
||||
# that the rules didn't exist in the first place
|
||||
[ "$op" == "-A" ] && rulenum=1
|
||||
[ "$op" == "-A" ] && op2="-I"
|
||||
|
||||
local dev=$(ip_to_dev $publicIp)
|
||||
[ $? -ne 0 ] && echo "Could not find device associated with $publicIp" && return 1
|
||||
|
||||
# shortcircuit the process if error and it is an append operation
|
||||
# continue if it is delete
|
||||
(sudo iptables -t nat $op PREROUTING -i $dev -d $publicIp -j DNAT \
|
||||
--to-destination $instIp &>> $OUTFILE || [ "$op" == "-D" ]) &&
|
||||
(sudo iptables $op FORWARD -i $dev -o eth0 -d $instIp -m state \
|
||||
--state NEW -j ACCEPT &>> $OUTFILE || [ "$op" == "-D" ]) &&
|
||||
(sudo iptables -t nat $op2 POSTROUTING $rulenum -s $instIp -j SNAT \
|
||||
--to-source $publicIp &>> $OUTFILE || [ "$op" == "-D" ])
|
||||
|
||||
result=$?
|
||||
logger -t cloud "$(basename $0): done static nat entry public ip=$publicIp op=$op result=$result"
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
|
||||
rflag=
|
||||
|
|
@ -192,7 +242,12 @@ OUTFILE=$(mktemp)
|
|||
#Firewall ports for one-to-one/static NAT
|
||||
if [ "$Gflag" == "1" ]
|
||||
then
|
||||
one_to_one_fw_entry $publicIp $instanceIp $protocol $dport $op
|
||||
if [ "$protocol" == "" ]
|
||||
then
|
||||
static_nat $publicIp $instanceIp $op
|
||||
else
|
||||
one_to_one_fw_entry $publicIp $instanceIp $protocol $dport $op
|
||||
fi
|
||||
result=$?
|
||||
[ "$result" -ne 0 ] && cat $OUTFILE >&2
|
||||
rm -f $OUTFILE
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
# firewall_rule.sh -- allow some ports / protocols to vm instances
|
||||
#
|
||||
#
|
||||
# @VERSION@
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: -a <public ip address:protocol:startport:endport:sourcecidrs> \n" $(basename $0) >&2
|
||||
printf "sourcecidrs format: cidr1-cidr2-cidr3-...\n"
|
||||
}
|
||||
#set -x
|
||||
#FIXME: eating up the error code during execution of iptables
|
||||
fw_remove_backup() {
|
||||
local pubIp=$1
|
||||
sudo iptables -t mangle -F _FIREWALL_$pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -D PREROUTING -j _FIREWALL_$pubIp -d $pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -X _FIREWALL_$pubIp 2> /dev/null
|
||||
}
|
||||
|
||||
fw_restore() {
|
||||
local pubIp=$1
|
||||
sudo iptables -t mangle -F FIREWALL_$pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -D PREROUTING -j FIREWALL_$pubIp -d $pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -X FIREWALL_$pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -E _FIREWALL_$pubIp FIREWALL_$pubIp 2> /dev/null
|
||||
}
|
||||
fw_chain_for_ip () {
|
||||
local pubIp=$1
|
||||
fw_remove_backup $1
|
||||
sudo iptables -t mangle -E FIREWALL_$pubIp _FIREWALL_$pubIp 2> /dev/null
|
||||
sudo iptables -t mangle -N FIREWALL_$pubIp 2> /dev/null
|
||||
# drop if no rules match (this will be the last rule in the chain)
|
||||
sudo iptables -t mangle -A FIREWALL_$pubIp -j DROP> /dev/null
|
||||
# ensure outgoing connections are maintained (first rule in chain)
|
||||
sudo iptables -t mangle -I FIREWALL_$pubIp -m state --state RELATED,ESTABLISHED -j ACCEPT> /dev/null
|
||||
sudo iptables -t mangle -I PREROUTING -d $pubIp -j FIREWALL_$pubIp
|
||||
}
|
||||
|
||||
fw_entry_for_public_ip() {
|
||||
local rules=$1
|
||||
|
||||
local pubIp=$(echo $rules | cut -d: -f1)
|
||||
local prot=$(echo $rules | cut -d: -f2)
|
||||
local sport=$(echo $rules | cut -d: -f3)
|
||||
local eport=$(echo $rules | cut -d: -f4)
|
||||
local scidrs=$(echo $rules | cut -d: -f5 | sed 's/-/ /g')
|
||||
|
||||
logger -t cloud "$(basename $0): enter apply firewall rules for public ip $pubIp:$prot:$sport:$eport:$scidrs"
|
||||
|
||||
|
||||
# note that rules are inserted after the RELATED,ESTABLISHED rule
|
||||
# but before the DROP rule
|
||||
for src in $scidrs
|
||||
do
|
||||
[ "$prot" == "reverted" ] && continue;
|
||||
if [ "$prot" == "icmp" ]
|
||||
then
|
||||
typecode="$sport/$eport"
|
||||
[ "$eport" == "-1" ] && typecode="$sport"
|
||||
[ "$sport" == "-1" ] && typecode="any"
|
||||
sudo iptables -t mangle -I FIREWALL_$pubIp 2 -s $src -p $prot \
|
||||
--icmp-type $typecode -j RETURN
|
||||
else
|
||||
sudo iptables -t mangle -I FIREWALL_$pubIp 2 -s $src -p $prot \
|
||||
--dport $sport:$eport -j RETURN
|
||||
fi
|
||||
result=$?
|
||||
[ $result -gt 0 ] &&
|
||||
logger -t cloud "Error adding iptables entry for $pubIp:$prot:$sport:$eport:$src" &&
|
||||
break
|
||||
done
|
||||
|
||||
logger -t cloud "$(basename $0): exit apply firewall rules for public ip $pubIp"
|
||||
return $result
|
||||
}
|
||||
|
||||
get_vif_list() {
|
||||
local vif_list=""
|
||||
for i in /sys/class/net/eth*; do
|
||||
vif=$(basename $i);
|
||||
if [ "$vif" != "eth0" ] && [ "$vif" != "eth1" ]
|
||||
then
|
||||
vif_list="$vif_list $vif";
|
||||
fi
|
||||
done
|
||||
if [ "$vif_list" == "" ]
|
||||
then
|
||||
vif_list="eth0"
|
||||
fi
|
||||
|
||||
logger -t cloud "FirewallRule public interfaces = $vif_list"
|
||||
echo $vif_list
|
||||
}
|
||||
|
||||
shift
|
||||
rules=
|
||||
while getopts 'a:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
a) aflag=1
|
||||
rules="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
VIF_LIST=$(get_vif_list)
|
||||
|
||||
if [ "$rules" == "" ]
|
||||
then
|
||||
rules="none"
|
||||
fi
|
||||
|
||||
#-a 172.16.92.44:tcp:80:80:0.0.0.0/0:,172.16.92.44:tcp:220:220:0.0.0.0/0:,172.16.92.44:tcp:222:222:192.168.10.0/24-75.57.23.0/22-88.100.33.1/32
|
||||
# if any entry is reverted , entry will be in the format <ip>:reverted:0:0:0
|
||||
# example : 172.16.92.44:tcp:80:80:0.0.0.0/0:,172.16.92.44:tcp:220:220:0.0.0.0/0:,200.1.1.2:reverted:0:0:0
|
||||
# The reverted entries will fix the following partially
|
||||
#FIXME: rule leak: when there are multiple ip address, there will chance that entry will be left over if the ipadress does not appear in the current execution when compare to old one
|
||||
# example : In the below first transaction have 2 ip's whereas in second transaction it having one ip, so after the second trasaction 200.1.2.3 ip will have rules in mangle table.
|
||||
# 1) -a 172.16.92.44:tcp:80:80:0.0.0.0/0:,200.16.92.44:tcp:220:220:0.0.0.0/0:,
|
||||
# 2) -a 172.16.92.44:tcp:80:80:0.0.0.0/0:,172.16.92.44:tcp:220:220:0.0.0.0/0:,
|
||||
|
||||
|
||||
success=0
|
||||
publicIps=
|
||||
rules_list=$(echo $rules | cut -d, -f1- --output-delimiter=" ")
|
||||
for r in $rules_list
|
||||
do
|
||||
pubIp=$(echo $r | cut -d: -f1)
|
||||
publicIps="$pubIp $publicIps"
|
||||
done
|
||||
|
||||
unique_ips=$(echo $publicIps| tr " " "\n" | sort | uniq | tr "\n" " ")
|
||||
|
||||
for u in $unique_ips
|
||||
do
|
||||
fw_chain_for_ip $u
|
||||
done
|
||||
|
||||
for r in $rules_list
|
||||
do
|
||||
pubIp=$(echo $r | cut -d: -f1)
|
||||
fw_entry_for_public_ip $r
|
||||
success=$?
|
||||
if [ $success -gt 0 ]
|
||||
then
|
||||
logger -t cloud "$(basename $0): failure to apply fw rules for ip $pubIp"
|
||||
break
|
||||
else
|
||||
logger -t cloud "$(basename $0): successful in applying fw rules for ip $pubIp"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $success -gt 0 ]
|
||||
then
|
||||
for p in $unique_ips
|
||||
do
|
||||
logger -t cloud "$(basename $0): restoring from backup for ip: $p"
|
||||
fw_restore $p
|
||||
done
|
||||
fi
|
||||
for p in $unique_ips
|
||||
do
|
||||
logger -t cloud "$(basename $0): deleting backup for ip: $p"
|
||||
fw_remove_backup $p
|
||||
done
|
||||
exit $success
|
||||
|
||||
|
|
@ -24,12 +24,12 @@
|
|||
# firewall.sh -- allow some ports / protocols to vm instances
|
||||
#
|
||||
#
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s: (-A|-D) -i <domR eth1 ip> -r <target-instance-ip> -P protocol (-p port_range | -t icmp_type_code) -l <public ip address> -d <target port> [-f <firewall ip> -u <firewall user> -y <firewall password> -z <firewall enable password> ] \n" $(basename $0) >&2
|
||||
printf "Usage for Firewall rule : %s: <domR eth1 ip> -F " $(basename $0) >&2
|
||||
printf "Usage for other purposes : %s: <domR eth1 ip> (-A|-D) -i <domR eth1 ip> -r <target-instance-ip> -P protocol (-p port_range | -t icmp_type_code) -l <public ip address> -d <target port> [-f <firewall ip> -u <firewall user> -y <firewall password> -z <firewall enable password> ] \n" $(basename $0) >&2
|
||||
}
|
||||
|
||||
# set -x
|
||||
#set -x
|
||||
|
||||
# check if gateway domain is up and running
|
||||
check_gw() {
|
||||
|
|
@ -52,9 +52,22 @@ if [ $? -gt 0 ]
|
|||
then
|
||||
exit 1
|
||||
fi
|
||||
fflag=
|
||||
while getopts ':F' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
F) fflag=1
|
||||
;;
|
||||
\?) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall.sh $*"
|
||||
if [ -n "$fflag" ]
|
||||
then
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall_rule.sh $*"
|
||||
else
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall.sh $*"
|
||||
fi
|
||||
exit $?
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,8 @@ public interface NetworkManager extends NetworkService {
|
|||
String getGlobalGuestDomainSuffix();
|
||||
|
||||
String getStartIpAddress(long networkId);
|
||||
|
||||
boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException;
|
||||
|
||||
String getIpInNetwork(long vmId, long networkId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -2431,6 +2432,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
success = false;
|
||||
}
|
||||
|
||||
// apply static nat
|
||||
if (!_rulesMgr.applyStaticNatsForNetwork(networkId, false, caller)) {
|
||||
s_logger.warn("Failed to apply static nats 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)) {
|
||||
|
|
@ -2631,6 +2638,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
return _nicDao.findByInstanceIdAndNetworkId(networkId, vmId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIpInNetwork(long vmId, long networkId) {
|
||||
Nic guestNic = getNicInNetwork(vmId, 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?";
|
||||
return guestNic.getIp4Address();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
|
||||
return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
|
||||
|
|
@ -3190,4 +3204,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;
|
||||
|
|
@ -120,7 +121,17 @@ public class DhcpElement extends AdapterBase implements NetworkElement, Password
|
|||
VirtualMachineProfile<UserVm> uservm = (VirtualMachineProfile<UserVm>)vm;
|
||||
Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
params.put(VirtualMachineProfile.Param.RestartNetwork, true);
|
||||
List<DomainRouterVO> routers = _routerMgr.deployDhcp(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters());
|
||||
List<DomainRouterVO> routers = _routerMgr.deployDhcp(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters());
|
||||
|
||||
//for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when network.dns.basiczone.updates is set to "all"
|
||||
Long podId = dest.getPod().getId();
|
||||
DataCenter dc = dest.getDataCenter();
|
||||
boolean isPodBased = (dc.getNetworkType() == NetworkType.Basic || network.isSecurityGroupEnabled()) && network.getTrafficType() == TrafficType.Guest;
|
||||
if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) {
|
||||
List<DomainRouterVO> allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running);
|
||||
routers.addAll(allRunningRoutersOutsideThePod);
|
||||
}
|
||||
|
||||
List<VirtualRouter> rets = _routerMgr.addVirtualMachineIntoNetwork(network, nic, uservm, dest, context, routers);
|
||||
return (rets != null) && (!rets.isEmpty());
|
||||
} else {
|
||||
|
|
@ -235,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import javax.naming.ConfigurationException;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.commands.ListFirewallRulesCmd;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
|
|
@ -72,6 +74,10 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
NetworkManager _networkMgr;
|
||||
@Inject
|
||||
UsageEventDao _usageEventDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
|
||||
private boolean _elbEnabled=false;
|
||||
|
||||
|
||||
@Override
|
||||
|
|
@ -92,6 +98,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_name = name;
|
||||
String elbEnabledString = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
|
||||
_elbEnabled = Boolean.parseBoolean(elbEnabledString);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -111,16 +119,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
// 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);
|
||||
validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall);
|
||||
|
||||
//icmp code and icmp type can't be passed in for any other protocol rather than icmp
|
||||
if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
|
||||
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
|
||||
}
|
||||
|
||||
if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
|
||||
throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
|
||||
}
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAccountId();
|
||||
Long domainId = ipAddress.getDomainId();
|
||||
|
|
@ -215,25 +226,26 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
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.
|
||||
}
|
||||
|
||||
|
||||
boolean allowFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && newRule.getPurpose() != rule.getPurpose());
|
||||
|
||||
if (!allowFirewall) {
|
||||
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())
|
||||
|
|
@ -251,15 +263,12 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
}
|
||||
|
||||
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())) {
|
||||
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");
|
||||
}
|
||||
|
|
@ -267,7 +276,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
|
||||
|
||||
@Override
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto) {
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose) {
|
||||
// Validate ip address
|
||||
_accountMgr.checkAccess(caller, ipAddress);
|
||||
|
||||
|
|
@ -293,10 +302,23 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
}
|
||||
|
||||
// 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();
|
||||
Map<Network.Capability, String> protocolCapabilities = null;
|
||||
|
||||
if (purpose == Purpose.LoadBalancing) {
|
||||
if (!_elbEnabled) {
|
||||
protocolCapabilities = _networkMgr.getServiceCapabilities(network.getDataCenterId(), network.getNetworkOfferingId(), Service.Lb);
|
||||
}
|
||||
} else {
|
||||
protocolCapabilities = _networkMgr.getServiceCapabilities(network.getDataCenterId(), network.getNetworkOfferingId(), Service.Firewall);
|
||||
}
|
||||
|
||||
if (protocolCapabilities != null) {
|
||||
String supportedProtocols = protocolCapabilities.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(proto.toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
|
||||
} else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,4 +518,5 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
|
|||
|
||||
return rules.size() == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,6 +293,13 @@ public class ElasticLoadBalancerManagerImpl implements
|
|||
elbVm.getPrivateIpAddress());
|
||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME,
|
||||
elbVm.getInstanceName());
|
||||
//FIXME: why are we setting attributes directly? Ick!! There should be accessors and
|
||||
//the constructor should set defaults.
|
||||
cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key());
|
||||
cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key());
|
||||
cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key());
|
||||
cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key());
|
||||
cmd.lbStatsIp = elbVm.getGuestIpAddress();
|
||||
cmds.addCommand(cmd);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
|||
throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id" + ipId);
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol());
|
||||
_firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), Purpose.LoadBalancing);
|
||||
|
||||
|
||||
networkId = ipAddr.getAssociatedWithNetworkId();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -72,7 +73,6 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
|
|||
|
||||
List<DomainRouterVO> deployDhcp(Network guestNetwork, DeployDestination dest, Account owner, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
|
||||
|
||||
|
||||
List<VirtualRouter> addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile<UserVm> vm, DeployDestination dest, ReservationContext context, List<DomainRouterVO> routers) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
|
||||
|
||||
boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
|
||||
|
|
@ -88,4 +88,9 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
|
|||
String[] applyVpnUsers(Network network, List<? extends VpnUser> users) throws ResourceUnavailableException;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ import com.cloud.dc.DataCenterVO;
|
|||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.dao.AccountVlanMapDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DcDetailsDaoImpl;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
|
|
@ -136,6 +135,8 @@ 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.StaticNatImpl;
|
||||
import com.cloud.network.rules.StaticNatRule;
|
||||
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
|
|
@ -1076,11 +1077,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
}
|
||||
|
||||
if (!routers.isEmpty()) {
|
||||
//for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when network.dns.basiczone.updates is set to "all"
|
||||
if (isPodBased) {
|
||||
List<DomainRouterVO> allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(guestNetwork.getId(), podId, State.Running);
|
||||
routers.addAll(allRunningRoutersOutsideThePod);
|
||||
}
|
||||
return routers;
|
||||
}
|
||||
|
||||
|
|
@ -1136,6 +1132,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
_networkDao.releaseFromLockTable(network.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return routers;
|
||||
}
|
||||
|
||||
|
|
@ -1397,7 +1394,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
|
||||
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
|
||||
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
|
||||
//Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
|
||||
for (PublicIpAddress ip : publicIps) {
|
||||
pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
|
||||
staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
|
||||
|
|
@ -1406,6 +1405,18 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
if (vpn != null) {
|
||||
vpns.add(vpn);
|
||||
}
|
||||
|
||||
if (ip.isOneToOneNat()) {
|
||||
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
|
||||
StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false);
|
||||
staticNats.add(staticNat);
|
||||
}
|
||||
}
|
||||
|
||||
//Re-apply static nats
|
||||
s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
|
||||
if (!staticNats.isEmpty()) {
|
||||
createApplyStaticNatCommands(staticNats, router, cmds);
|
||||
}
|
||||
|
||||
// Re-apply port forwarding rules
|
||||
|
|
@ -1596,20 +1607,26 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
|
||||
List<VirtualRouter> rets = new ArrayList<VirtualRouter>(routers.size());
|
||||
|
||||
boolean sendPasswordAndVmData = true;
|
||||
boolean sendDnsDhcpData = true;
|
||||
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
|
||||
|
||||
DataCenter dc = dest.getDataCenter();
|
||||
String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(profile.getServiceOfferingId()).getDisplayText();
|
||||
String zoneName = _dcDao.findById(network.getDataCenterId()).getName();
|
||||
boolean isZoneBasic = (dc.getNetworkType() == NetworkType.Basic);
|
||||
|
||||
for (DomainRouterVO router : routers) {
|
||||
if (router.getState() != State.Running) {
|
||||
s_logger.warn("Unable to add virtual machine " + profile.getVirtualMachine() + " to the router " + router + " as the router is not in Running state");
|
||||
continue;
|
||||
}
|
||||
boolean sendPasswordAndVmData = true;
|
||||
boolean sendDnsDhcpData = true;
|
||||
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
|
||||
|
||||
//for basic zone:
|
||||
//1) send vm data/password information only to the dhcp in the same pod
|
||||
//2) send dhcp/dns information to all routers in the cloudstack only when _dnsBasicZoneUpdates is set to "all" value
|
||||
DataCenter dc = dest.getDataCenter();
|
||||
if (dc.getNetworkType() == NetworkType.Basic) {
|
||||
|
||||
if (isZoneBasic) {
|
||||
Long podId = dest.getPod().getId();
|
||||
if (router.getPodIdToDeployIn().longValue() != podId.longValue()) {
|
||||
sendPasswordAndVmData = false;
|
||||
|
|
@ -1658,8 +1675,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
cmds.addCommand("password", cmd);
|
||||
}
|
||||
|
||||
String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(profile.getServiceOfferingId()).getDisplayText();
|
||||
String zoneName = _dcDao.findById(network.getDataCenterId()).getName();
|
||||
|
||||
|
||||
cmds.addCommand(
|
||||
"vmdata",
|
||||
|
|
@ -2074,6 +2090,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
s_logger.warn("Unable to associate ip addresses, virtual router is not in the right state " + router.getState());
|
||||
throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
//If rules fail to apply on one domR, no need to proceed with the rest
|
||||
if (!result) {
|
||||
throw new ResourceUnavailableException("Unable to apply firewall rules on router ", VirtualRouter.class, router.getId());
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2082,8 +2104,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;
|
||||
|
|
@ -2111,6 +2133,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
//If rules fail to apply on one domR, no need to proceed with the rest
|
||||
if (!result) {
|
||||
throw new ResourceUnavailableException("Unable to apply firewall rules 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 {
|
||||
|
|
@ -2118,6 +2146,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
throw new ResourceUnavailableException("Unable to apply firewall rules, virtual router is not in the right state", VirtualRouter.class, router.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2179,4 +2208,68 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
|||
// Send commands to router
|
||||
return sendCommandsToRouter(router, cmds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDnsBasicZoneUpdate() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.firewall.FirewallService;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
public interface FirewallManager extends FirewallService{
|
||||
|
|
@ -29,7 +30,7 @@ public interface FirewallManager extends FirewallService{
|
|||
*/
|
||||
void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException;
|
||||
|
||||
void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto);
|
||||
void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose);
|
||||
|
||||
boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ public interface RulesManager extends RulesService {
|
|||
boolean releasePorts(long ipId, String protocol, FirewallRule.Purpose purpose, int... ports);
|
||||
|
||||
List<PortForwardingRuleVO> listByNetworkId(long networkId);
|
||||
|
||||
|
||||
|
||||
boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke);
|
||||
|
||||
boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol());
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding);
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAccountId();
|
||||
|
|
@ -225,7 +225,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
if (e instanceof NetworkRuleConflictException) {
|
||||
throw (NetworkRuleConflictException) e;
|
||||
}
|
||||
throw new CloudRuntimeException("Unable to add rule for the ip id=" + newRule.getSourceIpAddressId(), e);
|
||||
throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,16 +245,13 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol());
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat);
|
||||
|
||||
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();
|
||||
String dstIp = _networkMgr.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
|
@ -291,7 +288,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 +348,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 (applyStaticNatForIp(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -692,6 +704,38 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller) {
|
||||
List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(networkId);
|
||||
if (ips.isEmpty()) {
|
||||
s_logger.debug("There are no static nat to apply for network id=" + networkId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (caller != null) {
|
||||
_accountMgr.checkAccess(caller, ips.toArray(new IPAddressVO[ips.size()]));
|
||||
}
|
||||
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
for (IPAddressVO ip : ips) {
|
||||
// Get nic IP4 address
|
||||
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
|
||||
StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false);
|
||||
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;
|
||||
}
|
||||
|
||||
@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();
|
||||
|
|
@ -797,11 +841,15 @@ 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 = applyStaticNatForIp(ipId, false, caller, true);
|
||||
|
||||
// revoke all port forwarding rules
|
||||
applyPortForwardingRules(ipId, true, caller);
|
||||
|
||||
|
|
@ -816,7 +864,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 +1003,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();
|
||||
|
|
@ -1002,9 +1050,53 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
throw new InvalidParameterValueException("Source ip address of the rule id=" + rule.getId() + " is not static nat enabled");
|
||||
}
|
||||
|
||||
Nic guestNic = _networkMgr.getNicInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId());
|
||||
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId());
|
||||
|
||||
return new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address());
|
||||
return new StaticNatRuleImpl(ruleVO, dstIp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
|
||||
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
IpAddress sourceIp = _ipAddressDao.findById(sourceIpId);
|
||||
|
||||
if (!sourceIp.isOneToOneNat()) {
|
||||
s_logger.debug("Source ip id=" + sourceIpId + " is not one to one nat");
|
||||
return true;
|
||||
}
|
||||
|
||||
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 (caller != null) {
|
||||
_accountMgr.checkAccess(caller, sourceIp);
|
||||
}
|
||||
|
||||
//create new static nat rule
|
||||
// Get nic IP4 address
|
||||
String dstIp = _networkMgr.getIpInNetwork(sourceIp.getAssociatedWithVmId(), networkId);
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -1557,6 +1557,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
|
||||
if(trackExternalChange) {
|
||||
if(serverState == State.Starting) {
|
||||
if(vm.getHostId() != null && vm.getHostId() != hostId) {
|
||||
s_logger.info("CloudStack is starting VM on host " + vm.getHostId() + ", but status report comes from a different host " + hostId + ", skip status sync for vm: " + vm.getInstanceName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if(vm.getHostId() == null || hostId != vm.getHostId()) {
|
||||
try {
|
||||
stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue