bug 8115: source ip filtering

Created a table for source cidrs list.
Created necessary Daos and VOs.
Updated PortForwardingRulesDao to persist/update non null list of cidrs.
For deletion depending on ON DELETE CASCADE.
This commit is contained in:
Abhinandan Prateek 2011-05-09 17:41:50 +05:30
parent 0bf96b92e5
commit 2984b0607f
9 changed files with 283 additions and 11 deletions

View File

@ -18,6 +18,8 @@
package com.cloud.api.commands;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
@ -27,6 +29,7 @@ import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.FirewallRuleResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
@ -62,6 +65,10 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, description = "the ID of the virtual machine for the port forwarding rule")
private Long virtualMachineId;
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
private List<String> cidrlist;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
@ -89,6 +96,10 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
return virtualMachineId;
}
public List<String> getSourceCidrList() {
return cidrlist;
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////

View File

@ -17,6 +17,8 @@
*/
package com.cloud.network.rules;
import java.util.List;
import com.cloud.utils.net.Ip;
/**
@ -41,6 +43,12 @@ public interface PortForwardingRule extends FirewallRule {
/**
* @return destination ip address.
*/
long getVirtualMachineId();
long getVirtualMachineId();
/**
* @return source cidr to forward
*/
List<String> getSourceCidrList();
}

View File

@ -0,0 +1,61 @@
/**
* 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;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name=("firewall_rules_cidrs"))
public class FirewallRulesCidrsVO {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@Column(name="firewall_rule_id")
private long firewallRuleId;
@Column(name="source_cidr")
private String sourceCidrList;
public FirewallRulesCidrsVO() { }
public FirewallRulesCidrsVO(long firewallRuleId, String sourceCidrList) {
this.firewallRuleId = firewallRuleId;
this.sourceCidrList = sourceCidrList;
}
public Long getId() {
return id;
}
public long getFirewallRuleId() {
return firewallRuleId;
}
public String getCidr() {
return sourceCidrList;
}
}

View File

@ -0,0 +1,32 @@
/**
* 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.dao;
import java.util.List;
import com.cloud.network.FirewallRulesCidrsVO;
import com.cloud.utils.db.GenericDao;
public interface FirewallRulesCidrsDao extends GenericDao<FirewallRulesCidrsVO, Long> {
void persist(long firewallRuleId, List<String> sourceCidrs);
List<String> getSourceCidrs(long firewallRuleId);
}

View File

@ -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.dao;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.network.FirewallRulesCidrsVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
@Local(value=FirewallRulesCidrsDaoImpl.class)
public class FirewallRulesCidrsDaoImpl extends GenericDaoBase<FirewallRulesCidrsVO, Long> implements FirewallRulesCidrsDao {
private static final Logger s_logger = Logger.getLogger(FirewallRulesCidrsDaoImpl.class);
protected final SearchBuilder<FirewallRulesCidrsVO> CidrsSearch;
protected FirewallRulesCidrsDaoImpl() {
CidrsSearch = createSearchBuilder();
CidrsSearch.and("firewallRuleId", CidrsSearch.entity().getFirewallRuleId(), SearchCriteria.Op.EQ);
CidrsSearch.done();
}
@Override
public List<String> getSourceCidrs(long firewallRuleId) {
SearchCriteria sc = CidrsSearch.create();
sc.setParameters("firewallRuleId", firewallRuleId);
List<FirewallRulesCidrsVO> results = search(sc, null);
List<String> hostTags = new ArrayList<String>(results.size());
for (FirewallRulesCidrsVO result : results) {
hostTags.add(result.getCidr());
}
return hostTags;
}
@Override
public void persist(long firewallRuleId, List<String> sourceCidrs) {
Transaction txn = Transaction.currentTxn();
txn.start();
for (String tag : sourceCidrs) {
s_logger.info("Saving cidrs " + tag);
FirewallRulesCidrsVO vo = new FirewallRulesCidrsVO(firewallRuleId, tag);
persist(vo);
}
txn.commit();
}
}

View File

@ -18,6 +18,8 @@
package com.cloud.network.rules;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@ -25,6 +27,7 @@ import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.cloud.utils.net.Ip;
@ -45,23 +48,39 @@ public class PortForwardingRuleVO extends FirewallRuleVO implements PortForwardi
private int destinationPortEnd;
@Column(name="instance_id")
private long virtualMachineId;
private long virtualMachineId;
// This is a delayed load value. If the value is null,
// then this field has not been loaded yet.
// Call firewallrules dao to load it.
@Transient
List<String> sourceCidrs;
public void setSourceCidrList(List<String> sourceCidrs) {
this.sourceCidrs=sourceCidrs;
}
@Override
public List<String> getSourceCidrList() {
return sourceCidrs;
}
public PortForwardingRuleVO() {
}
public PortForwardingRuleVO(String xId, long srcIpId, int srcPortStart, int srcPortEnd, Ip dstIp, int dstPortStart, int dstPortEnd, String protocol, long networkId, long accountId, long domainId, long instanceId) {
public PortForwardingRuleVO(String xId, long srcIpId, int srcPortStart, int srcPortEnd, Ip dstIp, int dstPortStart, int dstPortEnd, String protocol, List<String> sourceCidrs, long networkId, long accountId, long domainId, long instanceId) {
super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding);
this.destinationIpAddress = dstIp;
this.virtualMachineId = instanceId;
this.destinationPortStart = dstPortStart;
this.destinationPortEnd = dstPortEnd;
this.destinationPortEnd = dstPortEnd;
this.sourceCidrs = sourceCidrs;
}
public PortForwardingRuleVO(String xId, long srcIpId, int srcPort, Ip dstIp, int dstPort, String protocol, long networkId, long accountId, long domainId, long instanceId) {
this(xId, srcIpId, srcPort, srcPort, dstIp, dstPort, dstPort, protocol.toLowerCase(), networkId, accountId, domainId, instanceId);
public PortForwardingRuleVO(String xId, long srcIpId, int srcPort, Ip dstIp, int dstPort, String protocol, List<String> sourceCidrs, long networkId, long accountId, long domainId, long instanceId) {
this(xId, srcIpId, srcPort, srcPort, dstIp, dstPort, dstPort, protocol.toLowerCase(), sourceCidrs, networkId, accountId, domainId, instanceId);
}
@Override

View File

@ -255,7 +255,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(),
rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), rule.getSourceCidrList(), networkId, accountId, domainId, vmId);
newRule = _forwardingDao.persist(newRule);
try {
@ -332,8 +332,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
throw new InvalidParameterValueException("Start port can't be bigger than end port");
}
FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), networkId,
accountId, domainId, rule.getPurpose());
FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(),
networkId, accountId, domainId, rule.getPurpose());
newRule = _firewallDao.persist(newRule);
try {

View File

@ -21,22 +21,33 @@ import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
import com.cloud.network.dao.FirewallRulesDaoImpl;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRule.State;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.SearchCriteria.Op;
@Local(value=PortForwardingRulesDao.class)
public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRuleVO, Long> implements PortForwardingRulesDao {
private static final Logger s_logger = Logger.getLogger(PortForwardingRulesDaoImpl.class);
protected final SearchBuilder<PortForwardingRuleVO> AllFieldsSearch;
protected final SearchBuilder<PortForwardingRuleVO> ApplicationSearch;
protected final SearchBuilder<PortForwardingRuleVO> ActiveRulesSearch;
protected final SearchBuilder<PortForwardingRuleVO> AllRulesSearchByVM;
protected final SearchBuilder<PortForwardingRuleVO> ActiveRulesSearchByAccount;
protected final FirewallRulesCidrsDaoImpl _portForwardingRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class);
protected PortForwardingRulesDaoImpl() {
super();
@ -143,4 +154,53 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
return listBy(sc);
}
public void saveSourceCidrs(PortForwardingRuleVO portForwardingRule) {
List<String> cidrlist = portForwardingRule.getSourceCidrList();
if (cidrlist == null) {
return;
}
_portForwardingRulesCidrsDao.persist(portForwardingRule.getId(), cidrlist);
}
public void loadSourceCidrs(PortForwardingRuleVO portForwardingRule){
List<String> sourceCidrs = _portForwardingRulesCidrsDao.getSourceCidrs(portForwardingRule.getId());
portForwardingRule.setSourceCidrList(sourceCidrs);
}
@Override @DB
public PortForwardingRuleVO persist(PortForwardingRuleVO portForwardingRule) {
Transaction txn = Transaction.currentTxn();
txn.start();
PortForwardingRuleVO dbfirewallRule = super.persist(portForwardingRule);
saveSourceCidrs(portForwardingRule);
loadSourceCidrs(dbfirewallRule);
txn.commit();
return dbfirewallRule;
}
@Override @DB
public boolean update(Long portForwardingRuleId, PortForwardingRuleVO portForwardingRule) {
Transaction txn = Transaction.currentTxn();
txn.start();
boolean persisted = super.update(portForwardingRuleId, portForwardingRule);
if (!persisted) {
return persisted;
}
saveSourceCidrs(portForwardingRule);
txn.commit();
return persisted;
}
}

View File

@ -85,6 +85,7 @@ DROP TABLE IF EXISTS `cloud`.`load_balancing_ip_map`;
DROP TABLE IF EXISTS `cloud`.`load_balancing_rules`;
DROP TABLE IF EXISTS `cloud`.`port_forwarding_rules`;
DROP TABLE IF EXISTS `cloud`.`firewall_rules`;
DROP TABLE IF EXISTS `cloud`.`firewall_rules_cidrs`;
DROP TABLE IF EXISTS `cloud`.`ssh_keypairs`;
DROP TABLE IF EXISTS `cloud`.`usage_event`;
DROP TABLE IF EXISTS `cloud`.`host_tags`;
@ -565,6 +566,15 @@ CREATE TABLE `cloud`.`firewall_rules` (
CONSTRAINT `fk_firewall_rules__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`firewall_rules_cidrs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`firewall_rule_id` bigint(20) unsigned NOT NULL COMMENT 'firewall rule id',
`source_cidr` varchar(18) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_firewall_cidrs_firewall_rules` (`firewall_rule_id`),
CONSTRAINT `fk_firewall_cidrs_firewall_rules` FOREIGN KEY (`firewall_rule_id`) REFERENCES `firewall_rules` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `cloud`.`load_balancing_rules` (
`id` bigint unsigned NOT NULL,
`name` varchar(255) NOT NULL,