diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 8c86ed55df8f..5bc8f2e71868 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -2557,12 +2557,12 @@ public Pair, Integer> searchForNetworks(ListNetworksCmd SearchCriteria sc = createNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, null, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId); - addProjectNetworksConditionToSearch(sc, true); + addProjectNetworksConditionToSearch(sc, true, null); result = _networksDao.searchAndCount(sc, searchFilter); } else { SearchCriteria additionalSC = _networksDao.createSearchCriteria(); - addAccountSpecificNetworksToSearch(additionalSC, sb, networkFilter, skipProjectNetworks, permittedAccounts, path, isRecursive); + addAccountSpecificNetworksToSearch(additionalSC, sb, networkFilter, skipProjectNetworks, permittedAccounts, path, isRecursive, projectId); addDomainSpecificNetworksToSearch(additionalSC, sb, networkFilter, permittedAccounts, domainId, path, isRecursive); addSharedNetworksToSearch(additionalSC, sb, networkFilter, permittedAccounts, path, isRecursive); @@ -2622,7 +2622,7 @@ public Pair, Integer> searchForNetworks(ListNetworksCmd private void addAccountSpecificNetworksToSearch(SearchCriteria additionalSC, SearchBuilder sb, Network.NetworkFilter networkFilter, boolean skipProjectNetworks, - List permittedAccounts, String path, boolean isRecursive) { + List permittedAccounts, String path, boolean isRecursive, Long projectId) { if (!Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { return; } @@ -2641,7 +2641,7 @@ private void addAccountSpecificNetworksToSearch(SearchCriteria additi } else { accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); } - addProjectNetworksConditionToSearch(accountSC, skipProjectNetworks); + addProjectNetworksConditionToSearch(accountSC, skipProjectNetworks, projectId); additionalSC.addOr("id", SearchCriteria.Op.SC, accountSC); } @@ -2785,7 +2785,7 @@ private void addDomainLevelNetworksToSearch(SearchCriteria additional SearchCriteria domainSC = sb.create(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - addProjectNetworksConditionToSearch(domainSC, true); + addProjectNetworksConditionToSearch(domainSC, true, null); additionalSC.addOr("id", SearchCriteria.Op.SC, domainSC); } } @@ -2813,13 +2813,17 @@ private void addDomainNetworksByDomainPathToSearch(SearchCriteria add SearchCriteria domainSC = sb.create(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - addProjectNetworksConditionToSearch(domainSC, true); + addProjectNetworksConditionToSearch(domainSC, true, null); additionalSC.addOr("id", SearchCriteria.Op.SC, domainSC); } } - private void addProjectNetworksConditionToSearch(SearchCriteria sc, boolean skipProjectNetworks) { - sc.getJoin("account").addAnd("type", skipProjectNetworks ? Op.NEQ : Op.EQ, Account.Type.PROJECT); + protected void addProjectNetworksConditionToSearch(SearchCriteria sc, boolean skipProjectNetworks, Long projectId) { + if (!skipProjectNetworks && projectId == -1) { + sc.getJoin("account").addAnd("type", Op.NNULL); + } else { + sc.getJoin("account").addAnd("type", skipProjectNetworks ? Op.NEQ : Op.EQ, Account.Type.PROJECT); + } sc.addAnd("id", Op.SC, sc.getJoin("account")); } @@ -2829,7 +2833,7 @@ private void addSharedNetworksByAccountsToSearch(SearchCriteria addit if (!sharedNetworkIds.isEmpty()) { SearchCriteria ssc = sb.create(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - addProjectNetworksConditionToSearch(ssc, true); + addProjectNetworksConditionToSearch(ssc, true, null); additionalSC.addOr("id", SearchCriteria.Op.SC, ssc); } } @@ -2859,7 +2863,7 @@ private void addSharedNetworksByDomainPathToSearch(SearchCriteria add if (!sharedNetworkIds.isEmpty()) { SearchCriteria ssc = sb.create(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - addProjectNetworksConditionToSearch(ssc, true); + addProjectNetworksConditionToSearch(ssc, true, null); additionalSC.addOr("id", SearchCriteria.Op.SC, ssc); } } diff --git a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java index 2189b4517614..51b2dad3decd 100644 --- a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java +++ b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java @@ -114,6 +114,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.db.EntityManager; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.vm.DomainRouterVO; @@ -1299,4 +1300,34 @@ public void testGetIpAddressesFromIps() { Assert.assertEquals("Mac address is not valid: invalid-mac", e.getMessage()); } } + + @Test + public void addProjectNetworksConditionToSearch_includesProjectNetworksWhenNotSkipped() { + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + SearchCriteria accountJoin = Mockito.mock(SearchCriteria.class); + Mockito.when(sc.getJoin("account")).thenReturn(accountJoin); + service.addProjectNetworksConditionToSearch(sc, false, -1L); + Mockito.verify(accountJoin).addAnd("type", SearchCriteria.Op.NNULL); + Mockito.verify(sc).addAnd("id", SearchCriteria.Op.SC, accountJoin); + } + + @Test + public void addProjectNetworksConditionToSearch_excludesProjectNetworksWhenSkipped() { + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + SearchCriteria accountJoin = Mockito.mock(SearchCriteria.class); + Mockito.when(sc.getJoin("account")).thenReturn(accountJoin); + service.addProjectNetworksConditionToSearch(sc, true, -1L); + Mockito.verify(accountJoin).addAnd("type", SearchCriteria.Op.NEQ, Account.Type.PROJECT); + Mockito.verify(sc).addAnd("id", SearchCriteria.Op.SC, accountJoin); + } + + @Test + public void addProjectNetworksConditionToSearch_includesSpecificProjectWhenProjectIdProvided() { + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + SearchCriteria accountJoin = Mockito.mock(SearchCriteria.class); + Mockito.when(sc.getJoin("account")).thenReturn(accountJoin); + service.addProjectNetworksConditionToSearch(sc, false, 123L); + Mockito.verify(accountJoin).addAnd("type", SearchCriteria.Op.EQ, Account.Type.PROJECT); + Mockito.verify(sc).addAnd("id", SearchCriteria.Op.SC, accountJoin); + } }