Skip to content

Commit 26eaae7

Browse files
Allow VPC offering creation only with active VR service offerings (#6957)
1 parent 83c2bfa commit 26eaae7

File tree

7 files changed

+102
-10
lines changed

7 files changed

+102
-10
lines changed

api/src/main/java/com/cloud/network/NetworkService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.cloud.exception.InsufficientCapacityException;
4242
import com.cloud.exception.ResourceAllocationException;
4343
import com.cloud.exception.ResourceUnavailableException;
44+
import com.cloud.exception.InvalidParameterValueException;
4445
import com.cloud.network.Network.IpAddresses;
4546
import com.cloud.network.Network.Service;
4647
import com.cloud.network.Networks.TrafficType;
@@ -241,4 +242,6 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
241242
boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd removeNetworkPermissionsCmd);
242243

243244
boolean resetNetworkPermissions(ResetNetworkPermissionsCmd resetNetworkPermissionsCmd);
245+
246+
void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long serviceOfferingId) throws InvalidParameterValueException;
244247
}

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5885,13 +5885,7 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd)
58855885
final Long serviceOfferingId = cmd.getServiceOfferingId();
58865886

58875887
if (serviceOfferingId != null) {
5888-
final ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOfferingId);
5889-
if (offering == null) {
5890-
throw new InvalidParameterValueException("Cannot find specified service offering: " + serviceOfferingId);
5891-
}
5892-
if (!VirtualMachine.Type.DomainRouter.toString().equalsIgnoreCase(offering.getSystemVmType())) {
5893-
throw new InvalidParameterValueException("The specified service offering " + serviceOfferingId + " cannot be used by virtual router!");
5894-
}
5888+
_networkSvc.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(serviceOfferingId);
58955889
}
58965890

58975891
// configure service provider map

server/src/main/java/com/cloud/network/NetworkServiceImpl.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import javax.inject.Inject;
4242
import javax.naming.ConfigurationException;
4343

44+
import com.cloud.offering.ServiceOffering;
45+
import com.cloud.service.dao.ServiceOfferingDao;
4446
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
4547
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
4648
import org.apache.cloudstack.alert.AlertService;
@@ -247,6 +249,7 @@
247249
import com.cloud.vm.dao.UserVmDao;
248250
import com.cloud.vm.dao.VMInstanceDao;
249251
import com.googlecode.ipv6.IPv6Address;
252+
import com.cloud.service.ServiceOfferingVO;
250253

251254
/**
252255
* NetworkServiceImpl implements NetworkService.
@@ -395,6 +398,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
395398
CommandSetupHelper commandSetupHelper;
396399
@Inject
397400
AgentManager agentManager;
401+
@Inject
402+
ServiceOfferingDao serviceOfferingDao;
398403

399404
@Autowired
400405
@Qualifier("networkHelper")
@@ -4136,6 +4141,26 @@ private List<Pair<Integer, Integer>> validateVlanRange(PhysicalNetworkVO network
41364141

41374142
}
41384143

4144+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long serviceOfferingId) {
4145+
s_logger.debug(String.format("Validating if service offering [%s] is active, and if system VM is of Domain Router type.", serviceOfferingId));
4146+
final ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(serviceOfferingId);
4147+
4148+
if (serviceOffering == null) {
4149+
throw new InvalidParameterValueException(String.format("Could not find specified service offering [%s].", serviceOfferingId));
4150+
}
4151+
4152+
if (serviceOffering.getState() == ServiceOffering.State.Inactive) {
4153+
throw new InvalidParameterValueException(String.format("The specified service offering [%s] is inactive.", serviceOffering));
4154+
}
4155+
4156+
final String virtualMachineDomainRouterType = VirtualMachine.Type.DomainRouter.toString();
4157+
if (!virtualMachineDomainRouterType.equalsIgnoreCase(serviceOffering.getSystemVmType())) {
4158+
throw new InvalidParameterValueException(String.format("The specified service offering [%s] is of type [%s]. Virtual routers can only be created with service offering "
4159+
+ "of type [%s].", serviceOffering, serviceOffering.getSystemVmType(), virtualMachineDomainRouterType.toLowerCase()));
4160+
}
4161+
}
4162+
4163+
41394164
public String generateVnetString(List<String> vnetList) {
41404165
Collections.sort(vnetList, new Comparator<String>() {
41414166
@Override

server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,10 @@ public VpcOffering createVpcOffering(CreateVPCOfferingCmd cmd) {
438438
}
439439
}
440440

441+
if (serviceOfferingId != null) {
442+
_ntwkSvc.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(serviceOfferingId);
443+
}
444+
441445
return createVpcOffering(vpcOfferingName, displayText, supportedServices,
442446
serviceProviderList, serviceCapabilityList, internetProtocol, serviceOfferingId,
443447
domainIds, zoneIds, (enable ? State.Enabled : State.Disabled));

server/src/test/java/com/cloud/network/NetworkServiceImplTest.java

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.mockito.Mockito.mock;
2525
import static org.mockito.Mockito.times;
2626
import static org.mockito.Mockito.when;
27+
import static org.mockito.Mockito.doReturn;
2728

2829
import java.lang.reflect.Field;
2930
import java.lang.reflect.Modifier;
@@ -61,7 +62,6 @@
6162
import com.cloud.dc.DataCenterVO;
6263
import com.cloud.dc.dao.DataCenterDao;
6364
import com.cloud.exception.InsufficientCapacityException;
64-
import com.cloud.exception.InvalidParameterValueException;
6565
import com.cloud.exception.ResourceAllocationException;
6666
import com.cloud.network.dao.IPAddressDao;
6767
import com.cloud.network.dao.IPAddressVO;
@@ -96,7 +96,10 @@
9696
import com.cloud.vm.VirtualMachine;
9797
import com.cloud.vm.dao.DomainRouterDao;
9898
import com.cloud.vm.dao.NicDao;
99-
99+
import com.cloud.offering.ServiceOffering;
100+
import com.cloud.service.ServiceOfferingVO;
101+
import com.cloud.service.dao.ServiceOfferingDao;
102+
import com.cloud.exception.InvalidParameterValueException;
100103

101104
@PowerMockIgnore("javax.management.*")
102105
@RunWith(PowerMockRunner.class)
@@ -154,6 +157,10 @@ public class NetworkServiceImplTest {
154157
AccountService accountService;
155158
@Mock
156159
NetworkHelper networkHelper;
160+
@Mock
161+
ServiceOfferingDao serviceOfferingDaoMock;
162+
@Mock
163+
ServiceOfferingVO serviceOfferingVoMock;
157164

158165
@InjectMocks
159166
AccountManagerImpl accountManagerImpl;
@@ -171,7 +178,8 @@ public class NetworkServiceImplTest {
171178
@Mock
172179
private Account accountMock;
173180
@InjectMocks
174-
private NetworkServiceImpl service = new NetworkServiceImpl();
181+
NetworkServiceImpl service = new NetworkServiceImpl();
182+
175183
private static final String VLAN_ID_900 = "900";
176184
private static final String VLAN_ID_901 = "901";
177185
private static final String VLAN_ID_902 = "902";
@@ -200,6 +208,8 @@ private void registerCallContext() {
200208
CallContext.register(user, account);
201209
}
202210

211+
Class<InvalidParameterValueException> expectedException = InvalidParameterValueException.class;
212+
203213
@Before
204214
public void setup() throws Exception {
205215
MockitoAnnotations.initMocks(this);
@@ -241,6 +251,7 @@ public void setup() throws Exception {
241251
Mockito.lenient().doNothing().when(accountMgr).checkAccess(accountMock, networkOffering, dc);
242252
Mockito.when(accountMgr.isRootAdmin(accountMock.getId())).thenReturn(true);
243253
}
254+
244255
@Test
245256
public void testGetPrivateVlanPairNoVlans() {
246257
Pair<String, Network.PVlanType> pair = service.getPrivateVlanPair(null, null, null);
@@ -713,4 +724,50 @@ public void testCheckAndUpdateNetworkResetSuccess() {
713724
Assert.assertNull(networkVO.getIp6Dns1());
714725
Assert.assertNull(networkVO.getIp6Dns2());
715726
}
727+
@Test
728+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenServiceOfferingIsNull() {
729+
doReturn(null).when(serviceOfferingDaoMock).findById(anyLong());
730+
731+
String expectedMessage = String.format("Could not find specified service offering [%s].", 1l);
732+
InvalidParameterValueException assertThrows = Assert.assertThrows(expectedException, () -> {
733+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
734+
});
735+
736+
Assert.assertEquals(expectedMessage, assertThrows.getMessage());
737+
}
738+
739+
@Test
740+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenServiceOfferingStateIsInactive() {
741+
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
742+
doReturn(ServiceOffering.State.Inactive).when(serviceOfferingVoMock).getState();
743+
744+
String expectedMessage = String.format("The specified service offering [%s] is inactive.", serviceOfferingVoMock);
745+
InvalidParameterValueException assertThrows = Assert.assertThrows(expectedException, () -> {
746+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
747+
});
748+
749+
Assert.assertEquals(expectedMessage, assertThrows.getMessage());
750+
}
751+
752+
@Test
753+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustThrowInvalidParameterValueExceptionWhenSystemVmTypeIsNotDomainRouter() {
754+
doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findById(anyLong());
755+
doReturn(ServiceOffering.State.Active).when(serviceOfferingVoMock).getState();
756+
doReturn(VirtualMachine.Type.ElasticLoadBalancerVm.toString()).when(serviceOfferingVoMock).getSystemVmType();
757+
758+
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].",
759+
serviceOfferingVoMock, serviceOfferingVoMock.getSystemVmType(), VirtualMachine.Type.DomainRouter.toString().toLowerCase());
760+
InvalidParameterValueException assertThrows = Assert.assertThrows(expectedException, () -> {
761+
service.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
762+
});
763+
764+
Assert.assertEquals(expectedMessage, assertThrows.getMessage());
765+
}
766+
767+
@Test
768+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouterTestMustNotThrowInvalidParameterValueExceptionWhenSystemVmTypeIsDomainRouter() {
769+
NetworkServiceImpl networkServiceImplMock = mock(NetworkServiceImpl.class);
770+
771+
networkServiceImplMock.validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(1l);
772+
}
716773
}

server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242

4343
import com.cloud.alert.AlertManager;
44+
import com.cloud.network.NetworkService;
4445
import org.apache.cloudstack.acl.SecurityChecker;
4546
import org.apache.cloudstack.alert.AlertService;
4647
import org.apache.cloudstack.context.CallContext;
@@ -146,6 +147,8 @@ public class VpcManagerImplTest {
146147
NicDao nicDao;
147148
@Mock
148149
AlertManager alertManager;
150+
@Mock
151+
NetworkService networkServiceMock;
149152

150153
public static final long ACCOUNT_ID = 1;
151154
private AccountVO account;
@@ -196,6 +199,7 @@ public void setup()
196199
manager._resourceLimitMgr = resourceLimitService;
197200
manager._vpcOffDao = vpcOfferingDao;
198201
manager._dcDao = dataCenterDao;
202+
manager._ntwkSvc = networkServiceMock;
199203
CallContext.register(Mockito.mock(User.class), Mockito.mock(Account.class));
200204
registerCallContext();
201205
}
@@ -418,6 +422,7 @@ public void testUpdatePublicMtuToGreaterThanThreshold() {
418422
public void testDisabledConfigCreateIpv6VpcOffering() {
419423
CreateVPCOfferingCmd cmd = Mockito.mock(CreateVPCOfferingCmd.class);
420424
Mockito.when(cmd.getInternetProtocol()).thenReturn(NetUtils.InternetProtocol.DualStack.toString());
425+
Mockito.doNothing().when(networkServiceMock).validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(Mockito.any());
421426
manager.createVpcOffering(cmd);
422427
}
423428

server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,4 +1050,8 @@ public boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd removeNetwor
10501050
public boolean resetNetworkPermissions(ResetNetworkPermissionsCmd resetNetworkPermissionsCmd) {
10511051
return false;
10521052
}
1053+
1054+
@Override
1055+
public void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long serviceOfferingId) {
1056+
}
10531057
}

0 commit comments

Comments
 (0)