NSX: Prevent creation of L2 and Shared networks for NSX (#8463)

* NSX: Prevent creation of L2 and Shared networks for NSX

* add checks to backend to prevent creation of l2 and shared networks in nsx zones and filter only nsx offerings when creating isolated networks

* cleanup
This commit is contained in:
Pearl Dsilva 2024-01-08 15:50:21 -05:00 committed by GitHub
parent 886c071a6c
commit ecc2c8148d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 5 deletions

View File

@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@ -43,7 +44,9 @@ import javax.naming.ConfigurationException;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.network.dao.NsxProviderDao;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.element.NsxProviderVO;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.dao.ServiceOfferingDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
@ -410,6 +413,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
ServiceOfferingDao serviceOfferingDao;
@Inject
PublicIpQuarantineDao publicIpQuarantineDao;
@Inject
NsxProviderDao nsxProviderDao;
@Autowired
@Qualifier("networkHelper")
@ -1472,6 +1477,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
_accountMgr.checkAccess(owner, ntwkOff, zone);
validateZoneAvailability(caller, zone);
validateNetworkCreationSupported(zone.getId(), zone.getName(), ntwkOff.getGuestType());
ACLType aclType = getAclType(caller, cmd.getAclType(), ntwkOff);
@ -1728,6 +1734,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return network;
}
private void validateNetworkCreationSupported(long zoneId, String zoneName, GuestType guestType) {
NsxProviderVO nsxProviderVO = nsxProviderDao.findByZoneId(zoneId);
if (Objects.nonNull(nsxProviderVO) && List.of(GuestType.L2, GuestType.Shared).contains(guestType)) {
throw new InvalidParameterValueException(
String.format("Creation of %s networks is not supported in NSX enabled zone %s", guestType.name(), zoneName)
);
}
}
void checkAndSetRouterSourceNatIp(Account owner, CreateNetworkCmd cmd, Network network) throws InsufficientAddressCapacityException, ResourceAllocationException {
String sourceNatIp = cmd.getSourceNatIP();
if (sourceNatIp == null) {

View File

@ -40,6 +40,7 @@ import java.util.UUID;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.network.dao.NsxProviderDao;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.user.dao.AccountDao;
@ -212,6 +213,8 @@ public class NetworkServiceImplTest {
@Mock
private Ip ipMock;
@Mock
private NsxProviderDao nsxProviderDao;
private static Date beforeDate;
@ -295,6 +298,7 @@ public class NetworkServiceImplTest {
service.commandSetupHelper = commandSetupHelper;
service.networkHelper = networkHelper;
service._ipAddrMgr = ipAddressManagerMock;
service.nsxProviderDao = nsxProviderDao;
callContextMocked = Mockito.mockStatic(CallContext.class);
CallContext callContextMock = Mockito.mock(CallContext.class);
callContextMocked.when(CallContext::current).thenReturn(callContextMock);

View File

@ -2969,6 +2969,7 @@
"message.kubernetes.cluster.stop": "Please confirm that you want to stop the cluster.",
"message.kubernetes.cluster.upgrade": "Please select new Kubernetes version.",
"message.kubernetes.version.delete": "Please confirm that you want to delete this Kubernetes version.",
"message.l2.network.unsupported.for.nsx": "L2 networks aren't supported for NSX enabled zones",
"message.launch.zone": "Zone is ready to launch; please proceed to the next step.",
"message.launch.zone.description": "Zone is ready to launch; please proceed to the next step.",
"message.launch.zone.hint": "Configure Network components and traffic including IP addresses.",
@ -3116,6 +3117,7 @@
"message.setup.physical.network.during.zone.creation": "When adding a zone, you need to set up one or more physical Networks. Each Network corresponds to a NIC on the hypervisor. Each physical Network can carry one or more types of traffic, with certain restrictions on how they may be combined. Add or remove one or more traffic types onto each physical Network.",
"message.setup.physical.network.during.zone.creation.basic": "When adding a basic zone, you can set up one physical Network, which corresponds to a NIC on the hypervisor. The Network carries several types of traffic.<br/><br/>You may also <strong>add</strong> other traffic types onto the physical Network.",
"message.shared.network.offering.warning": "Domain admins and regular Users can only create shared Networks from Network offering with the setting specifyvlan=false. Please contact an administrator to create a Network offering if this list is empty.",
"message.shared.network.unsupported.for.nsx": "Shared networks aren't supported for NSX enabled zones",
"message.shutdown.triggered": "A shutdown has been triggered. CloudStack will not accept new jobs",
"message.snapshot.additional.zones": "Snapshots will always be created in its native zone - %x, here you can select additional zone(s) where it will be copied to at creation time",
"message.sourcenatip.change.warning": "WARNING: Changing the sourcenat IP address of the network will cause connectivity downtime for the Instances with NICs in the Network.",

View File

@ -573,6 +573,9 @@ export default {
this.selectedNetworkOffering = {}
api('listNetworkOfferings', params).then(json => {
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
if (this.selectedZone.isnsxenabled) {
this.networkOfferings = this.networkOfferings.filter(offering => offering.fornsx)
}
}).catch(error => {
this.$notifyError(error)
}).finally(() => {

View File

@ -18,7 +18,14 @@
<template>
<a-spin :spinning="loading">
<div class="form-layout" v-ctrl-enter="handleSubmit">
<div class="form">
<div v-if="isNsxEnabled">
<a-alert type="warning">
<template #message>
<span v-html="$t('message.l2.network.unsupported.for.nsx')" />
</template>
</a-alert>
</div>
<div v-else class="form">
<a-form
:ref="formRef"
:model="form"
@ -248,7 +255,8 @@ export default {
networkOfferings: [],
networkOfferingLoading: false,
selectedNetworkOffering: {},
isolatePvlanType: 'none'
isolatePvlanType: 'none',
isNsxEnabled: false
}
},
watch: {
@ -328,6 +336,7 @@ export default {
},
handleZoneChange (zone) {
this.selectedZone = zone
this.isNsxEnabled = zone?.isnsxenabled || false
this.updateVPCCheckAndFetchNetworkOfferingData()
},
fetchDomainData () {

View File

@ -106,7 +106,6 @@ export default {
fetchActionZoneData () {
this.loading = true
const params = {}
console.log(this.resource)
if (this.$route.name === 'deployVirtualMachine' && this.resource.zoneid) {
params.id = this.resource.zoneid
}

View File

@ -18,7 +18,14 @@
<template>
<a-spin :spinning="loading">
<div class="form-layout" v-ctrl-enter="handleSubmit">
<div class="form">
<div v-if="isNsxEnabled">
<a-alert type="warning">
<template #message>
<span v-html="$t('message.shared.network.unsupported.for.nsx')" />
</template>
</a-alert>
</div>
<div v-else class="form">
<a-form
:ref="formRef"
:model="form"
@ -546,7 +553,8 @@ export default {
minMTU: 68,
setMTU: false,
errorPublicMtu: '',
errorPrivateMtu: ''
errorPrivateMtu: '',
isNsxEnabled: false
}
},
watch: {
@ -665,6 +673,7 @@ export default {
this.setMTU = zone?.allowuserspecifyvrmtu || false
this.privateMtuMax = zone?.routerprivateinterfacemaxmtu || 1500
this.publicMtuMax = zone?.routerpublicinterfacemaxmtu || 1500
this.isNsxEnabled = zone?.isnsxenabled || false
if (isAdmin()) {
this.fetchPhysicalNetworkData()
} else {