Fix LB rule creation on different tier in not on VPC with conserve mode enabled

This commit is contained in:
nvazquez 2026-03-09 12:42:43 -03:00
parent 9cf2747078
commit b6fbdc37ef
No known key found for this signature in database
GPG Key ID: 656E1BCC8CB54F84
5 changed files with 58 additions and 17 deletions

View File

@ -211,4 +211,9 @@ public interface VpcManager {
void reconfigStaticNatForVpcVr(Long vpcId);
boolean applyStaticRouteForVpcVpnIfNeeded(Long vpcId, boolean updateAllVpn) throws ResourceUnavailableException;
/**
* Returns true if the network is part of a VPC, and the VPC is created from conserve mode enabled VPC offering
*/
boolean isNetworkOnVpcEnabledConserveMode(Network network);
}

View File

@ -31,7 +31,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;
@ -401,8 +400,8 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
}
NetworkVO newRuleNetwork = getNewRuleNetwork(newRule);
boolean newRuleIsOnVpcNetwork = isNewRuleOnVpcNetwork(newRuleNetwork);
boolean vpcConserveModeEnabled = isVpcConserveModeEnabled(newRuleNetwork);
boolean newRuleIsOnVpcNetwork = newRuleNetwork.getVpcId() != null;
boolean vpcConserveModeEnabled = _vpcMgr.isNetworkOnVpcEnabledConserveMode(newRuleNetwork);
for (FirewallRuleVO rule : rules) {
if (rule.getId() == newRule.getId()) {
@ -509,19 +508,6 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
}
}
protected boolean isVpcConserveModeEnabled(NetworkVO newRuleNetwork) {
if (isNewRuleOnVpcNetwork(newRuleNetwork)) {
Vpc vpc = _vpcMgr.getActiveVpc(newRuleNetwork.getVpcId());
VpcOfferingVO vpcOffering = vpc != null ? vpcOfferingDao.findById(vpc.getVpcOfferingId()) : null;
return vpcOffering != null && vpcOffering.isConserveMode();
}
return false;
}
protected boolean isNewRuleOnVpcNetwork(NetworkVO newRuleNetwork) {
return newRuleNetwork.getVpcId() != null;
}
protected NetworkVO getNewRuleNetwork(FirewallRule newRule) {
NetworkVO newRuleNetwork = _networkDao.findById(newRule.getNetworkId());
if (newRuleNetwork == null) {

View File

@ -1738,6 +1738,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
throw new NetworkRuleConflictException("Can't do load balance on IP address: " + ipVO.getAddress());
}
verifyLoadBalancerRuleNetwork(name, network, ipVO);
String cidrString = generateCidrString(cidrList);
boolean performedIpAssoc = false;
@ -1790,7 +1792,18 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
return result;
}
/**
protected void verifyLoadBalancerRuleNetwork(String lbName, Network network, IPAddressVO ipVO) {
boolean isVpcConserveModeEnabled = _vpcMgr.isNetworkOnVpcEnabledConserveMode(network);
if (!isVpcConserveModeEnabled && ipVO.getAssociatedWithNetworkId() != null && network.getId() != ipVO.getAssociatedWithNetworkId()) {
String msg = String.format("Cannot create Load Balancer rule %s as the IP address %s is not associated " +
"with the network %s (ID=%s)", lbName, ipVO.getAddress(), network.getName(), network.getUuid());
logger.error(msg);
throw new InvalidParameterValueException(msg);
}
}
/**
* Transforms the cidrList from a List of Strings to a String which contains all the CIDRs from cidrList separated by whitespaces. This is used to facilitate both the persistence
* in the DB and also later when building the configuration String in the getRulesForPool method of the HAProxyConfigurator class.
*/

View File

@ -2956,6 +2956,20 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return true;
}
protected boolean isNetworkOnVpc(Network network) {
return network.getVpcId() != null;
}
@Override
public boolean isNetworkOnVpcEnabledConserveMode(Network newRuleNetwork) {
if (isNetworkOnVpc(newRuleNetwork)) {
Vpc vpc = getActiveVpc(newRuleNetwork.getVpcId());
VpcOfferingVO vpcOffering = vpc != null ? _vpcOffDao.findById(vpc.getVpcOfferingId()) : null;
return vpcOffering != null && vpcOffering.isConserveMode();
}
return false;
}
protected boolean applyStaticRoutes(final List<StaticRouteVO> routes, final Account caller, final boolean updateRoutesInDB) throws ResourceUnavailableException {
final boolean success = true;
final List<StaticRouteProfile> staticRouteProfiles = getVpcStaticRoutes(routes);

View File

@ -581,4 +581,27 @@ public class VpcManagerImplTest {
Assert.assertThrows(InvalidParameterValueException.class, () -> manager.validateVpcPrivateGatewayAclId(vpcId, differentVpcAclId));
}
@Test
public void testIsNetworkOnVpcEnabledConserveModeIsolatedNetwork() {
Network network = mock(Network.class);
Mockito.when(network.getVpcId()).thenReturn(null);
Assert.assertFalse(manager.isNetworkOnVpcEnabledConserveMode(network));
}
@Test
public void testIsNetworkOnVpcEnabledConserveModeVpcNetworkConserveMode() {
Network network = mock(Network.class);
Vpc vpc = mock(Vpc.class);
VpcOfferingVO vpcOffering = mock(VpcOfferingVO.class);
long vpcId = 10L;
long vpcOfferingId = 11L;
Mockito.when(network.getVpcId()).thenReturn(vpcId);
Mockito.when(vpcDao.getActiveVpcById(Mockito.eq(vpcId))).thenReturn(vpc);
Mockito.when(vpc.getVpcOfferingId()).thenReturn(vpcOfferingId);
Mockito.when(vpcOfferingDao.findById(Mockito.eq(vpcOfferingId))).thenReturn(vpcOffering);
Mockito.when(vpcOffering.isConserveMode()).thenReturn(true);
Assert.assertTrue(manager.isNetworkOnVpcEnabledConserveMode(network));
}
}