From dfcbd2e97728ee8cbc2f16e9cbd4848e0529e637 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 14 Oct 2025 12:36:53 +0530 Subject: [PATCH] server: consistent behaviour for list apis with project=-1 (#11767) Signed-off-by: Abhishek Kumar --- .../com/cloud/network/NetworkServiceImpl.java | 19 +++++++++--- .../cloud/network/NetworkServiceImplTest.java | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 04e66d6e1b0..58c56134560 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -2563,7 +2563,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } 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); @@ -2623,7 +2623,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C 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; } @@ -2642,7 +2642,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } else { accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); } - addProjectNetworksConditionToSearch(accountSC, skipProjectNetworks); + addProjectNetworksConditionToSearch(accountSC, skipProjectNetworks, projectId); additionalSC.addOr("id", SearchCriteria.Op.SC, accountSC); } @@ -2823,8 +2823,17 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } } - 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) { + addProjectNetworksConditionToSearch(sc, skipProjectNetworks, null); + } + + 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")); } diff --git a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java index 2189b451761..51b2dad3dec 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.user.dao.UserDao; 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 class NetworkServiceImplTest { 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); + } }