You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2020/09/24 05:40:07 UTC
[cloudstack] branch 4.13 updated: server: Broadcast URI not set to
vxlan, but vlan (Fix #3040) (#4190)
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch 4.13
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.13 by this push:
new d6152b3 server: Broadcast URI not set to vxlan, but vlan (Fix #3040) (#4190)
d6152b3 is described below
commit d6152b37adcdbe64b66fde05c7aa53ebe0b17240
Author: Gabriel Beims Bräscher <ga...@apache.org>
AuthorDate: Thu Sep 24 02:39:50 2020 -0300
server: Broadcast URI not set to vxlan, but vlan (Fix #3040) (#4190)
This PR sets properly Broadcast URI to vxlan://vxlan_id when the physical network is of VXLAN.
Fixes: #3040
---
api/src/main/java/com/cloud/network/Networks.java | 49 ++++++++++----
.../engine/orchestration/NetworkOrchestrator.java | 23 ++++++-
.../orchestration/NetworkOrchestratorTest.java | 74 ++++++++++++++++++++++
3 files changed, 131 insertions(+), 15 deletions(-)
diff --git a/api/src/main/java/com/cloud/network/Networks.java b/api/src/main/java/com/cloud/network/Networks.java
index 559a369..f892e25 100644
--- a/api/src/main/java/com/cloud/network/Networks.java
+++ b/api/src/main/java/com/cloud/network/Networks.java
@@ -20,6 +20,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.lang3.StringUtils;
/**
* Network includes all of the enums used within networking.
@@ -253,20 +254,42 @@ public class Networks {
Long.parseLong(candidate);
return Vlan.toUri(candidate);
} catch (NumberFormatException nfe) {
- if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(candidate)) {
- return Native.toUri(candidate);
- }
- try {
- URI uri = new URI(candidate);
- BroadcastDomainType tiep = getSchemeValue(uri);
- if (tiep.scheme != null && tiep.scheme.equals(uri.getScheme())) {
- return uri;
- } else {
- throw new CloudRuntimeException("string '" + candidate + "' has an unknown BroadcastDomainType.");
- }
- } catch (URISyntaxException e) {
- throw new CloudRuntimeException("string is not a broadcast URI: " + candidate);
+ return getVlanUriWhenNumberFormatException(candidate);
+ }
+ }
+
+ /**
+ * This method is called in case of NumberFormatException is thrown when parsing the String into long
+ */
+ private static URI getVlanUriWhenNumberFormatException(String candidate) {
+ if(StringUtils.isBlank(candidate)) {
+ throw new CloudRuntimeException("Expected VLAN or VXLAN but got a null isolation method");
+ }
+ if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(candidate)) {
+ return Native.toUri(candidate);
+ }
+ try {
+ URI uri = new URI(candidate);
+ BroadcastDomainType tiep = getSchemeValue(uri);
+ if (tiep.scheme != null && tiep.scheme.equals(uri.getScheme())) {
+ return uri;
+ } else {
+ throw new CloudRuntimeException("string '" + candidate + "' has an unknown BroadcastDomainType.");
}
+ } catch (URISyntaxException e) {
+ throw new CloudRuntimeException("string is not a broadcast URI: " + candidate);
+ }
+ }
+
+ /**
+ * Encodes a string into a BroadcastUri, according to the given BroadcastDomainType
+ */
+ public static URI encodeStringIntoBroadcastUri(String candidate, BroadcastDomainType isolationMethod) {
+ try{
+ Long.parseLong(candidate);
+ return isolationMethod.toUri(candidate);
+ } catch (NumberFormatException nfe) {
+ return getVlanUriWhenNumberFormatException(candidate);
}
}
};
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 78f9315..c49da14 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
@@ -2279,7 +2279,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
if (vlanSpecified) {
- URI uri = BroadcastDomainType.fromString(vlanId);
+ URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
@@ -2424,7 +2424,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
//Logical router's UUID provided as VLAN_ID
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
} else {
- uri = BroadcastDomainType.fromString(vlanIdFinal);
+ uri = encodeVlanIdIntoBroadcastUri(vlanIdFinal, pNtwk);
}
userNetwork.setBroadcastUri(uri);
if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
@@ -2475,6 +2475,25 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return network;
}
+ /**
+ * Encodes VLAN/VXLAN ID into a Broadcast URI according to the isolation method from the Physical Network.
+ * @return Broadcast URI, e.g. 'vlan://vlan_ID' or 'vxlan://vlxan_ID'
+ */
+ protected URI encodeVlanIdIntoBroadcastUri(String vlanId, PhysicalNetwork pNtwk) {
+ if (pNtwk == null) {
+ throw new InvalidParameterValueException(String.format("Failed to encode VLAN/VXLAN %s into a Broadcast URI. Physical Network cannot be null.", vlanId));
+ }
+
+ if(StringUtils.isNotBlank(pNtwk.getIsolationMethods().get(0))) {
+ String isolationMethod = pNtwk.getIsolationMethods().get(0).toLowerCase();
+ String vxlan = BroadcastDomainType.Vxlan.toString().toLowerCase();
+ if(isolationMethod.equals(vxlan)) {
+ return BroadcastDomainType.encodeStringIntoBroadcastUri(vlanId, BroadcastDomainType.Vxlan);
+ }
+ }
+ return BroadcastDomainType.fromString(vlanId);
+ }
+
/**
* Checks bypass VLAN id/range overlap check during network creation for guest networks
* @param bypassVlanOverlapCheck bypass VLAN id/range overlap check
diff --git a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
index 3450c09..ed5265c 100644
--- a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
+++ b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
@@ -22,12 +22,15 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Before;
@@ -463,4 +466,75 @@ public class NetworkOrchestratorTest extends TestCase {
testOrchastrator.validateLockedRequestedIp(ipVoSpy, lockedIp);
}
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestVxlan() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "VXLAN", "vxlan", "vxlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestVlan() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "VLAN", "vlan", "vlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestEmpty() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("123", "", "vlan", "vlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestNull() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("123", null, "vlan", "vlan://123");
+ }
+
+ @Test(expected = CloudRuntimeException.class)
+ public void encodeVlanIdIntoBroadcastUriTestEmptyVlanId() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("", "vxlan", "vlan", "vlan://123");
+ }
+
+ @Test(expected = CloudRuntimeException.class)
+ public void encodeVlanIdIntoBroadcastUriTestNullVlanId() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest(null, "vlan", "vlan", "vlan://123");
+ }
+
+ @Test(expected = CloudRuntimeException.class)
+ public void encodeVlanIdIntoBroadcastUriTestBlankVlanId() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest(" ", "vlan", "vlan", "vlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestNullVlanIdWithSchema() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("vlan://123", "vlan", "vlan", "vlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestNullVlanIdWithSchemaIsolationVxlan() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("vlan://123", "vxlan", "vlan", "vlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestNullVxlanIdWithSchema() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("vxlan://123", "vxlan", "vxlan", "vxlan://123");
+ }
+
+ @Test
+ public void encodeVlanIdIntoBroadcastUriTestNullVxlanIdWithSchemaIsolationVlan() {
+ encodeVlanIdIntoBroadcastUriPrepareAndTest("vxlan://123", "vlan", "vxlan", "vxlan://123");
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void encodeVlanIdIntoBroadcastUriTestNullNetwork() {
+ URI resultUri = testOrchastrator.encodeVlanIdIntoBroadcastUri("vxlan://123", null);
+ }
+
+ private void encodeVlanIdIntoBroadcastUriPrepareAndTest(String vlanId, String isolationMethod, String expectedIsolation, String expectedUri) {
+ PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO();
+ List<String> isolationMethods = new ArrayList<>();
+ isolationMethods.add(isolationMethod);
+ physicalNetwork.setIsolationMethods(isolationMethods);
+
+ URI resultUri = testOrchastrator.encodeVlanIdIntoBroadcastUri(vlanId, physicalNetwork);
+
+ Assert.assertEquals(expectedIsolation, resultUri.getScheme());
+ Assert.assertEquals(expectedUri, resultUri.toString());
+ }
}