Fix for Vlan doesn't match issue while adding IP range for the shared network without any IP range (#10837)

This commit is contained in:
Suresh Kumar Anaparti 2025-05-16 12:54:55 +05:30 committed by GitHub
parent 1507a5633e
commit 13ab8a04d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 76 additions and 39 deletions

View File

@ -155,9 +155,6 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
}
public String getVlan() {
if (vlan == null || vlan.isEmpty()) {
vlan = "untagged";
}
return vlan;
}

View File

@ -4407,14 +4407,24 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
String endIP = cmd.getEndIp();
final String newVlanGateway = cmd.getGateway();
final String newVlanNetmask = cmd.getNetmask();
Long networkId = cmd.getNetworkID();
Long physicalNetworkId = cmd.getPhysicalNetworkId();
// Verify that network exists
Network network = getNetwork(networkId);
if (network != null) {
zoneId = network.getDataCenterId();
physicalNetworkId = network.getPhysicalNetworkId();
}
String vlanId = cmd.getVlan();
vlanId = verifyAndUpdateVlanId(vlanId, network);
// TODO decide if we should be forgiving or demand a valid and complete URI
if (!(vlanId == null || "".equals(vlanId) || vlanId.startsWith(BroadcastDomainType.Vlan.scheme()))) {
vlanId = BroadcastDomainType.Vlan.toUri(vlanId).toString();
}
final Boolean forVirtualNetwork = cmd.isForVirtualNetwork();
Long networkId = cmd.getNetworkID();
Long physicalNetworkId = cmd.getPhysicalNetworkId();
final String accountName = cmd.getAccountName();
final Long projectId = cmd.getProjectId();
final Long domainId = cmd.getDomainId();
@ -4487,18 +4497,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
// Verify that network exists
Network network = null;
if (networkId != null) {
network = _networkDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Unable to find network by id " + networkId);
} else {
zoneId = network.getDataCenterId();
physicalNetworkId = network.getPhysicalNetworkId();
}
}
// Verify that zone exists
final DataCenterVO zone = _zoneDao.findById(zoneId);
if (zone == null) {
@ -4639,6 +4637,32 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
ip6Cidr, domain, vlanOwner, network, sameSubnet);
}
private Network getNetwork(Long networkId) {
if (networkId == null) {
return null;
}
Network network = _networkDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Unable to find network by id " + networkId);
}
return network;
}
private String verifyAndUpdateVlanId(String vlanId, Network network) {
if (!StringUtils.isBlank(vlanId)) {
return vlanId;
}
if (network == null || network.getTrafficType() != TrafficType.Guest) {
return Vlan.UNTAGGED;
}
boolean connectivityWithoutVlan = isConnectivityWithoutVlan(network);
return getNetworkVlanId(network, connectivityWithoutVlan);
}
private Vlan commitVlan(final Long zoneId, final Long podId, final String startIP, final String endIP, final String newVlanGatewayFinal, final String newVlanNetmaskFinal,
final String vlanId, final Boolean forVirtualNetwork, final Boolean forSystemVms, final Long networkId, final Long physicalNetworkId, final String startIPv6, final String endIPv6,
final String ip6Gateway, final String ip6Cidr, final Domain domain, final Account vlanOwner, final Network network, final Pair<Boolean, Pair<String, String>> sameSubnet) {
@ -4847,28 +4871,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
// same as network's vlan
// 2) if vlan is missing, default it to the guest network's vlan
if (network.getTrafficType() == TrafficType.Guest) {
String networkVlanId = null;
boolean connectivityWithoutVlan = false;
if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) {
Map<Capability, String> connectivityCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Connectivity);
connectivityWithoutVlan = MapUtils.isNotEmpty(connectivityCapabilities) && connectivityCapabilities.containsKey(Capability.NoVlan);
}
final URI uri = network.getBroadcastUri();
if (connectivityWithoutVlan) {
networkVlanId = network.getBroadcastDomainType().toUri(network.getUuid()).toString();
} else if (uri != null) {
// Do not search for the VLAN tag when the network doesn't support VLAN
if (uri.toString().startsWith("vlan")) {
final String[] vlan = uri.toString().split("vlan:\\/\\/");
networkVlanId = vlan[1];
// For pvlan
if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
networkVlanId = networkVlanId.split("-")[0];
}
}
}
boolean connectivityWithoutVlan = isConnectivityWithoutVlan(network);
String networkVlanId = getNetworkVlanId(network, connectivityWithoutVlan);
if (vlanId != null && !connectivityWithoutVlan) {
// if vlan is specified, throw an error if it's not equal to
// network's vlanId
@ -5000,6 +5004,36 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
return vlan;
}
private boolean isConnectivityWithoutVlan(Network network) {
boolean connectivityWithoutVlan = false;
if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) {
Map<Capability, String> connectivityCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Connectivity);
connectivityWithoutVlan = MapUtils.isNotEmpty(connectivityCapabilities) && connectivityCapabilities.containsKey(Capability.NoVlan);
}
return connectivityWithoutVlan;
}
private String getNetworkVlanId(Network network, boolean connectivityWithoutVlan) {
String networkVlanId = null;
if (connectivityWithoutVlan) {
return network.getBroadcastDomainType().toUri(network.getUuid()).toString();
}
final URI uri = network.getBroadcastUri();
if (uri != null) {
// Do not search for the VLAN tag when the network doesn't support VLAN
if (uri.toString().startsWith("vlan")) {
final String[] vlan = uri.toString().split("vlan:\\/\\/");
networkVlanId = vlan[1];
// For pvlan
if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
networkVlanId = networkVlanId.split("-")[0];
}
}
}
return networkVlanId;
}
private void checkZoneVlanIpOverlap(DataCenterVO zone, Network network, String newCidr, String vlanId, String vlanGateway, String vlanNetmask, String startIP, String endIP) {
// Throw an exception if this subnet overlaps with subnet on other VLAN,
// if this is ip range extension, gateway, network mask should be same and ip range should not overlap

View File

@ -54,6 +54,8 @@ import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.DiskOffering;
@ -189,6 +191,8 @@ public class ConfigurationManagerTest {
@Mock
HostPodDao _podDao;
@Mock
NetworkDao _networkDao;
@Mock
PhysicalNetworkDao _physicalNetworkDao;
@Mock
ImageStoreDao _imageStoreDao;
@ -1325,6 +1329,8 @@ public class ConfigurationManagerTest {
public void testWrongIpv6CreateVlanAndPublicIpRange() {
CreateVlanIpRangeCmd cmd = Mockito.mock(CreateVlanIpRangeCmd.class);
Mockito.when(cmd.getIp6Cidr()).thenReturn("fd17:5:8a43:e2a4:c000::/66");
NetworkVO network = Mockito.mock(NetworkVO.class);
Mockito.when(_networkDao.findById(Mockito.anyLong())).thenReturn(network);
try {
configurationMgr.createVlanAndPublicIpRange(cmd);
} catch (InsufficientCapacityException | ResourceUnavailableException | ResourceAllocationException e) {