diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
index 1b634d5b904..9bdb3305a9c 100644
--- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -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) {
diff --git a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
index c993f7b7095..f2ab2a08ae7 100644
--- a/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
+++ b/server/src/test/java/com/cloud/network/NetworkServiceImplTest.java
@@ -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);
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index be035adc4ba..d6559243f71 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -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.
You may also add 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.",
diff --git a/ui/src/views/network/CreateIsolatedNetworkForm.vue b/ui/src/views/network/CreateIsolatedNetworkForm.vue
index 8336277a702..437630e10ea 100644
--- a/ui/src/views/network/CreateIsolatedNetworkForm.vue
+++ b/ui/src/views/network/CreateIsolatedNetworkForm.vue
@@ -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(() => {
diff --git a/ui/src/views/network/CreateL2NetworkForm.vue b/ui/src/views/network/CreateL2NetworkForm.vue
index 76695eb625f..6bb87e178f3 100644
--- a/ui/src/views/network/CreateL2NetworkForm.vue
+++ b/ui/src/views/network/CreateL2NetworkForm.vue
@@ -18,7 +18,14 @@