diff --git a/api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java b/api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java index 4e7b5f5aacb..9d10bd6d94d 100644 --- a/api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java +++ b/api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java @@ -17,8 +17,11 @@ */ package com.cloud.agent.api.to; +import java.util.List; + import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; +import com.cloud.utils.StringUtils; import com.cloud.utils.net.NetUtils; /** @@ -30,6 +33,7 @@ import com.cloud.utils.net.NetUtils; public class PortForwardingRuleTO extends FirewallRuleTO { String dstIp; int[] dstPortRange; + List sourceCidrs; protected PortForwardingRuleTO() { super(); @@ -39,6 +43,7 @@ public class PortForwardingRuleTO extends FirewallRuleTO { super(rule, srcIp); this.dstIp = rule.getDestinationIpAddress().addr(); this.dstPortRange = new int[] { rule.getDestinationPortStart(), rule.getDestinationPortEnd() }; + this.sourceCidrs = rule.getSourceCidrList(); } protected PortForwardingRuleTO(long id, String srcIp, int srcPortStart, int srcPortEnd, String dstIp, int dstPortStart, int dstPortEnd, String protocol, boolean revoked, boolean brandNew) { @@ -58,4 +63,13 @@ public class PortForwardingRuleTO extends FirewallRuleTO { public String getStringDstPortRange() { return NetUtils.portRangeToString(dstPortRange); } + + public List getSourceCidrs(){ + return sourceCidrs; + } + + public String geStringSourceCidrs(){ + return sourceCidrs==null ? null : StringUtils.join(sourceCidrs, ","); + } + } diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 744d6e5f631..d95c1e33e47 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -40,6 +40,7 @@ import com.cloud.network.rules.PortForwardingRule; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.net.Ip; +import com.cloud.utils.net.NetUtils; @Implementation(description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class) public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements PortForwardingRule { @@ -108,20 +109,27 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P public String getCommandName() { return s_name; } + + @Override + public void setSourceCidrList(List cidrs){ + cidrlist = cidrs; + } @Override public void execute() throws ResourceUnavailableException { UserContext callerContext = UserContext.current(); - boolean success = false; PortForwardingRule rule = _entityMgr.findById(PortForwardingRule.class, getEntityId()); + // load cidrs if any + rule.setSourceCidrList(_rulesService.getSourceCidrs(rule.getId())); + try { UserContext.current().setEventDetails("Rule Id: " + getEntityId()); success = _rulesService.applyPortForwardingRules(rule.getSourceIpAddressId(), callerContext.getCaller()); // State is different after the rule is applied, so get new object here rule = _entityMgr.findById(PortForwardingRule.class, getEntityId()); - FirewallRuleResponse fwResponse = new FirewallRuleResponse(); + FirewallRuleResponse fwResponse = new FirewallRuleResponse(); if (rule != null) { fwResponse = _responseGenerator.createFirewallRuleResponse(rule); setResponseObject(fwResponse); @@ -210,6 +218,12 @@ 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); + } + } try { PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId); setEntityId(result.getId()); diff --git a/api/src/com/cloud/network/rules/PortForwardingRule.java b/api/src/com/cloud/network/rules/PortForwardingRule.java index 0da49c657ad..74176c9bceb 100644 --- a/api/src/com/cloud/network/rules/PortForwardingRule.java +++ b/api/src/com/cloud/network/rules/PortForwardingRule.java @@ -49,6 +49,8 @@ public interface PortForwardingRule extends FirewallRule { * @return source cidr to forward */ List getSourceCidrList(); - - + /** + * @return source cidr to forward + */ + void setSourceCidrList(List cidrs); } diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java index 6898053b5fd..fa0761c711c 100644 --- a/api/src/com/cloud/network/rules/RulesService.java +++ b/api/src/com/cloud/network/rules/RulesService.java @@ -68,4 +68,6 @@ public interface RulesService { StaticNatRule buildStaticNatRule(FirewallRule rule); + List getSourceCidrs(long ruleId); + } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 9c7fcc08b4a..fac67997478 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1207,18 +1207,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String args = routerIp; String[] results = new String[cmd.getRules().length]; int i = 0; for (PortForwardingRuleTO rule : cmd.getRules()) { - args += rule.revoked() ? " -D " : " -A "; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange(); + StringBuilder args = new StringBuilder(); + args.append(routerIp); + args.append(rule.revoked() ? " -D " : " -A "); + args.append(" -P ").append(rule.getProtocol().toLowerCase()); + args.append(" -l ").append(rule.getSrcIp()); + args.append(" -p ").append(rule.getStringSrcPortRange()); + args.append(" -r ").append(rule.getDstIp()); + args.append(" -d ").append(rule.getStringDstPortRange()); + if (rule.geStringSourceCidrs() != null){ + args.append(" -s " + rule.geStringSourceCidrs()); + } + String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString()); - String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args); results[i++] = (result == null || result.isEmpty()) ? "Failed" : null; } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 0db84288c62..de5f995d134 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -73,6 +73,7 @@ import com.cloud.keystore.KeystoreManagerImpl; import com.cloud.maint.UpgradeManagerImpl; import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.NetworkManagerImpl; +import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.LoadBalancerDaoImpl; @@ -256,6 +257,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("ItWorkDao", ItWorkDaoImpl.class); addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class); + addDao("FirewallRulesCidrsDao", FirewallRulesCidrsDaoImpl.class); addDao("SSHKeyPairDao", SSHKeyPairDaoImpl.class); addDao("UsageEventDao", UsageEventDaoImpl.class); addDao("ClusterDetailsDao", ClusterDetailsDaoImpl.class); diff --git a/server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java index e6f51880375..6f40fdb34fa 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; -@Local(value=FirewallRulesCidrsDaoImpl.class) +@Local(value=FirewallRulesCidrsDao.class) public class FirewallRulesCidrsDaoImpl extends GenericDaoBase implements FirewallRulesCidrsDao { private static final Logger s_logger = Logger.getLogger(FirewallRulesCidrsDaoImpl.class); protected final SearchBuilder CidrsSearch; @@ -49,12 +49,12 @@ public class FirewallRulesCidrsDaoImpl extends GenericDaoBase results = search(sc, null); - List hostTags = new ArrayList(results.size()); + List cidrs = new ArrayList(results.size()); for (FirewallRulesCidrsVO result : results) { - hostTags.add(result.getCidr()); + cidrs.add(result.getCidr()); } - return hostTags; + return cidrs; } @Override @DB @@ -63,7 +63,6 @@ public class FirewallRulesCidrsDaoImpl extends GenericDaoBase getSourceCidrs(long ruleId){ + return _firewallCidrsDao.getSourceCidrs(ruleId); + } @Override public boolean applyPortForwardingRules(long ipId, boolean continueOnError, Account caller) { List rules = _forwardingDao.listForApplication(ipId); + if (rules.size() == 0) { s_logger.debug("There are no firwall rules to apply for ip id=" + ipId); return true; } + + for (PortForwardingRuleVO rule: rules){ + // load cidrs if any + rule.setSourceCidrList(_firewallCidrsDao.getSourceCidrs(rule.getId())); + } + if (caller != null) { _accountMgr.checkAccess(caller, rules.toArray(new PortForwardingRuleVO[rules.size()])); diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java index 99621bcd59e..f29ec55bc71 100644 --- a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java +++ b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java @@ -37,9 +37,13 @@ public interface PortForwardingRulesDao extends GenericDao listByIp(long ipId); - List listByVm(Long vmId); - - List listByNetwork(long networkId); - - List listByAccount(long accountId); + List listByVm(Long vmId); + + List listByNetwork(long networkId); + + List listByAccount(long accountId); + + void loadSourceCidrs(PortForwardingRuleVO portForwardingRule); + + void saveSourceCidrs(PortForwardingRuleVO portForwardingRule); }