From bb2a8cf7eab076a6deeffcfbb42a2577ee984cd1 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 14 Nov 2011 18:12:03 -0800 Subject: [PATCH] NaaS: added "subdomainAccess" parameter to domain level network object. The parameter defines whether the network can be accessed from the subdomains. If the parameter is not specified, it would be defaulted to allow.subdomain.network.access Global Config param --- api/src/com/cloud/api/ApiConstants.java | 1 + .../cloud/api/commands/CreateNetworkCmd.java | 7 + .../cloud/api/response/NetworkResponse.java | 15 ++- server/src/com/cloud/api/ApiDBUtils.java | 13 ++ server/src/com/cloud/api/ApiDispatcher.java | 3 +- .../src/com/cloud/api/ApiResponseHelper.java | 11 +- .../ConfigurationManagerImpl.java | 3 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 2 +- .../com/cloud/network/NetworkDomainVO.java | 11 +- .../src/com/cloud/network/NetworkManager.java | 7 +- .../com/cloud/network/NetworkManagerImpl.java | 125 +++++++++--------- .../src/com/cloud/network/dao/NetworkDao.java | 2 +- .../com/cloud/network/dao/NetworkDaoImpl.java | 8 +- .../cloud/network/dao/NetworkDomainDao.java | 4 +- .../network/dao/NetworkDomainDaoImpl.java | 19 +-- .../SecondaryStorageManagerImpl.java | 2 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 6 +- .../cloud/network/MockNetworkManagerImpl.java | 4 +- setup/db/create-schema.sql | 1 + 19 files changed, 144 insertions(+), 100 deletions(-) diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index fddd2dfdd55..2b10d22e447 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -303,5 +303,6 @@ public class ApiConstants { public static final String NSP_ID= "nspid"; public static final String ACL_TYPE= "acltype"; public static final String IS_SOURCE_NAT_SHARED = "isshared"; + public static final String SUBDOMAIN_ACCESS = "subdomainaccess"; } diff --git a/api/src/com/cloud/api/commands/CreateNetworkCmd.java b/api/src/com/cloud/api/commands/CreateNetworkCmd.java index a7d17789aa3..5036b542a21 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkCmd.java @@ -94,6 +94,9 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.ACL_TYPE, type=CommandType.STRING, description="Access control type; supported values are account and domain. If not specified, defaulted to Account in Adavnce zone, and to Domain in Basic zone. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network") private String aclType; + @Parameter(name=ApiConstants.SUBDOMAIN_ACCESS, type=CommandType.BOOLEAN, description="Defines whether to allow subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to true if not specified") + private Boolean subdomainAccess; + @IdentityMapper(entityTableName="physical_network") @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, description="the Physical Network ID the network belongs to") private Long physicalNetworkId; @@ -157,6 +160,10 @@ public class CreateNetworkCmd extends BaseCmd { return aclType; } + public Boolean getSubdomainAccess() { + return subdomainAccess; + } + public Long getZoneId() { Long physicalNetworkId = getPhysicalNetworkId(); diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index d12f611e057..5772d1da6e3 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -94,6 +94,12 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.VLAN) @Param(description="the vlan of the network") private String vlan; + @SerializedName(ApiConstants.ACL_TYPE) @Param(description="acl type - access type to the network") + private String aclType; + + @SerializedName(ApiConstants.SUBDOMAIN_ACCESS) @Param(description="true if users from subdomains can access the domain level network") + private Boolean subdomainAccess; + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the network") private String accountName; @@ -121,10 +127,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network id") private IdentityProxy physicalNetworkId = new IdentityProxy("physical_network"); - @SerializedName(ApiConstants.ACL_TYPE) @Param(description="acl type - access type to the network") - private String aclType; - - public void setId(Long id) { this.id.setValue(id); } @@ -254,5 +256,8 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes public void setAclType(String aclType) { this.aclType = aclType; } - + + public void setSubdomainAccess(Boolean subdomainAccess) { + this.subdomainAccess = subdomainAccess; + } } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 17522b0cbc9..6015f5ac8a6 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -56,6 +56,7 @@ import com.cloud.network.LoadBalancerVO; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkDomainVO; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkProfile; import com.cloud.network.NetworkRuleConfigVO; @@ -65,6 +66,7 @@ import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.dao.NetworkRuleConfigDao; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; @@ -116,6 +118,7 @@ import com.cloud.user.dao.UserDao; import com.cloud.user.dao.UserStatisticsDao; import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.DomainRouterVO; @@ -180,6 +183,7 @@ public class ApiDBUtils { private static ProjectService _projectMgr; private static ResourceManager _resourceMgr; private static AccountDetailsDao _accountDetailsDao; + private static NetworkDomainDao _networkDomainDao; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); @@ -229,6 +233,7 @@ public class ApiDBUtils { _projectMgr = locator.getManager(ProjectService.class); _resourceMgr = locator.getManager(ResourceManager.class); _accountDetailsDao = locator.getDao(AccountDetailsDao.class); + _networkDomainDao = locator.getDao(NetworkDomainDao.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -687,4 +692,12 @@ public class ApiDBUtils { public static boolean canElementEnableIndividualServices(Provider serviceProvider) { return _networkMgr.canElementEnableIndividualServices(serviceProvider); } + + public static Pair getDomainNetworkDetails(long networkId) { + NetworkDomainVO map = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); + + boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : _networkMgr.getAllowSubdomainAccessGlobal(); + + return new Pair(map.getDomainId(), subdomainAccess); + } } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 80ec0dd3d04..8c6b7f535d7 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -30,6 +30,7 @@ import java.util.regex.Matcher; import org.apache.log4j.Logger; +import com.cloud.identity.dao.IdentityDao; import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.commands.ListEventsCmd; import com.cloud.async.AsyncCommandQueued; @@ -40,8 +41,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.identity.dao.IdentityDao; -import com.cloud.identity.dao.IdentityDaoImpl; import com.cloud.server.ManagementServer; import com.cloud.user.Account; import com.cloud.user.UserContext; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 61b7794ed35..031fe776a21 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -32,6 +32,7 @@ import java.util.StringTokenizer; import org.apache.log4j.Logger; import com.cloud.acl.ControlledEntity; +import com.cloud.acl.ControlledEntity.ACLType; import com.cloud.api.commands.QueryAsyncJobResultCmd; import com.cloud.api.response.AccountResponse; import com.cloud.api.response.ApiResponseSerializer; @@ -175,6 +176,7 @@ import com.cloud.user.UserContext; import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; @@ -2452,7 +2454,14 @@ public class ApiResponseHelper implements ResponseGenerator { } response.setServices(serviceResponses); - populateOwner(response, network); + if (network.getAclType() == null || network.getAclType() == ACLType.Account) { + populateOwner(response, network); + } else { + //get domain from network_domain table + Pair domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId()); + response.setDomainId(domainNetworkDetails.first()); + response.setSubdomainAccess(domainNetworkDetails.second()); + } Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId()); if (dedicatedDomainId != null) { diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1552046d8a5..2eb6ab0ba2f 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -36,6 +36,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.acl.SecurityChecker; +import com.cloud.acl.ControlledEntity.ACLType; import com.cloud.alert.AlertManager; import com.cloud.api.commands.CreateCfgCmd; import com.cloud.api.commands.CreateDiskOfferingCmd; @@ -1458,7 +1459,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura userNetwork.setBroadcastDomainType(broadcastDomainType); userNetwork.setNetworkDomain(networkDomain); - _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, isNetworkDefault, false, Domain.ROOT_DOMAIN, null); + _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, isNetworkDefault, false, Domain.ROOT_DOMAIN, null, null); } } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 63c4a59ae8c..1986d4dd85f 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -583,7 +583,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx defaultNic.setDefaultNic(true); defaultNic.setDeviceId(2); - networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), null, plan, null, null, false, false, null, null).get(0), defaultNic)); + networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0), defaultNic)); for (NetworkOfferingVO offering : offerings) { networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null)); diff --git a/server/src/com/cloud/network/NetworkDomainVO.java b/server/src/com/cloud/network/NetworkDomainVO.java index 51ae0911251..c844b4ec8af 100644 --- a/server/src/com/cloud/network/NetworkDomainVO.java +++ b/server/src/com/cloud/network/NetworkDomainVO.java @@ -42,13 +42,17 @@ public class NetworkDomainVO implements PartOf { @Column(name="network_id") long networkId; + + @Column(name="subdomain_access") + Boolean subdomainAccess; protected NetworkDomainVO() { } - public NetworkDomainVO(long networkId, long domainId) { + public NetworkDomainVO(long networkId, long domainId, Boolean subdomainAccess) { this.networkId = networkId; this.domainId = domainId; + this.subdomainAccess = subdomainAccess; } @Override @@ -59,5 +63,8 @@ public class NetworkDomainVO implements PartOf { public long getNetworkId() { return networkId; } - + + public Boolean isSubdomainAccess() { + return subdomainAccess; + } } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 3084d3396f2..26316a02037 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -1,5 +1,6 @@ /** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. @@ -115,7 +116,7 @@ public interface NetworkManager extends NetworkService { throws ConcurrentOperationException; List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean isDefault, boolean errorIfAlreadySetup, - Long domainId, ACLType aclType) throws ConcurrentOperationException; + Long domainId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException; List getSystemAccountNetworkOfferings(String... offeringNames); @@ -156,7 +157,7 @@ public interface NetworkManager extends NetworkService { boolean destroyNetwork(long networkId, ReservationContext context); Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isDefault, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, - Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType) throws ConcurrentOperationException, InsufficientCapacityException; + Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException; /** * @throws InsufficientCapacityException @@ -248,4 +249,6 @@ public interface NetworkManager extends NetworkService { Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service); Long getPhysicalNetworkId(Network network); + + boolean getAllowSubdomainAccessGlobal(); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c8077dcdef7..0d5bf851e53 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -975,7 +975,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NicForTrafficTypeSearch.done(); _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger")); - + _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key())); _agentMgr.registerForHostEvents(this, true, false, true); @@ -1051,13 +1051,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) throws ConcurrentOperationException { - return setupNetwork(owner, offering, null, plan, name, displayText, isDefault, false, null, null); + return setupNetwork(owner, offering, null, plan, name, displayText, isDefault, false, null, null, null); } @Override @DB public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean isDefault, boolean errorIfAlreadySetup, - Long domainId, ACLType aclType) throws ConcurrentOperationException { + Long domainId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { Account locked = _accountDao.acquireInLockTable(owner.getId()); if (locked == null) { throw new ConcurrentOperationException("Unable to acquire lock on " + owner); @@ -1120,8 +1120,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag predefined.getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType); networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); - if (domainId != null) { - _networksDao.addDomainToNetwork(id, domainId); + if (domainId != null && aclType == ACLType.Domain) { + _networksDao.addDomainToNetwork(id, domainId, subdomainAccess); } } @@ -1724,6 +1724,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String aclTypeStr = cmd.getAclType(); Long domainId = cmd.getDomainId(); boolean isDomainSpecific = false; + Boolean subdomainAccess = cmd.getSubdomainAccess(); // Validate network offering NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); @@ -1803,6 +1804,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountMgr.checkAccess(caller, domain); } isDomainSpecific = true; + } else if (subdomainAccess != null) { + throw new InvalidParameterValueException("Parameter subDomainAccess can be specified only with aclType=Domain"); } @@ -1880,7 +1883,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - Network network = createNetwork(networkOfferingId, name, displayText, isDefault, gateway, cidr, vlanId, networkDomain, owner, false, sharedDomainId, pNtwk, zoneId, aclType); + Network network = createNetwork(networkOfferingId, name, displayText, isDefault, gateway, cidr, vlanId, networkDomain, owner, false, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess); //Vlan is created in 2 cases - works in Advance zone only: //1) GuestType is Shared @@ -1900,7 +1903,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB public Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isDefault, String gateway, String cidr, String vlanId, String networkDomain, Account owner, - boolean isSecurityGroupEnabled, Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType) throws ConcurrentOperationException, InsufficientCapacityException { + boolean isSecurityGroupEnabled, Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException { NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); DataCenterVO zone = _dcDao.findById(zoneId); @@ -2046,7 +2049,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - List networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, isDefault, true, domainId, aclType); + List networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, isDefault, true, domainId, aclType, subdomainAccess); Network network = null; if (networks == null || networks.isEmpty()) { @@ -2086,7 +2089,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Long projectId = cmd.getProjectId(); List permittedAccounts = new ArrayList(); String path = null; - Long sharedNetworkDomainId = null; Long physicalNetworkId = cmd.getPhysicalNetworkId(); List supportedServicesStr = cmd.getSupportedServices(); @@ -2121,7 +2123,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!_accountMgr.isAdmin(caller.getType())) { permittedAccounts.add(caller.getId()); - sharedNetworkDomainId = caller.getDomainId(); + domainId = caller.getDomainId(); } //set project information @@ -2141,14 +2143,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag path = _domainDao.findById(caller.getDomainId()).getPath(); - if ((isSystem == null || !isSystem) && (aclType != null && aclType.equalsIgnoreCase(ACLType.Domain.toString()))) { - if (domainId == null) { - sharedNetworkDomainId = domainId; - } else { - sharedNetworkDomainId = caller.getDomainId(); - } - } - Filter searchFilter = new Filter(NetworkVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _networksDao.createSearchBuilder(); @@ -2163,36 +2157,32 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag SearchBuilder zoneSearch = _dcDao.createSearchBuilder(); zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ); sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER); - - //domain level networks - if (sharedNetworkDomainId != null) { - SearchBuilder domainNetworkSearch = _networkDomainDao.createSearchBuilder(); - sb.join("domainNetworkSearch", domainNetworkSearch, sb.entity().getId(), domainNetworkSearch.entity().getNetworkId(), JoinBuilder.JoinType.LEFTOUTER); - } - sb.and("removed", sb.entity().getRemoved(), Op.NULL); + + if (permittedAccounts.isEmpty()) { + SearchBuilder domainSearch = _domainDao.createSearchBuilder(); + domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); + sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } List networksToReturn = new ArrayList(); if (isSystem == null || !isSystem) { - //Get domain level + account level networks - if (sharedNetworkDomainId != null) { - networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, ACLType.Domain.toString()), searchFilter, sharedNetworkDomainId)); + //Get domain level networks + if (domainId != null) { + networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, aclType), searchFilter, domainId)); } else if (permittedAccounts.isEmpty()){ - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); - networksToReturn.addAll(listDomainSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, aclType), searchFilter, path)); + networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, aclType), searchFilter, path)); } - if (!permittedAccounts.isEmpty()) { - networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, ACLType.Account.toString()), searchFilter, path, permittedAccounts)); + //get account specific networks + if (!permittedAccounts.isEmpty()){ + networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, aclType), searchFilter, permittedAccounts)); } } else { networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, isDefault, trafficType, physicalNetworkId, null), searchFilter); } - if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) { List supportedNetworks = new ArrayList(); Service[] suppportedServices = new Service[supportedServicesStr.size()]; @@ -2259,48 +2249,51 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (physicalNetworkId != null) { sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId); } - + return sc; } private List listDomainLevelNetworks(SearchCriteria sc, Filter searchFilter, long domainId) { - - Set allowedDomains = new HashSet(); - if (_allowSubdomainNetworkAccess) { - allowedDomains = _domainMgr.getDomainParentIds(domainId); - } else { - allowedDomains.add(domainId); - } - - sc.addJoinAnd("domainNetworkSearch", "domainId", SearchCriteria.Op.IN, allowedDomains.toArray()); + List networkIds = new ArrayList(); + Set allowedDomains = _domainMgr.getDomainParentIds(domainId); + List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); + + for (NetworkDomainVO map : maps) { + boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : getAllowSubdomainAccessGlobal(); + if (map.getDomainId() == domainId || subdomainAccess) { + networkIds.add(map.getNetworkId()); + } + } + + SearchCriteria domainSC = _networksDao.createSearchCriteria(); + domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); + domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); + + sc.addAnd("id", SearchCriteria.Op.SC, domainSC); return _networksDao.search(sc, searchFilter); } - private List listAccountSpecificNetworks(SearchCriteria sc, Filter searchFilter, String path, List permittedAccounts) { - //account level networks + private List listAccountSpecificNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { SearchCriteria accountSC = _networksDao.createSearchCriteria(); if (!permittedAccounts.isEmpty()) { accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); } - + accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); - if (path != null) { - Set allowedDomains = _domainMgr.getDomainChildrenIds(path); - accountSC.addAnd("domainId", SearchCriteria.Op.IN, allowedDomains.toArray()); - } sc.addAnd("id", SearchCriteria.Op.SC, accountSC); - return _networksDao.search(sc, searchFilter); } - private List listDomainSpecificNetworks(SearchCriteria sc, Filter searchFilter, String path) { - + private List listAccountSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path) { + SearchCriteria accountSC = _networksDao.createSearchCriteria(); + accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); + if (path != null) { sc.setJoinParameters("domainSearch", "path", path + "%"); } - + return _networksDao.search(sc, searchFilter); } @@ -2957,7 +2950,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (createNetwork) { List offerings = _configMgr.listNetworkOfferings(TrafficType.Guest, false); PhysicalNetwork physicalNetwork = translateZoneIdToPhysicalNetwork(zoneId); - network = createNetwork(offerings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, null, null, null, owner, false, null, physicalNetwork, zoneId, ACLType.Account); + network = createNetwork(offerings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, null, null, null, owner, false, null, physicalNetwork, zoneId, ACLType.Account, null); if (network == null) { s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); @@ -3235,19 +3228,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return false; } - List networkDomainMap = _networkDomainDao.listDomainNetworkMapByNetworkId(networkId); - if (networkDomainMap.isEmpty()) { + NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); + if (networkDomainMap == null) { s_logger.trace("Network id=" + networkId + " is shared, but not domain specific"); return true; } else { - networkDomainId = networkDomainMap.get(0).getDomainId(); + networkDomainId = networkDomainMap.getDomainId(); } if (domainId == networkDomainId.longValue()) { return true; } - if (_allowSubdomainNetworkAccess) { + if (networkDomainMap.subdomainAccess) { Set parentDomains = _domainMgr.getDomainParentIds(domainId); if (parentDomains.contains(domainId)) { @@ -3260,9 +3253,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public Long getDedicatedNetworkDomain(long networkId) { - List networkMaps = _networkDomainDao.listDomainNetworkMapByNetworkId(networkId); - if (!networkMaps.isEmpty()) { - return networkMaps.get(0).getDomainId(); + NetworkDomainVO networkMaps = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); + if (networkMaps != null) { + return networkMaps.getDomainId(); } else { return null; } @@ -4976,4 +4969,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return physicalNetworkId; } + @Override + public boolean getAllowSubdomainAccessGlobal() { + return _allowSubdomainNetworkAccess; + } } diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java index 642f03b93cc..07801749b17 100644 --- a/server/src/com/cloud/network/dao/NetworkDao.java +++ b/server/src/com/cloud/network/dao/NetworkDao.java @@ -72,7 +72,7 @@ public interface NetworkDao extends GenericDao { List listByZoneSecurityGroup(Long zoneId); - void addDomainToNetwork(long networkId, long domainId); + void addDomainToNetwork(long networkId, long domainId, Boolean subdomainAccess); Long getNetworkCountByOfferingId(long offeringId); diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index 7f13e132490..a3dee05b479 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -321,12 +321,12 @@ public class NetworkDaoImpl extends GenericDaoBase implements N } @Override - public void addDomainToNetwork(long networkId, long domainId) { - addDomainToNetworknetwork(networkId, domainId); + public void addDomainToNetwork(long networkId, long domainId, Boolean subdomainAccess) { + addDomainToNetworknetwork(networkId, domainId, subdomainAccess); } - protected void addDomainToNetworknetwork(long networkId, long domainId) { - NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId); + protected void addDomainToNetworknetwork(long networkId, long domainId, Boolean subdomainAccess) { + NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId, subdomainAccess); _domainsDao.persist(domain); } diff --git a/server/src/com/cloud/network/dao/NetworkDomainDao.java b/server/src/com/cloud/network/dao/NetworkDomainDao.java index 1aa59f58048..46b24c8cdbd 100644 --- a/server/src/com/cloud/network/dao/NetworkDomainDao.java +++ b/server/src/com/cloud/network/dao/NetworkDomainDao.java @@ -24,7 +24,7 @@ import com.cloud.network.NetworkDomainVO; import com.cloud.utils.db.GenericDao; public interface NetworkDomainDao extends GenericDao{ - List listDomainNetworkMapByDomain(long domainId); - List listDomainNetworkMapByNetworkId(long networkId); + List listDomainNetworkMapByDomain(Object... domainId); + NetworkDomainVO getDomainNetworkMapByNetworkId(long networkId); List listNetworkIdsByDomain(long domainId); } diff --git a/server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java index 83bdf07f8c4..218d80bc5bb 100644 --- a/server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java @@ -32,7 +32,7 @@ import com.cloud.utils.db.SearchCriteria.Op; @Local(value=NetworkDomainDao.class) @DB(txn=false) public class NetworkDomainDaoImpl extends GenericDaoBase implements NetworkDomainDao { final SearchBuilder AllFieldsSearch; - + final SearchBuilder DomainsSearch; protected NetworkDomainDaoImpl() { super(); @@ -42,22 +42,24 @@ public class NetworkDomainDaoImpl extends GenericDaoBase AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ); AllFieldsSearch.done(); + DomainsSearch = createSearchBuilder(); + DomainsSearch.and("domainId", DomainsSearch.entity().getDomainId(), Op.IN); + DomainsSearch.done(); } @Override - public List listDomainNetworkMapByDomain(long domainId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("domainId", domainId); + public List listDomainNetworkMapByDomain(Object... domainId) { + SearchCriteria sc = DomainsSearch.create(); + sc.setParameters("domainId", (Object[])domainId); return listBy(sc); } @Override - public List listDomainNetworkMapByNetworkId(long networkId) { + public NetworkDomainVO getDomainNetworkMapByNetworkId(long networkId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("networkId", networkId); - - return listBy(sc); + return findOneBy(sc); } @Override @@ -66,8 +68,7 @@ public class NetworkDomainDaoImpl extends GenericDaoBase List maps = listDomainNetworkMapByDomain(domainId); for (NetworkDomainVO map : maps) { networkIdsToReturn.add(map.getNetworkId()); - } - + } return networkIdsToReturn; } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 8113eaba6eb..bc962c5987a 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -541,7 +541,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V defaultNic.setDefaultNic(true); defaultNic.setDeviceId(2); try { - networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), null, plan, null, null, false, false, null, null).get(0), defaultNic)); + networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0), defaultNic)); for (NetworkOfferingVO offering : offerings) { networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null)); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 20f16cec659..a7f36d8079e 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2217,7 +2217,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (virtualNetworks.isEmpty()) { s_logger.debug("Creating default Virtual network for account " + owner + " as a part of deployVM process"); Network newNetwork = _networkMgr.createNetwork(defaultVirtualOffering.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, - null, null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account); + null, null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException("More than 1 default Virtaul networks are found for account " + owner + "; please specify networkIds"); @@ -2230,7 +2230,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (defaultVirtualOffering.get(0).getAvailability() == Availability.Optional) { s_logger.debug("Creating default Virtual network for account " + owner + " as a part of deployVM process"); Network newNetwork = _networkMgr.createNetwork(defaultVirtualOffering.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, - null, null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account); + null, null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else { throw new InvalidParameterValueException("Unable to find default networks for account " + owner); @@ -3427,7 +3427,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List virtualNetworks = _networkMgr.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated, true); if (virtualNetworks.isEmpty()) { Network newNetwork = _networkMgr.createNetwork(networkOffering, newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, - null, null, null, newAccount, false, null, physicalNetwork, zone.getId(), ACLType.Account); + null, null, null, newAccount, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException("More than 1 default Virtaul networks are found for account " + newAccount + "; please specify networkIds"); diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 2dae895b4fd..23939a28fda 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -197,7 +197,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS @Override public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean isDefault, boolean errorIfAlreadySetup, - Long domainId, ACLType aclType) throws ConcurrentOperationException { + Long domainId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { // TODO Auto-generated method stub return null; } @@ -308,7 +308,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS @Override public Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isDefault, String gateway, String cidr, String vlanId, String networkDomain, Account owner, - boolean isSecurityGroupEnabled, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType) throws ConcurrentOperationException, InsufficientCapacityException { + boolean isSecurityGroupEnabled, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException { // TODO Auto-generated method stub return null; } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 16ec19720ed..5e04bc071df 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1710,6 +1710,7 @@ CREATE TABLE `cloud`.`domain_network_ref` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `subdomain_access` int(1) unsigned COMMENT '1 if network can be accessible from the subdomain', PRIMARY KEY (`id`), CONSTRAINT `fk_domain_network_ref__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_domain_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE