This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push:
new f0838cdd309 [VMware] Update vlans with proper range before creating
port group for dvSwitch (#10708)
f0838cdd309 is described below
commit f0838cdd30984818919c12663dec6effa26483c7
Author: Suresh Kumar Anaparti <[email protected]>
AuthorDate: Thu May 8 12:18:14 2025 +0530
[VMware] Update vlans with proper range before creating port group for
dvSwitch (#10708)
---
.../src/main/java/com/cloud/utils/StringUtils.java | 92 +++++++++++++++++++++-
.../hypervisor/vmware/mo/HypervisorHostHelper.java | 22 ++++--
.../vmware/mo/HypervisorHostHelperTest.java | 56 ++++++++++++-
3 files changed, 159 insertions(+), 11 deletions(-)
diff --git a/utils/src/main/java/com/cloud/utils/StringUtils.java
b/utils/src/main/java/com/cloud/utils/StringUtils.java
index 01b6f833271..c6116123b40 100644
--- a/utils/src/main/java/com/cloud/utils/StringUtils.java
+++ b/utils/src/main/java/com/cloud/utils/StringUtils.java
@@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -90,7 +92,7 @@ public class StringUtils extends
org.apache.commons.lang3.StringUtils {
/**
* Converts a List of tags to a comma separated list
- * @param tags
+ * @param tagsList
* @return String containing a comma separated list of tags
*/
@@ -304,4 +306,92 @@ public class StringUtils extends
org.apache.commons.lang3.StringUtils {
return mapResult;
}
+
+ /**
+ * Converts the comma separated numbers to ranges for any consecutive
numbers in the input with numbers (and ranges)
+ * Eg: "198,200-203,299,300,301,303,304,305,306,307,308,311,197" to
"197-198,200-203,299-301,303-308,311"
+ * @param inputNumbersAndRanges
+ * @return String containing a converted ranges for any consecutive numbers
+ */
+ public static String numbersToRange(String inputNumbersAndRanges) {
+ Set<Integer> numberSet = new TreeSet<>();
+ for (String inputNumber : inputNumbersAndRanges.split(",")) {
+ inputNumber = inputNumber.trim();
+ if (inputNumber.contains("-")) {
+ String[] range = inputNumber.split("-");
+ if (range.length == 2 && range[0] != null && range[1] != null)
{
+ int start = NumbersUtil.parseInt(range[0], 0);
+ int end = NumbersUtil.parseInt(range[1], 0);
+ for (int i = start; i <= end; i++) {
+ numberSet.add(i);
+ }
+ }
+ } else {
+ numberSet.add(NumbersUtil.parseInt(inputNumber, 0));
+ }
+ }
+
+ StringBuilder result = new StringBuilder();
+ if (!numberSet.isEmpty()) {
+ List<Integer> numbers = new ArrayList<>(numberSet);
+ int startNumber = numbers.get(0);
+ int endNumber = startNumber;
+
+ for (int i = 1; i < numbers.size(); i++) {
+ if (numbers.get(i) == endNumber + 1) {
+ endNumber = numbers.get(i);
+ } else {
+ appendRange(result, startNumber, endNumber);
+ startNumber = endNumber = numbers.get(i);
+ }
+ }
+ appendRange(result, startNumber, endNumber);
+ }
+
+ return result.toString();
+ }
+
+ private static void appendRange(StringBuilder sb, int startNumber, int
endNumber) {
+ if (sb.length() > 0) {
+ sb.append(",");
+ }
+ if (startNumber == endNumber) {
+ sb.append(startNumber);
+ } else {
+ sb.append(startNumber).append("-").append(endNumber);
+ }
+ }
+
+ /**
+ * Converts the comma separated numbers and ranges to numbers
+ * Eg: "197-198,200-203,299-301,303-308,311" to
"197,198,200,201,202,203,299,300,301,303,304,305,306,307,308,311"
+ * @param inputNumbersAndRanges
+ * @return String containing a converted numbers
+ */
+ public static String rangeToNumbers(String inputNumbersAndRanges) {
+ Set<Integer> numberSet = new TreeSet<>();
+ for (String inputNumber : inputNumbersAndRanges.split(",")) {
+ inputNumber = inputNumber.trim();
+ if (inputNumber.contains("-")) {
+ String[] range = inputNumber.split("-");
+ int startNumber = Integer.parseInt(range[0]);
+ int endNumber = Integer.parseInt(range[1]);
+ for (int i = startNumber; i <= endNumber; i++) {
+ numberSet.add(i);
+ }
+ } else {
+ numberSet.add(Integer.parseInt(inputNumber));
+ }
+ }
+
+ StringBuilder result = new StringBuilder();
+ for (int number : numberSet) {
+ if (result.length() > 0) {
+ result.append(",");
+ }
+ result.append(number);
+ }
+
+ return result.toString();
+ }
}
diff --git
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index 44965e9321b..e43af246696 100644
---
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -274,16 +274,18 @@ public class HypervisorHostHelper {
}
}
- public static String composeCloudNetworkName(String prefix, String vlanId,
String svlanId, Integer networkRateMbps, String vSwitchName) {
+ public static String composeCloudNetworkName(String prefix, String vlanId,
String svlanId, Integer networkRateMbps, String vSwitchName, VirtualSwitchType
vSwitchType) {
StringBuffer sb = new StringBuffer(prefix);
if (vlanId == null || UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
sb.append(".untagged");
} else {
+ if (vSwitchType != VirtualSwitchType.StandardVirtualSwitch &&
StringUtils.containsAny(vlanId, ",-")) {
+ vlanId = com.cloud.utils.StringUtils.numbersToRange(vlanId);
+ }
sb.append(".").append(vlanId);
if (svlanId != null) {
sb.append(".").append("s" + svlanId);
}
-
}
if (networkRateMbps != null && networkRateMbps.intValue() > 0)
@@ -293,7 +295,12 @@ public class HypervisorHostHelper {
sb.append(".").append(VersioningContants.PORTGROUP_NAMING_VERSION);
sb.append("-").append(vSwitchName);
- return sb.toString();
+ String networkName = sb.toString();
+ if (networkName.length() > 80) {
+ // the maximum limit for a vSwitch name is 80 chars, applies to
both standard and distributed virtual switches.
+ s_logger.warn(String.format("The network name: %s for the vSwitch
%s of type %s, exceeds 80 chars", networkName, vSwitchName, vSwitchType));
+ }
+ return networkName;
}
public static Map<String, String> getValidatedVsmCredentials(VmwareContext
context) throws Exception {
@@ -595,7 +602,7 @@ public class HypervisorHostHelper {
if (vlanId != null) {
vlanId = vlanId.replace("vlan://", "");
}
- networkName = composeCloudNetworkName(namePrefix, vlanId,
secondaryvlanId, networkRateMbps, physicalNetwork);
+ networkName = composeCloudNetworkName(namePrefix, vlanId,
secondaryvlanId, networkRateMbps, physicalNetwork, vSwitchType);
if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)
&& !StringUtils.containsAny(vlanId, ",-")) {
createGCTag = true;
@@ -1167,8 +1174,9 @@ public class HypervisorHostHelper {
if (vlanId == null && vlanRange != null && !vlanRange.isEmpty()) {
s_logger.debug("Creating dvSwitch port vlan-trunk spec with range:
" + vlanRange);
VmwareDistributedVirtualSwitchTrunkVlanSpec trunkVlanSpec = new
VmwareDistributedVirtualSwitchTrunkVlanSpec();
- for (final String vlanRangePart : vlanRange.split(",")) {
- if (vlanRangePart == null || vlanRange.isEmpty()) {
+ String vlanRangeUpdated =
com.cloud.utils.StringUtils.numbersToRange(vlanRange);
+ for (final String vlanRangePart : vlanRangeUpdated.split(",")) {
+ if (vlanRangePart == null || vlanRangePart.isEmpty()) {
continue;
}
final NumericRange numericRange = new NumericRange();
@@ -1320,7 +1328,7 @@ public class HypervisorHostHelper {
// No doubt about this, depending on vid=null to avoid lots of
code below
vid = null;
} else {
- networkName = composeCloudNetworkName(namePrefix, vlanId, null,
networkRateMbps, vSwitchName);
+ networkName = composeCloudNetworkName(namePrefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.StandardVirtualSwitch);
if (vlanId != null &&
!UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
createGCTag = true;
diff --git
a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
index 1c888a05748..05fb9c9e6d3 100644
---
a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
+++
b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
@@ -557,7 +557,7 @@ public class HypervisorHostHelperTest {
networkRateMbps = 200;
prefix = "cloud.public";
vSwitchName = "vSwitch0";
- String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName);
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName, VirtualSwitchType.StandardVirtualSwitch);
assertEquals("cloud.public.100.200.1-vSwitch0", cloudNetworkName);
}
@@ -567,7 +567,7 @@ public class HypervisorHostHelperTest {
networkRateMbps = null;
prefix = "cloud.storage";
vSwitchName = "vSwitch1";
- String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName);
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName, VirtualSwitchType.StandardVirtualSwitch);
assertEquals("cloud.storage.untagged.0.1-vSwitch1", cloudNetworkName);
}
@@ -578,10 +578,60 @@ public class HypervisorHostHelperTest {
networkRateMbps = 512;
prefix = "cloud.guest";
vSwitchName = "vSwitch2";
- String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName);
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId,
networkRateMbps, vSwitchName, VirtualSwitchType.StandardVirtualSwitch);
assertEquals("cloud.guest.400.s123.512.1-vSwitch2", cloudNetworkName);
}
+ @Test
+ public void testComposeCloudNetworkNameVlanRangeGuestTrafficDvSwitch() {
+ vlanId = "400-500";
+ networkRateMbps = 512;
+ prefix = "cloud.guest";
+ vSwitchName = "dvSwitch0";
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.VMwareDistributedVirtualSwitch);
+ assertEquals("cloud.guest.400-500.512.1-dvSwitch0", cloudNetworkName);
+ }
+
+ @Test
+ public void testComposeCloudNetworkNameVlanNumbersGuestTrafficDvSwitch() {
+ vlanId =
"3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020";
+ networkRateMbps = 512;
+ prefix = "cloud.guest";
+ vSwitchName = "dvSwitch0";
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.VMwareDistributedVirtualSwitch);
+ assertEquals("cloud.guest.3001-3020.512.1-dvSwitch0",
cloudNetworkName);
+ }
+
+ @Test
+ public void
testComposeCloudNetworkNameVlanNumbersAndRangeGuestTrafficDvSwitch() {
+ vlanId =
"3001,3004-3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3020";
+ networkRateMbps = 512;
+ prefix = "cloud.guest";
+ vSwitchName = "dvSwitch0";
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.VMwareDistributedVirtualSwitch);
+ assertEquals("cloud.guest.3001,3004-3018,3020.512.1-dvSwitch0",
cloudNetworkName);
+ }
+
+ @Test
+ public void
testComposeCloudNetworkNameUnorderedVlanNumbersAndRangeGuestTrafficDvSwitch() {
+ vlanId =
"3018,3020,3011,3012,3004-3006,3007,3001,3008,3009,3010,3013,3014,3015,3016,3017";
+ networkRateMbps = 512;
+ prefix = "cloud.guest";
+ vSwitchName = "dvSwitch0";
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.VMwareDistributedVirtualSwitch);
+ assertEquals("cloud.guest.3001,3004-3018,3020.512.1-dvSwitch0",
cloudNetworkName);
+ }
+
+ @Test
+ public void
testComposeCloudNetworkNameOverlappingVlanNumbersAndRangeGuestTrafficDvSwitch()
{
+ vlanId =
"3018,3020,3011,3012,3004-3006,3007,3001,3008,3009,3010,3013,3014,3015,3016,3017,3005-3008";
+ networkRateMbps = 512;
+ prefix = "cloud.guest";
+ vSwitchName = "dvSwitch0";
+ String cloudNetworkName =
HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, null,
networkRateMbps, vSwitchName, VirtualSwitchType.VMwareDistributedVirtualSwitch);
+ assertEquals("cloud.guest.3001,3004-3018,3020.512.1-dvSwitch0",
cloudNetworkName);
+ }
+
@Test
public void testOvfDomRewriter() {
final String ovfString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +