This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new 26eaae78723 Allow VPC offering creation only with active VR service
offerings (#6957)
26eaae78723 is described below
commit 26eaae78723727556aec7afbdd06e97006735443
Author: Stephan Krug <[email protected]>
AuthorDate: Tue Jan 31 04:42:57 2023 -0300
Allow VPC offering creation only with active VR service offerings (#6957)
---
.../java/com/cloud/network/NetworkService.java | 3 ++
.../configuration/ConfigurationManagerImpl.java | 8 +--
.../java/com/cloud/network/NetworkServiceImpl.java | 25 +++++++++
.../java/com/cloud/network/vpc/VpcManagerImpl.java | 4 ++
.../com/cloud/network/NetworkServiceImplTest.java | 63 ++++++++++++++++++++--
.../com/cloud/network/vpc/VpcManagerImplTest.java | 5 ++
.../java/com/cloud/vpc/MockNetworkManagerImpl.java | 4 ++
7 files changed, 102 insertions(+), 10 deletions(-)
diff --git a/api/src/main/java/com/cloud/network/NetworkService.java
b/api/src/main/java/com/cloud/network/NetworkService.java
index 85e25ba7732..e329f45acfb 100644
--- a/api/src/main/java/com/cloud/network/NetworkService.java
+++ b/api/src/main/java/com/cloud/network/NetworkService.java
@@ -41,6 +41,7 @@ import
com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Network.IpAddresses;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
@@ -241,4 +242,6 @@ public interface NetworkService {
boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd
removeNetworkPermissionsCmd);
boolean resetNetworkPermissions(ResetNetworkPermissionsCmd
resetNetworkPermissionsCmd);
+
+ void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final
Long serviceOfferingId) throws InvalidParameterValueException;
}
diff --git
a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 5e684a07ad6..271f9ad17cf 100644
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -5885,13 +5885,7 @@ public class ConfigurationManagerImpl extends
ManagerBase implements Configurati
final Long serviceOfferingId = cmd.getServiceOfferingId();
if (serviceOfferingId != null) {
- final ServiceOfferingVO offering =
_serviceOfferingDao.findById(serviceOfferingId);
- if (offering == null) {
- throw new InvalidParameterValueException("Cannot find
specified service offering: " + serviceOfferingId);
- }
- if
(!VirtualMachine.Type.DomainRouter.toString().equalsIgnoreCase(offering.getSystemVmType()))
{
- throw new InvalidParameterValueException("The specified
service offering " + serviceOfferingId + " cannot be used by virtual router!");
- }
+
_networkSvc.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(serviceOfferingId);
}
// configure service provider map
diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
index adfde495d3e..c868144a306 100644
--- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -41,6 +41,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.service.dao.ServiceOfferingDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.alert.AlertService;
@@ -247,6 +249,7 @@ import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.googlecode.ipv6.IPv6Address;
+import com.cloud.service.ServiceOfferingVO;
/**
* NetworkServiceImpl implements NetworkService.
@@ -395,6 +398,8 @@ public class NetworkServiceImpl extends ManagerBase
implements NetworkService, C
CommandSetupHelper commandSetupHelper;
@Inject
AgentManager agentManager;
+ @Inject
+ ServiceOfferingDao serviceOfferingDao;
@Autowired
@Qualifier("networkHelper")
@@ -4136,6 +4141,26 @@ public class NetworkServiceImpl extends ManagerBase
implements NetworkService, C
}
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long
serviceOfferingId) {
+ s_logger.debug(String.format("Validating if service offering [%s] is
active, and if system VM is of Domain Router type.", serviceOfferingId));
+ final ServiceOfferingVO serviceOffering =
serviceOfferingDao.findById(serviceOfferingId);
+
+ if (serviceOffering == null) {
+ throw new InvalidParameterValueException(String.format("Could not
find specified service offering [%s].", serviceOfferingId));
+ }
+
+ if (serviceOffering.getState() == ServiceOffering.State.Inactive) {
+ throw new InvalidParameterValueException(String.format("The
specified service offering [%s] is inactive.", serviceOffering));
+ }
+
+ final String virtualMachineDomainRouterType =
VirtualMachine.Type.DomainRouter.toString();
+ if
(!virtualMachineDomainRouterType.equalsIgnoreCase(serviceOffering.getSystemVmType()))
{
+ throw new InvalidParameterValueException(String.format("The
specified service offering [%s] is of type [%s]. Virtual routers can only be
created with service offering "
+ + "of type [%s].", serviceOffering,
serviceOffering.getSystemVmType(),
virtualMachineDomainRouterType.toLowerCase()));
+ }
+ }
+
+
public String generateVnetString(List<String> vnetList) {
Collections.sort(vnetList, new Comparator<String>() {
@Override
diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
index 30c4aa367f8..9222520602f 100644
--- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
@@ -438,6 +438,10 @@ public class VpcManagerImpl extends ManagerBase implements
VpcManager, VpcProvis
}
}
+ if (serviceOfferingId != null) {
+
_ntwkSvc.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(serviceOfferingId);
+ }
+
return createVpcOffering(vpcOfferingName, displayText,
supportedServices,
serviceProviderList, serviceCapabilityList, internetProtocol,
serviceOfferingId,
domainIds, zoneIds, (enable ? State.Enabled : State.Disabled));
diff --git a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
index 1dfecd9680d..fcf7ad3665a 100644
--- a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
+++ b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doReturn;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -61,7 +62,6 @@ import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
@@ -96,7 +96,10 @@ import com.cloud.vm.NicVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
-
+import com.cloud.offering.ServiceOffering;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.exception.InvalidParameterValueException;
@PowerMockIgnore("javax.management.*")
@RunWith(PowerMockRunner.class)
@@ -154,6 +157,10 @@ public class NetworkServiceImplTest {
AccountService accountService;
@Mock
NetworkHelper networkHelper;
+ @Mock
+ ServiceOfferingDao serviceOfferingDaoMock;
+ @Mock
+ ServiceOfferingVO serviceOfferingVoMock;
@InjectMocks
AccountManagerImpl accountManagerImpl;
@@ -171,7 +178,8 @@ public class NetworkServiceImplTest {
@Mock
private Account accountMock;
@InjectMocks
- private NetworkServiceImpl service = new NetworkServiceImpl();
+ NetworkServiceImpl service = new NetworkServiceImpl();
+
private static final String VLAN_ID_900 = "900";
private static final String VLAN_ID_901 = "901";
private static final String VLAN_ID_902 = "902";
@@ -200,6 +208,8 @@ public class NetworkServiceImplTest {
CallContext.register(user, account);
}
+ Class<InvalidParameterValueException> expectedException =
InvalidParameterValueException.class;
+
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -241,6 +251,7 @@ public class NetworkServiceImplTest {
Mockito.lenient().doNothing().when(accountMgr).checkAccess(accountMock,
networkOffering, dc);
Mockito.when(accountMgr.isRootAdmin(accountMock.getId())).thenReturn(true);
}
+
@Test
public void testGetPrivateVlanPairNoVlans() {
Pair<String, Network.PVlanType> pair =
service.getPrivateVlanPair(null, null, null);
@@ -713,4 +724,50 @@ public class NetworkServiceImplTest {
Assert.assertNull(networkVO.getIp6Dns1());
Assert.assertNull(networkVO.getIp6Dns2());
}
+ @Test
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenServiceOfferingIsNull()
{
+ doReturn(null).when(serviceOfferingDaoMock).findById(anyLong());
+
+ String expectedMessage = String.format("Could not find specified
service offering [%s].", 1l);
+ InvalidParameterValueException assertThrows =
Assert.assertThrows(expectedException, () -> {
+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
+ });
+
+ Assert.assertEquals(expectedMessage, assertThrows.getMessage());
+ }
+
+ @Test
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenServiceOfferingStateIsInactive()
{
+
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
+
doReturn(ServiceOffering.State.Inactive).when(serviceOfferingVoMock).getState();
+
+ String expectedMessage = String.format("The specified service offering
[%s] is inactive.", serviceOfferingVoMock);
+ InvalidParameterValueException assertThrows =
Assert.assertThrows(expectedException, () -> {
+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
+ });
+
+ Assert.assertEquals(expectedMessage, assertThrows.getMessage());
+ }
+
+ @Test
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenSystemVmTypeIsNotDomainRouter()
{
+
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
+
doReturn(ServiceOffering.State.Active).when(serviceOfferingVoMock).getState();
+
doReturn(VirtualMachine.Type.ElasticLoadBalancerVm.toString()).when(serviceOfferingVoMock).getSystemVmType();
+
+ String expectedMessage = String.format("The specified service offering
[%s] is of type [%s]. Virtual routers can only be created with service offering
of type [%s].",
+ serviceOfferingVoMock,
serviceOfferingVoMock.getSystemVmType(),
VirtualMachine.Type.DomainRouter.toString().toLowerCase());
+ InvalidParameterValueException assertThrows =
Assert.assertThrows(expectedException, () -> {
+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
+ });
+
+ Assert.assertEquals(expectedMessage, assertThrows.getMessage());
+ }
+
+ @Test
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustNotThrowInvalidParameterValueExceptionWhenSystemVmTypeIsDomainRouter()
{
+ NetworkServiceImpl networkServiceImplMock =
mock(NetworkServiceImpl.class);
+
+
networkServiceImplMock.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
+ }
}
diff --git a/server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
b/server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
index 03d4c1659b3..c820026309d 100644
--- a/server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
+++ b/server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
@@ -41,6 +41,7 @@ import java.util.UUID;
import com.cloud.alert.AlertManager;
+import com.cloud.network.NetworkService;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.context.CallContext;
@@ -146,6 +147,8 @@ public class VpcManagerImplTest {
NicDao nicDao;
@Mock
AlertManager alertManager;
+ @Mock
+ NetworkService networkServiceMock;
public static final long ACCOUNT_ID = 1;
private AccountVO account;
@@ -196,6 +199,7 @@ public class VpcManagerImplTest {
manager._resourceLimitMgr = resourceLimitService;
manager._vpcOffDao = vpcOfferingDao;
manager._dcDao = dataCenterDao;
+ manager._ntwkSvc = networkServiceMock;
CallContext.register(Mockito.mock(User.class),
Mockito.mock(Account.class));
registerCallContext();
}
@@ -418,6 +422,7 @@ public class VpcManagerImplTest {
public void testDisabledConfigCreateIpv6VpcOffering() {
CreateVPCOfferingCmd cmd = Mockito.mock(CreateVPCOfferingCmd.class);
Mockito.when(cmd.getInternetProtocol()).thenReturn(NetUtils.InternetProtocol.DualStack.toString());
+
Mockito.doNothing().when(networkServiceMock).validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(Mockito.any());
manager.createVpcOffering(cmd);
}
diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
index c7cf7ecf3e5..bd0c73f54cb 100644
--- a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -1050,4 +1050,8 @@ public class MockNetworkManagerImpl extends ManagerBase
implements NetworkOrches
public boolean resetNetworkPermissions(ResetNetworkPermissionsCmd
resetNetworkPermissionsCmd) {
return false;
}
+
+ @Override
+ public void
validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long
serviceOfferingId) {
+ }
}