diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index ec6e712311e..c3668593fd1 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -199,7 +199,7 @@ public interface Network extends ControlledEntity { String getDisplayText(); - boolean isShared(); + boolean getIsShared(); String getReservationId(); diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java index 7c029c10e48..e0798056f61 100644 --- a/api/src/com/cloud/network/NetworkProfile.java +++ b/api/src/com/cloud/network/NetworkProfile.java @@ -48,7 +48,7 @@ public class NetworkProfile implements Network{ this.related = network.getRelated(); this.guestIpType = network.getGuestType(); this.displayText = network.getDisplayText(); - this.isShared = network.isShared(); + this.isShared = network.getIsShared(); this.reservationId = network.getReservationId(); this.isDefault = network.isDefault(); this.networkDomain = network.getNetworkDomain(); @@ -152,7 +152,7 @@ public class NetworkProfile implements Network{ } @Override - public boolean isShared() { + public boolean getIsShared() { return isShared; } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 1af0bb60529..c0c13096029 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -70,4 +70,6 @@ public interface NetworkService { Map> getZoneCapabilities(long zoneId); Map> getNetworkCapabilities(long networkId); + + boolean isNetworkAvailableInDomain(long networkId, long domainId); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index d47b719aabf..149b4ed03a3 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2303,7 +2303,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString()); } - response.setIsShared(network.isShared()); + response.setIsShared(network.getIsShared()); response.setIsDefault(network.isDefault()); response.setState(network.getState().toString()); response.setRelated(network.getRelated()); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 695459b645d..c1ecbe30a01 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -63,6 +63,7 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; @@ -1656,6 +1657,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Boolean isDefault = cmd.isDefault(); Long accountId = null; String path = null; + List avoidNetworks = new ArrayList(); + List allowedSharedNetworks = new ArrayList(); if (isSystem == null) { isSystem = false; @@ -1754,21 +1757,51 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc.addAnd("guestType", SearchCriteria.Op.EQ, type); } - if (!isSystem) { - + if (!isSystem) { if (accountName != null && domainId != null) { if (isShared == null) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); - sc.addOr("isShared", SearchCriteria.Op.EQ, true); + //sc.addOr("isShared", SearchCriteria.Op.EQ, true); } else if (!isShared) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } else { sc.addAnd("isShared", SearchCriteria.Op.EQ, true); } + + if (isShared == null || isShared) { + List allNetworks = _networksDao.listNetworksBy(true); + for (NetworkVO network : allNetworks) { + if (!isNetworkAvailableInDomain(network.getId(), domainId)) { + avoidNetworks.add(network.getId()); + } else { + allowedSharedNetworks.add(network.getId()); + } + } + } + } else if (isShared != null) { sc.addAnd("isShared", SearchCriteria.Op.EQ, isShared); } } + + //find list of shared networks to avoid + if (domainId != null && accountName == null) { + List allNetworks = _networksDao.listNetworksBy(true); + for (NetworkVO network : allNetworks) { + if (!isNetworkAvailableInDomain(network.getId(), domainId)) { + avoidNetworks.add(network.getId()); + } + } + sc.addAnd("isShared", SearchCriteria.Op.EQ, true); + } + + for (Long avoidNetwork : avoidNetworks) { + sc.addAnd("id", SearchCriteria.Op.NOTIN, avoidNetwork); + } + + for (Long allowerdSharedNetwork : allowedSharedNetworks) { + sc.addOr("id", SearchCriteria.Op.IN, allowerdSharedNetwork); + } if (isDefault != null) { sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); @@ -1781,8 +1814,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!isSystem && path != null && (isShared == null || !isShared)) { sc.setJoinParameters("domainSearch", "path", path + "%"); } - - List networks = _networksDao.search(sc, searchFilter); @@ -2604,7 +2635,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkVO network : zoneNetworks) { NetworkOfferingVO no = _networkOfferingDao.findById(network.getNetworkOfferingId()); if (!no.isSystemOnly()) { - if (network.isShared() || !_networksDao.listBy(accountId, network.getId()).isEmpty()) { + if (network.getIsShared() || !_networksDao.listBy(accountId, network.getId()).isEmpty()) { if ((guestType == null || guestType == network.getGuestType()) && (isDefault == null || isDefault == network.isDefault)) { accountNetworks.add(network); } @@ -2639,4 +2670,38 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return ip; } + + @Override + public boolean isNetworkAvailableInDomain(long networkId, long domainId) { + boolean result = false; + Long networkDomainId = null; + Network network = getNetwork(networkId); + if (!network.getIsShared()) { + s_logger.trace("Network id=" + networkId + " is not shared"); + return false; + } + + + List networks = _networksDao.listSharedDomainNetworksByNetworkId(networkId); + if (networks.isEmpty()) { + s_logger.trace("Network id=" + networkId + " is shared, but not domain specific"); + return true; + } else { + networkDomainId = networks.get(0).getDomainId(); + } + + if (domainId == networkDomainId.longValue()) { + return true; + } + + Domain domain = _domainDao.findById(domainId); + while (domain.getParent() != null) { + if (domain.getParent().longValue() == networkDomainId) { + return true; + } + domain = _domainDao.findById(domain.getParent()); + } + + return result; + } } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 719b0e4d171..d04c3f7c22c 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -377,7 +377,7 @@ public class NetworkVO implements Network { } @Override - public boolean isShared() { + public boolean getIsShared() { return isShared; } diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java index bcb1918a9e1..4e6f4bac27a 100644 --- a/server/src/com/cloud/network/dao/NetworkDao.java +++ b/server/src/com/cloud/network/dao/NetworkDao.java @@ -60,4 +60,9 @@ public interface NetworkDao extends GenericDao { void clearCheckForGc(long networkId); List listByZoneSecurityGroup(Long zoneId); void addDomainToNetwork(long networkId, long domainId); + + List listSharedDomainNetworksByDomain(long domainId); + List listSharedDomainNetworksByNetworkId(long networkId); + + List listNetworksBy(boolean isShared); } diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index 1633137e781..498ada55263 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -52,6 +52,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N final SearchBuilder AccountNetworkSearch; final SearchBuilder ZoneBroadcastUriSearch; final SearchBuilder ZoneSecurityGroupSearch; + final SearchBuilder DomainSearch; NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class); NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class); @@ -72,6 +73,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N AllFieldsSearch.and("account", AllFieldsSearch.entity().getAccountId(), Op.EQ); AllFieldsSearch.and("guesttype", AllFieldsSearch.entity().getGuestType(), Op.EQ); AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ); + AllFieldsSearch.and("isShared", AllFieldsSearch.entity().getIsShared(), Op.EQ); AllFieldsSearch.done(); AccountSearch = createSearchBuilder(); @@ -110,6 +112,14 @@ public class NetworkDaoImpl extends GenericDaoBase implements N ZoneSecurityGroupSearch.done(); _tgMacAddress = _tgs.get("macAddress"); + + DomainSearch = createSearchBuilder(); + SearchBuilder domainJoin = _domainsDao.createSearchBuilder(); + domainJoin.and("domainId", domainJoin.entity().getDomainId(), Op.EQ); + domainJoin.and("networkId", domainJoin.entity().getNetworkId(), Op.EQ); + DomainSearch.join("domains", domainJoin, DomainSearch.entity().getId(), domainJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER); + DomainSearch.done(); + } @Override @@ -284,4 +294,27 @@ public class NetworkDaoImpl extends GenericDaoBase implements N NetworkDomainVO domain = new NetworkDomainVO(configurationId, domainId); _domainsDao.persist(domain); } + + @Override + public List listSharedDomainNetworksByDomain(long domainId) { + SearchCriteria sc = DomainSearch.create(); + sc.setJoinParameters("domains", "domainId", domainId); + + return listBy(sc); + } + + @Override + public List listSharedDomainNetworksByNetworkId(long networkId) { + SearchCriteria sc = DomainSearch.create(); + sc.setJoinParameters("domains", "networkId", networkId); + + return listBy(sc); + } + + @Override + public List listNetworksBy(boolean isShared) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("isShared", isShared); + return listBy(sc); + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 02a1189aea5..aacc63ce634 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -772,7 +772,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian long dcId = dest.getDataCenter().getId(); NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(guestNetwork.getNetworkOfferingId()); - if (offering.isSystemOnly() || guestNetwork.isShared()) { + if (offering.isSystemOnly() || guestNetwork.getIsShared()) { owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); } @@ -927,7 +927,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian buf.append(" defaultroute=false"); String virtualNetworkElementNicIP = _networkMgr.getIpOfNetworkElementInVirtualNetwork(network.getAccountId(), network.getDataCenterId()); - if (!network.isShared() && virtualNetworkElementNicIP != null) { + if (!network.getIsShared() && virtualNetworkElementNicIP != null) { defaultDns1 = virtualNetworkElementNicIP; } else { s_logger.debug("No Virtual network found for account id=" + network.getAccountId() + " so setting dns to the dns of the network id=" + network.getId()); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index f5a8e04aea5..443318608b5 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1979,12 +1979,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager throw new InvalidParameterValueException("Can't create a vm with multiple networks one of which is Security Group enabled"); } - if (network.getTrafficType() != TrafficType.Guest || network.getGuestType() != GuestIpType.Direct || (network.isShared() && !network.isSecurityGroupEnabled())) { + if (network.getTrafficType() != TrafficType.Guest || network.getGuestType() != GuestIpType.Direct || (network.getIsShared() && !network.isSecurityGroupEnabled())) { throw new InvalidParameterValueException("Can specify only Direct Guest Account specific networks when deploy vm in Security Group enabled zone"); } //Perform account permission check - if (!network.isShared()) { + if (!network.getIsShared()) { //Check account permissions List networkMap = _networkDao.listBy(owner.getId(), network.getId()); if (networkMap == null || networkMap.isEmpty()) { @@ -2082,12 +2082,16 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } //Perform account permission check - if (!network.isShared()) { + if (!network.getIsShared()) { List networkMap = _networkDao.listBy(owner.getId(), network.getId()); if (networkMap == null || networkMap.isEmpty()) { throw new PermissionDeniedException("Unable to create a vm using network with id " + network.getId() + ", permission denied"); } - } + } else { + if (!_networkMgr.isNetworkAvailableInDomain(networkId, owner.getDomainId())) { + throw new PermissionDeniedException("Shared network id=" + networkId + " is not available in domain id=" + owner.getDomainId()); + } + } //check that corresponding offering is available NetworkOffering networkOffering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); diff --git a/utils/src/com/cloud/utils/db/SearchCriteria.java b/utils/src/com/cloud/utils/db/SearchCriteria.java index 03743d88410..d2756b2ebbf 100755 --- a/utils/src/com/cloud/utils/db/SearchCriteria.java +++ b/utils/src/com/cloud/utils/db/SearchCriteria.java @@ -47,6 +47,7 @@ public class SearchCriteria { BETWEEN(" BETWEEN ? AND ? ", 2), NBETWEEN(" NOT BETWEEN ? AND ? ", 2), IN(" IN () ", -1), + NOTIN(" NOT IN () ", -1), LIKE(" LIKE ? ", 1), NLIKE(" NOT LIKE ? ", 1), NIN(" NOT IN () ", -1),