diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index dca0fbf816e..9917f3eaa2b 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -171,7 +171,7 @@ public class CreatePortForwardingRuleCmd extends BaseCmd implements PortForwardi @Override public Ip getDestinationIpAddress() { - throw new UnsupportedOperationException("Not implemented yet"); + return null; } @Override diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 99dc726a6cf..b1ba2a8b619 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -61,7 +61,6 @@ import com.cloud.maid.dao.StackMaidDaoImpl; import com.cloud.maint.UpgradeManagerImpl; import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.NetworkManagerImpl; -import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.FirewallRulesDaoImpl; import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.LoadBalancerDaoImpl; @@ -72,6 +71,8 @@ import com.cloud.network.dao.RemoteAccessVpnDaoImpl; import com.cloud.network.dao.VpnUserDaoImpl; import com.cloud.network.lb.LoadBalancingRulesManagerImpl; import com.cloud.network.router.DomainRouterManagerImpl; +import com.cloud.network.rules.RulesManagerImpl; +import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.NetworkGroupManagerImpl; import com.cloud.network.security.dao.IngressRuleDaoImpl; import com.cloud.network.security.dao.NetworkGroupDaoImpl; @@ -226,7 +227,8 @@ public class DefaultComponentLibrary implements ComponentLibrary { addDao("RemoteAccessVpnDao", RemoteAccessVpnDaoImpl.class); addDao("VpnUserDao", VpnUserDaoImpl.class); addDao("ItWorkDao", ItWorkDaoImpl.class); - addDao("FirewallRulesDao", FirewallRulesDao.class); + addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); + addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class); } Map> _managers = new HashMap>(); @@ -279,6 +281,7 @@ public class DefaultComponentLibrary implements ComponentLibrary { addManager("DomainRouterManager", DomainRouterManagerImpl.class); addManager("EntityManager", EntityManagerImpl.class); addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class); + addManager("RulesManager", RulesManagerImpl.class); } protected List> addAdapterChain(Class interphace, List>> adapters) { diff --git a/server/src/com/cloud/network/LoadBalancerVO.java b/server/src/com/cloud/network/LoadBalancerVO.java index 7e7788f7c60..a0c6e0be4cb 100644 --- a/server/src/com/cloud/network/LoadBalancerVO.java +++ b/server/src/com/cloud/network/LoadBalancerVO.java @@ -21,9 +21,9 @@ package com.cloud.network; import java.util.List; import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.SecondaryTable; import javax.persistence.Table; import com.cloud.network.rules.FirewallRuleVO; @@ -33,8 +33,8 @@ import com.cloud.utils.net.NetUtils; @Entity @Table(name=("load_balancer")) -@SecondaryTable(name="account", - pkJoinColumns={@PrimaryKeyJoinColumn(name="account_id", referencedColumnName="id")}) +@DiscriminatorValue(value="LoadBalancing") +@PrimaryKeyJoinColumn(name="id") public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer { @Column(name="name") diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 9c0b37e240c..e5c764382cf 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2124,7 +2124,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean applyRules(Ip ip, List rules, boolean continueOnError) throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; + if (rules.size() == 0) { + s_logger.debug("There are no rules to forward to the network elements"); + return true; + } + + Network network = _networkConfigDao.findById(rules.get(0).getNetworkId()); + for (NetworkElement ne : _networkElements) { + try { + boolean handled = ne.applyRules(network, rules); + s_logger.debug("Network Rules for " + ip + " 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); + } + } + + return true; } } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index d7a507a8195..d0720ba0de8 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -33,7 +33,7 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.net.Ip; -@Local(value = { FirewallRulesDao.class }) @DB(txn=false) +@Local(value=FirewallRulesDao.class) @DB(txn=false) public class FirewallRulesDaoImpl extends GenericDaoBase implements FirewallRulesDao { private static final Logger s_logger = Logger.getLogger(FirewallRulesDaoImpl.class); diff --git a/server/src/com/cloud/network/rules/FirewallRuleVO.java b/server/src/com/cloud/network/rules/FirewallRuleVO.java index 84cc86b9a38..51ce6515d93 100644 --- a/server/src/com/cloud/network/rules/FirewallRuleVO.java +++ b/server/src/com/cloud/network/rules/FirewallRuleVO.java @@ -58,10 +58,10 @@ public class FirewallRuleVO implements FirewallRule { @Column(name="ip_address", updatable=false) Ip sourceIpAddress; - @Column(name="port_start", updatable=false) + @Column(name="start_port", updatable=false) int sourcePortStart; - @Column(name="port_end", updatable=false) + @Column(name="end_port", updatable=false) int sourcePortEnd; @Column(name="protocol", updatable=false) @@ -135,6 +135,7 @@ public class FirewallRuleVO implements FirewallRule { return state; } + @Override public long getNetworkId() { return networkId; } diff --git a/server/src/com/cloud/network/rules/PortForwardingRuleVO.java b/server/src/com/cloud/network/rules/PortForwardingRuleVO.java index 180d5cbbe8e..e9112a500fc 100644 --- a/server/src/com/cloud/network/rules/PortForwardingRuleVO.java +++ b/server/src/com/cloud/network/rules/PortForwardingRuleVO.java @@ -29,7 +29,7 @@ import javax.persistence.Table; import com.cloud.utils.net.Ip; @Entity -@Table(name=("port_forwarding_rule")) +@Table(name=("port_forwarding_rules")) @DiscriminatorValue(value="PortForwarding") @PrimaryKeyJoinColumn(name="id") public class PortForwardingRuleVO extends FirewallRuleVO implements PortForwardingRule { diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 2aef929dde6..921c7d1e998 100644 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -56,7 +56,7 @@ import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; -@Local(value=RulesManager.class) +@Local(value={RulesManager.class, RulesService.class}) public class RulesManagerImpl implements RulesManager, RulesService, Manager { private static final Logger s_logger = Logger.getLogger(RulesManagerImpl.class); String _name; @@ -254,11 +254,21 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { // FIXME: Not working yet. return null; } - + @Override public List listPortForwardingRules(ListPortForwardingRulesCmd cmd) { - // TODO Auto-generated method stub - return null; + Ip ipAddress = new Ip(cmd.getIpAddress()); + Account caller = UserContext.current().getAccount(); + + IPAddressVO ipAddressVO = _ipAddressDao.findById(ipAddress.addr()); + if (ipAddressVO == null || ipAddressVO.getAllocated() == null) { + throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); + } + + List rules = _forwardingDao.listByIpAndNotRevoked(ipAddress); + _accountMgr.checkAccess(caller, rules.toArray(new PortForwardingRuleVO[rules.size()])); + + return rules; } @Override @@ -666,36 +676,6 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { // return newFwRule; // } // -// @Override -// public List listPortForwardingRules(ListPortForwardingRulesCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { -// String ipAddress = cmd.getIpAddress(); -// Account account = UserContext.current().getAccount(); -// -// IPAddressVO ipAddressVO = _ipAddressDao.findById(ipAddress); -// if (ipAddressVO == null) { -// throw new InvalidParameterValueException("Unable to find IP address " + ipAddress); -// } -// -// Account addrOwner = _accountDao.findById(ipAddressVO.getAccountId()); -// -// // if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters -// if ((account != null) && isAdmin(account.getType())) { -// if (ipAddressVO.getAccountId() != null) { -// if ((addrOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), addrOwner.getDomainId())) { -// throw new PermissionDeniedException("Unable to list port forwarding rules for address " + ipAddress + ", permission denied for account " + account.getId()); -// } -// } -// } else { -// if (account != null) { -// if ((ipAddressVO.getAccountId() == null) || (account.getId() != ipAddressVO.getAccountId().longValue())) { -// throw new PermissionDeniedException("Unable to list port forwarding rules for address " + ipAddress + ", permission denied for account " + account.getId()); -// } -// } -// } -// -// return _rulesDao.listIPForwarding(cmd.getIpAddress(), true); -// } - // @Override @DB // public boolean deletePortForwardingRule(Long id, boolean sysContext) { // Long ruleId = id; diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java index 9156eae8e54..c9d3bcb0d99 100644 --- a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java +++ b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java @@ -25,4 +25,12 @@ import com.cloud.utils.net.Ip; public interface PortForwardingRulesDao extends GenericDao { List listForApplication(Ip ip); + + /** + * Find all port forwarding rules that have not been revoked. + * + * @param ip ip address + * @return List of PortForwardingRuleVO + */ + List listByIpAndNotRevoked(Ip ip); } diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRuleDaoImpl.java b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java similarity index 71% rename from server/src/com/cloud/network/rules/dao/PortForwardingRuleDaoImpl.java rename to server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java index a4a45f8c0a5..fdea05416ce 100644 --- a/server/src/com/cloud/network/rules/dao/PortForwardingRuleDaoImpl.java +++ b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java @@ -30,12 +30,13 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.net.Ip; @Local(value=PortForwardingRulesDao.class) -public class PortForwardingRuleDaoImpl extends GenericDaoBase implements PortForwardingRulesDao { +public class PortForwardingRulesDaoImpl extends GenericDaoBase implements PortForwardingRulesDao { protected final SearchBuilder AllFieldsSearch; - protected final SearchBuilder ApplicationSearch; + protected final SearchBuilder ApplicationSearch; + protected final SearchBuilder ActiveRulesSearch; - protected PortForwardingRuleDaoImpl() { + protected PortForwardingRulesDaoImpl() { super(); AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); @@ -44,6 +45,11 @@ public class PortForwardingRuleDaoImpl extends GenericDaoBase listByIpAndNotRevoked(Ip ip) { + SearchCriteria sc = ActiveRulesSearch.create(); + sc.setParameters("ip", ip); + sc.setParameters("state", State.Revoke); + + return listBy(sc, null); + } } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 290c8280104..b58eec19b80 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -557,7 +557,9 @@ public class AccountManagerImpl implements AccountManager, AccountService { accountId = userAccount.getId(); } - if (accountId != null) domainId = null; + if (accountId != null) { + domainId = null; + } @@ -701,7 +703,6 @@ public class AccountManagerImpl implements AccountManager, AccountService { } } } - private boolean doSetUserStatus(long userId, String state) { UserVO userForUpdate = _userDao.createForUpdate(); @@ -738,6 +739,7 @@ public class AccountManagerImpl implements AccountManager, AccountService { return success; } + @Override public boolean deleteUserInternal(long userId, long startEventId) { UserAccount userAccount = null; Long accountId = null; @@ -789,8 +791,9 @@ public class AccountManagerImpl implements AccountManager, AccountService { return false; }finally{ long domainId = 0L; - if (userAccount != null) + if (userAccount != null) { domainId = userAccount.getDomainId(); + } String description = "User " + username + " (id: " + userId + ") for accountId = " + accountId + " and domainId = " + domainId; if(result){ EventUtils.saveEvent(UserContext.current().getUserId(), accountId, EventVO.LEVEL_INFO, EventTypes.EVENT_USER_DELETE, "Successfully deleted " +description, startEventId); @@ -800,6 +803,7 @@ public class AccountManagerImpl implements AccountManager, AccountService { } } + @Override public boolean deleteAccount(AccountVO account) { long accountId = account.getId(); long userId = 1L; // only admins can delete users, pass in userId 1 XXX: Shouldn't it be userId 2. @@ -927,6 +931,7 @@ public class AccountManagerImpl implements AccountManager, AccountService { } } + @Override public boolean disableAccount(long accountId) { boolean success = false; if (accountId <= 2) { @@ -1168,8 +1173,9 @@ public class AccountManagerImpl implements AccountManager, AccountService { //Check if user exists in the system User user = _userDao.findById(userId); - if ((user == null) || (user.getRemoved() != null)) + if ((user == null) || (user.getRemoved() != null)) { throw new InvalidParameterValueException("Unable to find active user by id " + userId); + } // If the user is a System user, return an error Account account = _accountDao.findById(user.getAccountId()); @@ -1191,10 +1197,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { } // there are no enabled users attached to this user's account, disable the account - if (disableAccount(user.getAccountId())) + if (disableAccount(user.getAccountId())) { return _userAccountDao.findById(userId); - else + } else { throw new CloudRuntimeException("Unable to disable corresponding account for the user " + userId); + } } else { throw new CloudRuntimeException("Unable to disable user " + userId); @@ -1209,8 +1216,9 @@ public class AccountManagerImpl implements AccountManager, AccountService { //Check if user exists in the system User user = _userDao.findById(userId); - if ((user == null) || (user.getRemoved() != null)) + if ((user == null) || (user.getRemoved() != null)) { throw new InvalidParameterValueException("Unable to find active user by id " + userId); + } // If the user is a System user, return an error Account account = _accountDao.findById(user.getAccountId()); @@ -1227,9 +1235,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { // make sure the account is enabled too success = (success && enableAccount(user.getAccountId())); - if (success) + if (success) { return _userAccountDao.findById(userId); - else throw new CloudRuntimeException("Unable to enable user " + userId); + } else { + throw new CloudRuntimeException("Unable to enable user " + userId); + } } @Override @@ -1283,10 +1293,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { } } - if (success) + if (success) { return _userAccountDao.findById(id); - else + } else { throw new CloudRuntimeException("Unable to lock user " + id); + } } @Override @@ -1335,10 +1346,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { } success = enableAccount(account.getId()); - if (success) + if (success) { return _accountDao.findById(account.getId()); - else + } else { throw new CloudRuntimeException("Unable to enable account " + accountName + " in domain " + domainId); + } } @Override @@ -1361,10 +1373,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { throw new InvalidParameterValueException("can not lock system account"); } - if (lockAccountInternal(account.getId())) + if (lockAccountInternal(account.getId())) { return _accountDao.findById(account.getId()); - else + } else { throw new CloudRuntimeException("Unable to lock account " + accountName + " in domain " + domainId); + } } @Override @@ -1381,10 +1394,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { if (account == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } - if (disableAccount(account.getId())) + if (disableAccount(account.getId())) { return _accountDao.findById(account.getId()); - else + } else { throw new CloudRuntimeException("Unable to update account " + accountName + " in domain " + domainId); + } } @Override @@ -1426,10 +1440,11 @@ public class AccountManagerImpl implements AccountManager, AccountService { acctForUpdate.setAccountName(newAccountName); success = _accountDao.update(Long.valueOf(account.getId()), acctForUpdate); } - if (success) + if (success) { return _accountDao.findById(account.getId()); - else + } else { throw new CloudRuntimeException("Unable to update account " + accountName + " in domain " + domainId); + } } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 71e4fff2147..d4abe6d7e7e 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -433,7 +433,7 @@ CREATE TABLE `cloud`.`op_dc_vnet_alloc` ( CREATE TABLE `cloud`.`firewall_rules` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', - `ip_address` bigint unsigned NOT NULL COMMENT 'id_address', + `ip_address` bigint unsigned NOT NULL COMMENT 'ip_address', `start_port` int(10) NOT NULL default -1 COMMENT 'starting port of a port range', `end_port` int(10) NOT NULL default -1 COMMENT 'end port of a port range', `state` char(32) NOT NULL COMMENT 'current state of this rule', @@ -441,9 +441,13 @@ CREATE TABLE `cloud`.`firewall_rules` ( `purpose` char(32) NOT NULL COMMENT 'why are these ports opened?', `account_id` bigint unsigned NOT NULL COMMENT 'owner id', `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', `xid` char(40) NOT NULL COMMENT 'external id', `created` datetime COMMENT 'Date created', - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + CONSTRAINT `fk_firewall_rules__network_id` FOREIGN KEY(`network_id`) REFERENCES `network`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`load_balancing_rules` ( diff --git a/utils/src/com/cloud/utils/db/Attribute.java b/utils/src/com/cloud/utils/db/Attribute.java index 6967c5fe323..82a071adc40 100755 --- a/utils/src/com/cloud/utils/db/Attribute.java +++ b/utils/src/com/cloud/utils/db/Attribute.java @@ -113,7 +113,6 @@ public class Attribute { flags = Flag.Insertable.setTrue(flags); flags = Flag.TableGV.setTrue(flags); } else if (gv.strategy() == GenerationType.AUTO) { - assert (false) : "Auto generation not supported."; flags = Flag.DaoGenerated.setTrue(flags); flags = Flag.Insertable.setTrue(flags); flags = Flag.AutoGV.setTrue(flags); diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 51b994f392b..1bcdea98b4e 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -1303,7 +1303,7 @@ public abstract class GenericDaoBase implements Gene if (type == EnumType.STRING) { pstmt.setString(j, value == null ? null : value.toString()); } else if (type == EnumType.ORDINAL) { - pstmt.setLong(j, value != null ? null : ((Ip)value).longValue()); + pstmt.setLong(j, value == null ? null : ((Ip)value).longValue()); } } else { pstmt.setObject(j, value);