From 981d74825a87727d7f8e397cad75877986c96d79 Mon Sep 17 00:00:00 2001 From: Ben <5091256+benj-n@users.noreply.github.com> Date: Tue, 11 Jul 2023 03:11:23 -0400 Subject: [PATCH] Add L2 networks to Zones with SG (#7719) --- .../command/user/network/CreateNetworkCmd.java | 4 ++-- .../user/network/CreateNetworkCmdTest.java | 18 +++++++++++++++++- .../orchestration/NetworkOrchestrator.java | 4 ++-- .../java/com/cloud/vm/UserVmManagerImpl.java | 6 ++++-- ui/src/views/network/CreateL2NetworkForm.vue | 2 +- ui/src/views/network/CreateNetwork.vue | 2 +- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java index 8b8ce104076..5b814e77004 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java @@ -311,10 +311,10 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd { } } if (physicalNetworkId != null) { - if (offering.getGuestType() == GuestType.Shared) { + if ((offering.getGuestType() == GuestType.Shared) || (offering.getGuestType() == GuestType.L2)) { return physicalNetworkId; } else { - throw new InvalidParameterValueException("Physical network ID can be specified for networks of guest IP type " + GuestType.Shared + " only."); + throw new InvalidParameterValueException("Physical network ID can be specified for networks of guest IP type " + GuestType.Shared + " or " + GuestType.L2 + " only."); } } else { if (zoneId == null) { diff --git a/api/src/test/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmdTest.java index bab5688ae8a..3f5b7582802 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmdTest.java @@ -251,7 +251,23 @@ public class CreateNetworkCmdTest { try { cmd.getPhysicalNetworkId(); } catch (Exception e) { - Assert.assertTrue(e.getMessage().startsWith("Physical network ID can be specified for networks of guest IP type Shared only")); + Assert.assertTrue(e.getMessage().startsWith("Physical network ID can be specified for networks of guest IP type Shared or L2 only.")); + } + } + + @Test + public void testGetPhysicalNetworkIdForL2Net() { + Long physicalNetworkId = 1L; + Long networkOfferingId = 1L; + ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId); + NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class); + ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId); + Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering); + Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.L2); + try { + Assert.assertEquals(cmd.getPhysicalNetworkId(), physicalNetworkId); + } catch (Exception e) { + Assert.fail("Failed to get physical network id"); } } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index a3714ba79fc..2f3e128bcaa 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2665,8 +2665,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } // Only Account specific Isolated network with sourceNat service disabled are allowed in security group // enabled zone - if (ntwkOff.getGuestType() != GuestType.Shared) { - throw new InvalidParameterValueException("Only shared guest network can be created in security group enabled zone"); + if ((ntwkOff.getGuestType() != GuestType.Shared) && (ntwkOff.getGuestType() != GuestType.L2)) { + throw new InvalidParameterValueException("Only shared or L2 guest network can be created in security group enabled zone"); } if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) { throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone"); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index b4e8e137984..7ec3450acb1 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -236,6 +236,7 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.kvm.dpdk.DpdkHelper; import com.cloud.network.IpAddressManager; import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.IpAddresses; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -3584,13 +3585,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir for (Long networkId : networkIdList) { NetworkVO network = _networkDao.findById(networkId); + NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); if (network == null) { throw new InvalidParameterValueException("Unable to find network by id " + networkId); } - if (!_networkModel.isSecurityGroupSupportedInNetwork(network)) { - throw new InvalidParameterValueException("Network is not security group enabled: " + network.getId()); + if (!_networkModel.isSecurityGroupSupportedInNetwork(network) && (ntwkOffering.getGuestType() != GuestType.L2)) { + throw new InvalidParameterValueException("Network is not security group enabled or not L2 network: " + network.getId()); } _accountMgr.checkAccess(owner, AccessType.UseEntry, false, network); diff --git a/ui/src/views/network/CreateL2NetworkForm.vue b/ui/src/views/network/CreateL2NetworkForm.vue index 56d34b2a6bc..b5f5763e628 100644 --- a/ui/src/views/network/CreateL2NetworkForm.vue +++ b/ui/src/views/network/CreateL2NetworkForm.vue @@ -315,7 +315,7 @@ export default { api('listZones', params).then(json => { for (const i in json.listzonesresponse.zone) { const zone = json.listzonesresponse.zone[i] - if (zone.networktype === 'Advanced' && zone.securitygroupsenabled !== true) { + if (zone.networktype === 'Advanced') { this.zones.push(zone) } } diff --git a/ui/src/views/network/CreateNetwork.vue b/ui/src/views/network/CreateNetwork.vue index 82aef814037..4ead6ba6525 100644 --- a/ui/src/views/network/CreateNetwork.vue +++ b/ui/src/views/network/CreateNetwork.vue @@ -26,7 +26,7 @@ @refresh-data="refreshParent" @refresh="handleRefresh"/> - +