| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| package com.cloud.network; | |
| import com.cloud.dc.DataCenter; | |
| import com.cloud.dc.DataCenterVO; | |
| import com.cloud.dc.VlanVO; | |
| import com.cloud.dc.dao.DataCenterDao; | |
| import com.cloud.dc.dao.VlanDao; | |
| import com.cloud.domain.DomainVO; | |
| import com.cloud.domain.dao.DomainDao; | |
| import com.cloud.exception.InvalidParameterValueException; | |
| import com.cloud.exception.PermissionDeniedException; | |
| import com.cloud.network.Network.Provider; | |
| import com.cloud.network.dao.IPAddressDao; | |
| import com.cloud.network.dao.IPAddressVO; | |
| import com.cloud.network.dao.NetworkDao; | |
| import com.cloud.network.dao.NetworkDomainDao; | |
| import com.cloud.network.dao.NetworkDomainVO; | |
| import com.cloud.network.dao.NetworkVO; | |
| import com.cloud.network.dao.PhysicalNetworkDao; | |
| import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; | |
| import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; | |
| import com.cloud.network.dao.PhysicalNetworkVO; | |
| import com.cloud.projects.dao.ProjectDao; | |
| import com.cloud.user.Account; | |
| import com.cloud.user.AccountManager; | |
| import com.cloud.user.AccountVO; | |
| import com.cloud.user.DomainManager; | |
| import com.cloud.user.dao.AccountDao; | |
| import com.cloud.utils.db.Filter; | |
| import com.cloud.utils.db.SearchBuilder; | |
| import com.cloud.utils.db.SearchCriteria; | |
| import com.cloud.utils.exception.CloudRuntimeException; | |
| import com.cloud.utils.net.Ip; | |
| import junit.framework.Assert; | |
| import org.apache.cloudstack.network.NetworkPermissionVO; | |
| import org.apache.cloudstack.network.dao.NetworkPermissionDao; | |
| import org.junit.After; | |
| import org.junit.Before; | |
| import org.junit.Test; | |
| import org.mockito.InjectMocks; | |
| import org.mockito.Mock; | |
| import org.mockito.MockitoAnnotations; | |
| import org.mockito.Spy; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Collections; | |
| import java.util.List; | |
| import java.util.Set; | |
| import static org.mockito.ArgumentMatchers.any; | |
| import static org.mockito.ArgumentMatchers.anyLong; | |
| import static org.mockito.ArgumentMatchers.eq; | |
| import static org.mockito.ArgumentMatchers.isNull; | |
| import static org.mockito.Mockito.mock; | |
| import static org.mockito.Mockito.never; | |
| import static org.mockito.Mockito.times; | |
| import static org.mockito.Mockito.verify; | |
| import static org.mockito.Mockito.when; | |
| public class NetworkModelTest { | |
| @Mock | |
| private DataCenterDao dataCenterDao; | |
| @Mock | |
| private PhysicalNetworkDao physicalNetworkDao; | |
| @Mock | |
| private PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao; | |
| @Mock | |
| private NetworkService networkService; | |
| @InjectMocks | |
| @Spy | |
| private NetworkModelImpl networkModel = new NetworkModelImpl(); | |
| @Mock | |
| private DataCenterVO zone1; | |
| @Mock | |
| private DataCenterVO zone2; | |
| @Mock | |
| private PhysicalNetworkVO physicalNetworkZone1; | |
| @Mock | |
| private PhysicalNetworkVO physicalNetworkZone2; | |
| @Mock | |
| private PhysicalNetworkServiceProviderVO providerVO; | |
| @Mock | |
| private AccountDao accountDao; | |
| @Mock | |
| private NetworkDao networkDao; | |
| @Mock | |
| private NetworkPermissionDao networkPermissionDao; | |
| @Mock | |
| private NetworkDomainDao networkDomainDao; | |
| @Mock | |
| private DomainManager domainManager; | |
| @Mock | |
| private DomainDao domainDao; | |
| @Mock | |
| private ProjectDao projectDao; | |
| @Mock | |
| private AccountManager _accountMgr; | |
| private static final long ZONE_1_ID = 1L; | |
| private static final long ZONE_2_ID = 2L; | |
| private static final long PHYSICAL_NETWORK_1_ID = 1L; | |
| private static final long PHYSICAL_NETWORK_2_ID = 2L; | |
| private static final String IPV6_CIDR = "fd59:16ba:559b:243d::/64"; | |
| private static final String IPV6_GATEWAY = "fd59:16ba:559b:243d::1"; | |
| private static final String START_IPV6 = "fd59:16ba:559b:243d:0:0:0:2"; | |
| private static final String END_IPV6 = "fd59:16ba:559b:243d:ffff:ffff:ffff:ffff"; | |
| private AutoCloseable closeable; | |
| @Before | |
| public void setUp() { | |
| closeable = MockitoAnnotations.openMocks(this); | |
| when(dataCenterDao.listEnabledZones()).thenReturn(Arrays.asList(zone1, zone2)); | |
| when(physicalNetworkDao.listByZoneAndTrafficType(ZONE_1_ID, Networks.TrafficType.Guest)). | |
| thenReturn(Collections.singletonList(physicalNetworkZone1)); | |
| when(physicalNetworkDao.listByZoneAndTrafficType(ZONE_2_ID, Networks.TrafficType.Guest)). | |
| thenReturn(Collections.singletonList(physicalNetworkZone2)); | |
| when(physicalNetworkServiceProviderDao.findByServiceProvider( | |
| PHYSICAL_NETWORK_1_ID, Network.Provider.ConfigDrive.getName())).thenReturn(null); | |
| when(physicalNetworkServiceProviderDao.findByServiceProvider( | |
| PHYSICAL_NETWORK_2_ID, Network.Provider.ConfigDrive.getName())).thenReturn(null); | |
| when(zone1.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); | |
| when(zone1.getId()).thenReturn(ZONE_1_ID); | |
| when(zone2.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); | |
| when(zone2.getId()).thenReturn(ZONE_2_ID); | |
| when(physicalNetworkZone1.getId()).thenReturn(PHYSICAL_NETWORK_1_ID); | |
| when(physicalNetworkZone2.getId()).thenReturn(PHYSICAL_NETWORK_2_ID); | |
| } | |
| @After | |
| public void tearDown() throws Exception { | |
| closeable.close(); | |
| } | |
| @Test | |
| public void testGetSourceNatIpAddressForGuestNetwork() { | |
| NetworkModelImpl modelImpl = new NetworkModelImpl(); | |
| IPAddressDao ipAddressDao = mock(IPAddressDao.class); | |
| modelImpl._ipAddressDao = ipAddressDao; | |
| List<IPAddressVO> fakeList = new ArrayList<IPAddressVO>(); | |
| IPAddressVO fakeIp = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false); | |
| fakeList.add(fakeIp); | |
| SearchBuilder<IPAddressVO> fakeSearch = mock(SearchBuilder.class); | |
| modelImpl.IpAddressSearch = fakeSearch; | |
| VlanDao fakeVlanDao = mock(VlanDao.class); | |
| when(fakeVlanDao.findById(anyLong())).thenReturn(mock(VlanVO.class)); | |
| modelImpl._vlanDao = fakeVlanDao; | |
| when(fakeSearch.create()).thenReturn(mock(SearchCriteria.class)); | |
| when(ipAddressDao.search(any(SearchCriteria.class), (Filter) isNull())).thenReturn(fakeList); | |
| when(ipAddressDao.findById(anyLong())).thenReturn(fakeIp); | |
| Account fakeAccount = mock(Account.class); | |
| when(fakeAccount.getId()).thenReturn(1L); | |
| Network fakeNetwork = mock(Network.class); | |
| when(fakeNetwork.getId()).thenReturn(1L); | |
| PublicIpAddress answer = modelImpl.getSourceNatIpAddressForGuestNetwork(fakeAccount, fakeNetwork); | |
| Assert.assertNull(answer); | |
| IPAddressVO fakeIp2 = new IPAddressVO(new Ip("76.75.75.75"), 1, 0xaabb10ddeeffL, 10, true); | |
| fakeList.add(fakeIp2); | |
| when(ipAddressDao.findById(anyLong())).thenReturn(fakeIp2); | |
| answer = modelImpl.getSourceNatIpAddressForGuestNetwork(fakeAccount, fakeNetwork); | |
| Assert.assertNotNull(answer); | |
| Assert.assertEquals(answer.getAddress().addr(), "76.75.75.75"); | |
| } | |
| @Test | |
| public void testVerifyDisabledConfigDriveEntriesOnZonesBothEnabledZones() { | |
| networkModel.verifyDisabledConfigDriveEntriesOnEnabledZones(); | |
| verify(networkModel, times(2)).addDisabledConfigDriveEntriesOnZone(any(DataCenterVO.class)); | |
| } | |
| @Test | |
| public void testVerifyDisabledConfigDriveEntriesOnZonesOneEnabledZone() { | |
| when(dataCenterDao.listEnabledZones()).thenReturn(Collections.singletonList(zone1)); | |
| networkModel.verifyDisabledConfigDriveEntriesOnEnabledZones(); | |
| verify(networkModel).addDisabledConfigDriveEntriesOnZone(any(DataCenterVO.class)); | |
| } | |
| @Test | |
| public void testVerifyDisabledConfigDriveEntriesOnZonesNoEnabledZones() { | |
| when(dataCenterDao.listEnabledZones()).thenReturn(null); | |
| networkModel.verifyDisabledConfigDriveEntriesOnEnabledZones(); | |
| verify(networkModel, never()).addDisabledConfigDriveEntriesOnZone(any(DataCenterVO.class)); | |
| } | |
| @Test | |
| public void testAddDisabledConfigDriveEntriesOnZoneBasicZone() { | |
| when(zone1.getNetworkType()).thenReturn(DataCenter.NetworkType.Basic); | |
| networkModel.addDisabledConfigDriveEntriesOnZone(zone1); | |
| verify(physicalNetworkDao, never()).listByZoneAndTrafficType(ZONE_1_ID, Networks.TrafficType.Guest); | |
| verify(networkService, never()). | |
| addProviderToPhysicalNetwork(anyLong(), eq(Provider.ConfigDrive.getName()), isNull(Long.class), isNull(List.class)); | |
| } | |
| @Test | |
| public void testAddDisabledConfigDriveEntriesOnZoneAdvancedZoneExistingConfigDrive() { | |
| when(physicalNetworkServiceProviderDao.findByServiceProvider( | |
| PHYSICAL_NETWORK_1_ID, Network.Provider.ConfigDrive.getName())).thenReturn(providerVO); | |
| networkModel.addDisabledConfigDriveEntriesOnZone(zone1); | |
| verify(networkService, never()). | |
| addProviderToPhysicalNetwork(anyLong(), eq(Provider.ConfigDrive.getName()), isNull(Long.class), isNull(List.class)); | |
| } | |
| @Test | |
| public void testAddDisabledConfigDriveEntriesOnZoneAdvancedZoneNonExistingConfigDrive() { | |
| networkModel.addDisabledConfigDriveEntriesOnZone(zone1); | |
| verify(networkService). | |
| addProviderToPhysicalNetwork(anyLong(), eq(Provider.ConfigDrive.getName()), isNull(Long.class), isNull(List.class)); | |
| } | |
| @Test | |
| public void checkIp6ParametersTestAllGood() { | |
| networkModel.checkIp6Parameters(START_IPV6, END_IPV6, IPV6_GATEWAY,IPV6_CIDR); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestCidr32() { | |
| String ipv6cidr = "fd59:16ba:559b:243d::/32"; | |
| networkModel.checkIp6CidrSizeEqualTo64(ipv6cidr); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestCidr63() { | |
| String ipv6cidr = "fd59:16ba:559b:243d::/63"; | |
| networkModel.checkIp6CidrSizeEqualTo64(ipv6cidr); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestCidr65() { | |
| String ipv6cidr = "fd59:16ba:559b:243d::/65"; | |
| networkModel.checkIp6CidrSizeEqualTo64(ipv6cidr); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestCidr120() { | |
| String ipv6cidr = "fd59:16ba:559b:243d::/120"; | |
| networkModel.checkIp6CidrSizeEqualTo64(ipv6cidr); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestNullGateway() { | |
| networkModel.checkIp6Parameters(START_IPV6, END_IPV6, null,IPV6_CIDR); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestNullCidr() { | |
| networkModel.checkIp6Parameters(START_IPV6, END_IPV6, IPV6_GATEWAY,null); | |
| } | |
| @Test(expected = InvalidParameterValueException.class) | |
| public void checkIp6ParametersTestNullCidrAndNulGateway() { | |
| networkModel.checkIp6Parameters(START_IPV6, END_IPV6, null,null); | |
| } | |
| @Test | |
| public void checkIp6ParametersTestNullStartIpv6() { | |
| networkModel.checkIp6Parameters(null, END_IPV6, IPV6_GATEWAY,IPV6_CIDR); | |
| } | |
| @Test | |
| public void checkIp6ParametersTestNullEndIpv6() { | |
| networkModel.checkIp6Parameters(START_IPV6, null, IPV6_GATEWAY,IPV6_CIDR); | |
| } | |
| @Test | |
| public void checkIp6ParametersTestNullStartAndEndIpv6() { | |
| networkModel.checkIp6Parameters(null, null, IPV6_GATEWAY,IPV6_CIDR); | |
| } | |
| @Test | |
| public void testCheckNetworkPermissions() { | |
| long accountId = 1L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(accountId); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); | |
| when(network.getAccountId()).thenReturn(accountId); | |
| when(accountDao.findById(accountId)).thenReturn(caller); | |
| when(networkDao.listBy(caller.getId(), network.getId())).thenReturn(List.of(network)); | |
| when(networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId())).thenReturn(mock(NetworkPermissionVO.class)); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test | |
| public void testCheckNetworkPermissionsForAdmin() { | |
| long accountId = 1L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(accountId); | |
| when(caller.getType()).thenReturn(Account.Type.ADMIN); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); | |
| when(network.getAccountId()).thenReturn(accountId); | |
| when(accountDao.findById(accountId)).thenReturn(caller); | |
| when(networkDao.listBy(caller.getId(), network.getId())).thenReturn(List.of(network)); | |
| when(networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId())).thenReturn(mock(NetworkPermissionVO.class)); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test(expected = CloudRuntimeException.class) | |
| public void testCheckNetworkPermissionsNullNetwork() { | |
| AccountVO caller = mock(AccountVO.class); | |
| NetworkVO network = null; | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test(expected = PermissionDeniedException.class) | |
| public void testCheckNetworkPermissionsNoOwner() { | |
| long accountId = 1L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(accountId); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); | |
| when(network.getAccountId()).thenReturn(accountId); | |
| when(accountDao.findById(accountId)).thenReturn(null); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test(expected = PermissionDeniedException.class) | |
| public void testCheckNetworkPermissionsNoPermission() { | |
| long accountId = 1L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(accountId); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); | |
| when(network.getAccountId()).thenReturn(accountId); | |
| when(accountDao.findById(accountId)).thenReturn(caller); | |
| when(networkDao.listBy(caller.getId(), network.getId())).thenReturn(null); | |
| when(networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId())).thenReturn(null); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test | |
| public void testCheckNetworkPermissionsSharedNetwork() { | |
| long id = 1L; | |
| long subDomainId = 2L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(id); | |
| when(caller.getDomainId()).thenReturn(id); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Shared); | |
| when(network.getId()).thenReturn(id); | |
| when(networkDao.findById(network.getId())).thenReturn(network); | |
| NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); | |
| when(networkDomainVO.getDomainId()).thenReturn(id); | |
| when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| when(caller.getDomainId()).thenReturn(subDomainId); | |
| networkDomainVO.subdomainAccess = Boolean.TRUE; | |
| when(domainManager.getDomainParentIds(subDomainId)).thenReturn(Set.of(id)); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test(expected = PermissionDeniedException.class) | |
| public void testCheckNetworkPermissionsSharedNetworkNoSubDomainAccess() { | |
| long id = 1L; | |
| long subDomainId = 2L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(id); | |
| when(caller.getDomainId()).thenReturn(subDomainId); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Shared); | |
| when(network.getId()).thenReturn(id); | |
| when(networkDao.findById(network.getId())).thenReturn(network); | |
| when(domainDao.findById(caller.getDomainId())).thenReturn(mock(DomainVO.class)); | |
| NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); | |
| when(networkDomainVO.getDomainId()).thenReturn(id); | |
| networkDomainVO.subdomainAccess = Boolean.FALSE; | |
| when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| @Test(expected = PermissionDeniedException.class) | |
| public void testCheckNetworkPermissionsSharedNetworkNotSubDomain() { | |
| long id = 1L; | |
| long subDomainId = 2L; | |
| AccountVO caller = mock(AccountVO.class); | |
| when(caller.getId()).thenReturn(id); | |
| when(caller.getDomainId()).thenReturn(subDomainId); | |
| when(caller.getType()).thenReturn(Account.Type.NORMAL); | |
| NetworkVO network = mock(NetworkVO.class); | |
| when(network.getGuestType()).thenReturn(Network.GuestType.Shared); | |
| when(network.getId()).thenReturn(id); | |
| when(networkDao.findById(network.getId())).thenReturn(network); | |
| when(domainDao.findById(caller.getDomainId())).thenReturn(mock(DomainVO.class)); | |
| NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); | |
| when(networkDomainVO.getDomainId()).thenReturn(id); | |
| networkDomainVO.subdomainAccess = Boolean.TRUE; | |
| when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); | |
| when(domainManager.getDomainParentIds(subDomainId)).thenReturn(Set.of(0L)); | |
| networkModel.checkNetworkPermissions(caller, network); | |
| } | |
| } |