diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 6575da47364b..c264e483981a 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -5861,10 +5861,8 @@ public Network createPrivateNetwork(final String networkName, final String displ if (broadcastUriString != null) { URI uri = BroadcastDomainType.fromString(broadcastUriString); uriString = uri.toString(); - BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri); - // numeric vlan or vlan URI are ok for now - // TODO make a test for any supported scheme - if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) { + BroadcastDomainType type = BroadcastDomainType.getSchemeValue(uri); + if (type != BroadcastDomainType.Vlan && type != BroadcastDomainType.Vxlan && type != BroadcastDomainType.Lswitch) { throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString); } } else if (associatedNetworkId != null) { diff --git a/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java index 4c22dc16f820..b45512576ff4 100644 --- a/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java @@ -125,6 +125,9 @@ public Network design(NetworkOffering offering, DeploymentPlan plan, Network use if (userSpecified.getBroadcastUri() != null) { network.setBroadcastUri(userSpecified.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(userSpecified.getBroadcastUri()) == BroadcastDomainType.Vxlan) { + network.setBroadcastDomainType(BroadcastDomainType.Vxlan); + } network.setState(State.Setup); } } else { diff --git a/server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java b/server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java index 924d7df88961..10b3f7f7b55b 100644 --- a/server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java +++ b/server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java @@ -62,12 +62,14 @@ import java.util.UUID; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; //@Ignore("Requires database to be set up") public class CreatePrivateNetworkTest { @@ -142,9 +144,25 @@ public void setup() throws Exception { @After public void tearDown() throws Exception { + CallContext.unregister(); closeable.close(); } + @Test + public void createPrivateNetworkAcceptsVxlanUri() throws Exception { + TransactionLegacy txn = TransactionLegacy.open("createPrivateNetworkAcceptsVxlanUri"); + try { + Network network = networkService.createPrivateNetwork("bla", "fake", 1L, "vxlan://1005002", "10.1.1.2", null, + "10.1.1.1", "255.255.255.0", 1L, 1L, true, 1L, false, null); + + Assert.assertNotNull(network); + verify(_networkMgr).createPrivateNetwork(anyLong(), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), + eq("vxlan://1005002"), eq(false), any(Account.class), any(PhysicalNetwork.class), eq(1L)); + } finally { + txn.close("createPrivateNetworkAcceptsVxlanUri"); + } + } + @Test @DB public void createInvalidlyHostedPrivateNetwork() { diff --git a/server/src/test/java/com/cloud/network/guru/PrivateNetworkGuruTest.java b/server/src/test/java/com/cloud/network/guru/PrivateNetworkGuruTest.java new file mode 100644 index 000000000000..6a4f96a3563e --- /dev/null +++ b/server/src/test/java/com/cloud/network/guru/PrivateNetworkGuruTest.java @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.guru; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.NetworkVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.utils.db.EntityManager; + +@RunWith(Parameterized.class) +public class PrivateNetworkGuruTest { + @Parameterized.Parameters(name = "{index}: {0}, {1} -> {2}") + public static Collection networkTypes() { + return Arrays.asList(new Object[][] { + {BroadcastDomainType.Vlan, "vxlan://1005002", BroadcastDomainType.Vxlan}, + {BroadcastDomainType.Vlan, "vlan://123", BroadcastDomainType.Vlan}, + {BroadcastDomainType.Native, "vlan://untagged", BroadcastDomainType.Native}, + {BroadcastDomainType.Lswitch, "lswitch://private-network", BroadcastDomainType.Lswitch}, + {BroadcastDomainType.Vlan, null, BroadcastDomainType.Vlan} + }); + } + + private final BroadcastDomainType suppliedType; + private final URI broadcastUri; + private final BroadcastDomainType expectedType; + + public PrivateNetworkGuruTest(BroadcastDomainType suppliedType, String broadcastUri, BroadcastDomainType expectedType) { + this.suppliedType = suppliedType; + this.broadcastUri = broadcastUri == null ? null : URI.create(broadcastUri); + this.expectedType = expectedType; + } + + @Test + public void designPreservesNetworkIsolation() { + PrivateNetworkGuru guru = new PrivateNetworkGuru(); + guru._entityMgr = mock(EntityManager.class); + DeploymentPlan plan = mock(DeploymentPlan.class); + DataCenter dc = mock(DataCenter.class); + NetworkOffering offering = mock(NetworkOffering.class); + when(plan.getDataCenterId()).thenReturn(1L); + when(guru._entityMgr.findById(DataCenter.class, 1L)).thenReturn(dc); + when(dc.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated); + when(offering.isSystemOnly()).thenReturn(true); + + NetworkVO suppliedNetwork = new NetworkVO(); + suppliedNetwork.setCidr("10.1.1.0/24"); + suppliedNetwork.setGateway("10.1.1.1"); + suppliedNetwork.setBroadcastDomainType(suppliedType); + suppliedNetwork.setBroadcastUri(broadcastUri); + + Network network = guru.design(offering, plan, suppliedNetwork, "private-network", 1L, mock(Account.class)); + + assertNotNull(network); + assertEquals(expectedType, network.getBroadcastDomainType()); + assertEquals(broadcastUri, network.getBroadcastUri()); + assertEquals(broadcastUri == null ? Network.State.Allocated : Network.State.Setup, network.getState()); + assertEquals(suppliedNetwork.getCidr(), network.getCidr()); + assertEquals(suppliedNetwork.getGateway(), network.getGateway()); + } +}