[VMware] Update vlans with proper range before creating port group for dvSwitch (#10708)

This commit is contained in:
Suresh Kumar Anaparti 2025-05-08 12:18:14 +05:30 committed by GitHub
parent 919c9797cc
commit f0838cdd30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 159 additions and 11 deletions

View File

@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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 * Converts a List of tags to a comma separated list
* @param tags * @param tagsList
* @return String containing a comma separated list of tags * @return String containing a comma separated list of tags
*/ */
@ -304,4 +306,92 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
return mapResult; 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();
}
} }

View File

@ -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); StringBuffer sb = new StringBuffer(prefix);
if (vlanId == null || UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) { if (vlanId == null || UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
sb.append(".untagged"); sb.append(".untagged");
} else { } else {
if (vSwitchType != VirtualSwitchType.StandardVirtualSwitch && StringUtils.containsAny(vlanId, ",-")) {
vlanId = com.cloud.utils.StringUtils.numbersToRange(vlanId);
}
sb.append(".").append(vlanId); sb.append(".").append(vlanId);
if (svlanId != null) { if (svlanId != null) {
sb.append(".").append("s" + svlanId); sb.append(".").append("s" + svlanId);
} }
} }
if (networkRateMbps != null && networkRateMbps.intValue() > 0) if (networkRateMbps != null && networkRateMbps.intValue() > 0)
@ -293,7 +295,12 @@ public class HypervisorHostHelper {
sb.append(".").append(VersioningContants.PORTGROUP_NAMING_VERSION); sb.append(".").append(VersioningContants.PORTGROUP_NAMING_VERSION);
sb.append("-").append(vSwitchName); 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 { public static Map<String, String> getValidatedVsmCredentials(VmwareContext context) throws Exception {
@ -595,7 +602,7 @@ public class HypervisorHostHelper {
if (vlanId != null) { if (vlanId != null) {
vlanId = vlanId.replace("vlan://", ""); 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, ",-")) { if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId) && !StringUtils.containsAny(vlanId, ",-")) {
createGCTag = true; createGCTag = true;
@ -1167,8 +1174,9 @@ public class HypervisorHostHelper {
if (vlanId == null && vlanRange != null && !vlanRange.isEmpty()) { if (vlanId == null && vlanRange != null && !vlanRange.isEmpty()) {
s_logger.debug("Creating dvSwitch port vlan-trunk spec with range: " + vlanRange); s_logger.debug("Creating dvSwitch port vlan-trunk spec with range: " + vlanRange);
VmwareDistributedVirtualSwitchTrunkVlanSpec trunkVlanSpec = new VmwareDistributedVirtualSwitchTrunkVlanSpec(); VmwareDistributedVirtualSwitchTrunkVlanSpec trunkVlanSpec = new VmwareDistributedVirtualSwitchTrunkVlanSpec();
for (final String vlanRangePart : vlanRange.split(",")) { String vlanRangeUpdated = com.cloud.utils.StringUtils.numbersToRange(vlanRange);
if (vlanRangePart == null || vlanRange.isEmpty()) { for (final String vlanRangePart : vlanRangeUpdated.split(",")) {
if (vlanRangePart == null || vlanRangePart.isEmpty()) {
continue; continue;
} }
final NumericRange numericRange = new NumericRange(); 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 // No doubt about this, depending on vid=null to avoid lots of code below
vid = null; vid = null;
} else { } 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)) { if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
createGCTag = true; createGCTag = true;

View File

@ -557,7 +557,7 @@ public class HypervisorHostHelperTest {
networkRateMbps = 200; networkRateMbps = 200;
prefix = "cloud.public"; prefix = "cloud.public";
vSwitchName = "vSwitch0"; 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); assertEquals("cloud.public.100.200.1-vSwitch0", cloudNetworkName);
} }
@ -567,7 +567,7 @@ public class HypervisorHostHelperTest {
networkRateMbps = null; networkRateMbps = null;
prefix = "cloud.storage"; prefix = "cloud.storage";
vSwitchName = "vSwitch1"; 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); assertEquals("cloud.storage.untagged.0.1-vSwitch1", cloudNetworkName);
} }
@ -578,10 +578,60 @@ public class HypervisorHostHelperTest {
networkRateMbps = 512; networkRateMbps = 512;
prefix = "cloud.guest"; prefix = "cloud.guest";
vSwitchName = "vSwitch2"; 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); 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 @Test
public void testOvfDomRewriter() { public void testOvfDomRewriter() {
final String ovfString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + final String ovfString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +