Update CIDR/Gateway of the Shared Networks from Guest IP ranges (#11249)

This commit is contained in:
Suresh Kumar Anaparti 2025-07-29 14:00:14 +05:30 committed by GitHub
parent f6ad184ea2
commit 86827f871d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 161 additions and 35 deletions

View File

@ -659,3 +659,8 @@ CALL `cloud`.`INSERT_EXTENSION_CUSTOM_ACTION_DETAILS_IF_NOT_EXISTS`(
'Resume',
'[]'
);
ALTER TABLE `cloud`.`networks` MODIFY COLUMN `cidr` varchar(255) DEFAULT NULL COMMENT 'CloudStack managed vms get IP address from cidr.In general this cidr also serves as the network CIDR. But in case IP reservation feature is being used by a Guest network, networkcidr is the Effective network CIDR for that network';
ALTER TABLE `cloud`.`networks` MODIFY COLUMN `gateway` varchar(255) DEFAULT NULL COMMENT 'gateway(s) for this network configuration';
ALTER TABLE `cloud`.`networks` MODIFY COLUMN `ip6_cidr` varchar(1024) DEFAULT NULL COMMENT 'IPv6 cidr(s) for this network';
ALTER TABLE `cloud`.`networks` MODIFY COLUMN `ip6_gateway` varchar(1024) DEFAULT NULL COMMENT 'IPv6 gateway(s) for this network';

View File

@ -2539,10 +2539,11 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setType(network.getGuestType().toString());
}
response.setGateway(network.getGateway());
response.setGateway(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getGateway()));
String cidr = com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getCidr());
// FIXME - either set netmask or cidr
response.setCidr(network.getCidr());
response.setCidr(cidr);
if (network.getNetworkCidr() != null) {
response.setNetworkCidr((network.getNetworkCidr()));
}
@ -2553,18 +2554,18 @@ public class ApiResponseHelper implements ResponseGenerator {
if (network.getNetworkCidr() != null) {
response.setNetmask(NetUtils.cidr2Netmask(network.getNetworkCidr()));
}
if (((network.getCidr()) != null) && (network.getNetworkCidr() == null)) {
response.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
if ((cidr != null) && (network.getNetworkCidr() == null)) {
response.setNetmask(NetUtils.cidr2Netmask(cidr));
}
response.setIp6Gateway(network.getIp6Gateway());
response.setIp6Cidr(network.getIp6Cidr());
response.setIp6Gateway(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getIp6Gateway()));
response.setIp6Cidr(com.cloud.utils.StringUtils.getFirstValueFromCommaSeparatedString(network.getIp6Cidr()));
// create response for reserved IP ranges that can be used for
// non-cloudstack purposes
String reservation = null;
if ((network.getCidr() != null) && (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr()))) {
String[] guestVmCidrPair = network.getCidr().split("\\/");
if ((cidr != null) && (NetUtils.isNetworkAWithinNetworkB(cidr, network.getNetworkCidr()))) {
String[] guestVmCidrPair = cidr.split("\\/");
String[] guestCidrPair = network.getNetworkCidr().split("\\/");
Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]);

View File

@ -5397,9 +5397,42 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, domain, vlanOwner, vlanIp6Gateway, vlanIp6Cidr,
ipv4, zone, vlanType, ipv6Range, ipRange, forSystemVms, provider);
if (vlan != null) {
if (ipv4) {
addCidrAndGatewayForIpv4(networkId, vlanGateway, vlanNetmask);
} else if (ipv6) {
addCidrAndGatewayForIpv6(networkId, vlanIp6Gateway, vlanIp6Cidr);
}
}
return vlan;
}
private void addCidrAndGatewayForIpv4(final long networkId, final String vlanGateway, final String vlanNetmask) {
final NetworkVO networkVO = _networkDao.findById(networkId);
String networkCidr = networkVO.getCidr();
String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
String newNetworkCidr = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkCidr, newCidr, true);
networkVO.setCidr(newNetworkCidr);
String networkGateway = networkVO.getGateway();
String newNetworkGateway = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkGateway, vlanGateway, true);
networkVO.setGateway(newNetworkGateway);
_networkDao.update(networkId, networkVO);
}
private void addCidrAndGatewayForIpv6(final long networkId, final String vlanIp6Gateway, final String vlanIp6Cidr) {
final NetworkVO networkVO = _networkDao.findById(networkId);
String networkIp6Cidr = networkVO.getIp6Cidr();
String newNetworkIp6Cidr = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkIp6Cidr, vlanIp6Cidr, true);
networkVO.setIp6Cidr(newNetworkIp6Cidr);
String networkIp6Gateway = networkVO.getIp6Gateway();
String newNetworkIp6Gateway = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkIp6Gateway, vlanIp6Gateway, true);
networkVO.setIp6Gateway(newNetworkIp6Gateway);
_networkDao.update(networkId, networkVO);
}
private boolean isConnectivityWithoutVlan(Network network) {
boolean connectivityWithoutVlan = false;
if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) {
@ -6440,12 +6473,47 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
private boolean deleteAndPublishVlanAndPublicIpRange(final long userId, final long vlanDbId, final Account caller) {
VlanVO deletedVlan = deleteVlanAndPublicIpRange(userId, vlanDbId, caller);
if (deletedVlan != null) {
final boolean ipv4 = deletedVlan.getVlanGateway() != null;
final boolean ipv6 = deletedVlan.getIp6Gateway() != null;
final long networkId = deletedVlan.getNetworkId();
if (ipv4) {
removeCidrAndGatewayForIpv4(networkId, deletedVlan);
} else if (ipv6) {
removeCidrAndGatewayForIpv6(networkId, deletedVlan);
}
messageBus.publish(_name, MESSAGE_DELETE_VLAN_IP_RANGE_EVENT, PublishScope.LOCAL, deletedVlan);
return true;
}
return false;
}
private void removeCidrAndGatewayForIpv4(final long networkId, VlanVO deletedVlan) {
final NetworkVO networkVO = _networkDao.findById(networkId);
String networkCidr = networkVO.getCidr();
String cidrToRemove = NetUtils.getCidrFromGatewayAndNetmask(deletedVlan.getVlanGateway(), deletedVlan.getVlanNetmask());
String newNetworkCidr = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkCidr, cidrToRemove, false);
networkVO.setCidr(newNetworkCidr);
String networkGateway = networkVO.getGateway();
String newNetworkGateway = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkGateway, deletedVlan.getVlanGateway(), false);
networkVO.setGateway(newNetworkGateway);
_networkDao.update(networkId, networkVO);
}
private void removeCidrAndGatewayForIpv6(final long networkId, VlanVO deletedVlan) {
final NetworkVO networkVO = _networkDao.findById(networkId);
String networkIp6Cidr = networkVO.getIp6Cidr();
String newNetworkIp6Cidr = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkIp6Cidr, deletedVlan.getIp6Cidr(), false);
networkVO.setIp6Cidr(newNetworkIp6Cidr);
String networkIp6Gateway = networkVO.getIp6Gateway();
String newNetworkIp6Gateway = com.cloud.utils.StringUtils.updateCommaSeparatedStringWithValue(networkIp6Gateway, deletedVlan.getIp6Gateway(), false);
networkVO.setIp6Gateway(newNetworkIp6Gateway);
_networkDao.update(networkId, networkVO);
}
@Override
public void checkDiskOfferingAccess(final Account caller, final DiskOffering dof, DataCenter zone) {
for (final SecurityChecker checker : _secChecker) {

View File

@ -24,14 +24,17 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class StringUtils extends org.apache.commons.lang3.StringUtils {
private static final char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
@ -409,4 +412,53 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
String[] finalMergedTagsArray = appendedTags.split(",");
return finalMergedTagsArray;
}
/**
* Converts the comma separated numbers and ranges to numbers
* @param originalString the original string (can be null or empty) containing list of comma separated values that has to be updated
* @param value the value to add to, or remove from the original string
* @param add if true, adds the input value; if false, removes it
* @return String containing the modified original string (or null if empty)
*/
public static String updateCommaSeparatedStringWithValue(String originalString, String value, boolean add) {
if (org.apache.commons.lang3.StringUtils.isEmpty(value)) {
return originalString;
}
Set<String> values = new LinkedHashSet<>();
if (org.apache.commons.lang3.StringUtils.isNotEmpty(originalString)) {
values.addAll(Arrays.stream(originalString.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toList()));
}
if (add) {
values.add(value);
} else {
values.remove(value);
}
return values.isEmpty() ? null : String.join(",", values);
}
/**
* Returns the first value from a comma-separated string.
* @param inputString the input string (can be null or empty) containing list of comma separated values
* @return the first value, or null if none found
*/
public static String getFirstValueFromCommaSeparatedString(String inputString) {
if (org.apache.commons.lang3.StringUtils.isEmpty(inputString)) {
return inputString;
}
String[] values = inputString.split(",");
if (values.length > 0) {
return values[0].trim();
}
return null;
}
}