From 273ae032743cdeeb99a998c5d80cf5efef47ea42 Mon Sep 17 00:00:00 2001 From: CodeBleu <400979+CodeBleu@users.noreply.github.com> Date: Wed, 17 Sep 2025 07:49:46 -0400 Subject: [PATCH] Allow updating of Load Balancer source CIDR list (#11568) --- .../UpdateLoadBalancerRuleCmd.java | 7 +++ .../com/cloud/network/dao/LoadBalancerVO.java | 9 ++++ .../cloud/network/dao/LoadBalancerVOTest.java | 45 +++++++++++++++++++ .../lb/LoadBalancingRulesManagerImpl.java | 26 ++++++++--- 4 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 engine/schema/src/test/java/com/cloud/network/dao/LoadBalancerVOTest.java diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java index 25254ba9eb7..8593cad82c6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java @@ -33,6 +33,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; +import java.util.List; @APICommand(name = "updateLoadBalancerRule", description = "Updates load balancer", responseObject = LoadBalancerResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -64,6 +65,9 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd { @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "The protocol for the LB") private String lbProtocol; + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from", since = "4.22") + private List cidrList; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -92,6 +96,9 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd { return lbProtocol; } + public List getCidrList() { + return cidrList; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java index ad0338b9849..3886529322e 100644 --- a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java +++ b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java @@ -144,4 +144,13 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer { ReflectionToStringBuilderUtils.reflectOnlySelectedFields( this, "id", "uuid", "name", "purpose", "state")); } + + /** + * Sets the CIDR list associated with this load balancer rule. + * + * @param cidrList a comma-separated list of CIDR strings, e.g. "1.2.3.4/24,1.2.3.5/24" or an empty string e.g. "" to clear the restrictions + */ + public void setCidrList(String cidrList) { + this.cidrList = cidrList; + } } diff --git a/engine/schema/src/test/java/com/cloud/network/dao/LoadBalancerVOTest.java b/engine/schema/src/test/java/com/cloud/network/dao/LoadBalancerVOTest.java new file mode 100644 index 00000000000..8f84ecac3dd --- /dev/null +++ b/engine/schema/src/test/java/com/cloud/network/dao/LoadBalancerVOTest.java @@ -0,0 +1,45 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.dao; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class LoadBalancerVOTest { + @Test + public void testSetCidrList() { + LoadBalancerVO loadBalancer = new LoadBalancerVO(); + String cidrList = "192.168.1.0/24,10.0.0.0/16"; + loadBalancer.setCidrList(cidrList); + assertEquals(cidrList, loadBalancer.getCidrList()); + } + + @Test + public void testSetCidrListEmpty() { + LoadBalancerVO loadBalancer = new LoadBalancerVO(); + loadBalancer.setCidrList(""); + assertEquals("", loadBalancer.getCidrList()); + } + + @Test + public void testSetCidrListNull() { + LoadBalancerVO loadBalancer = new LoadBalancerVO(); + loadBalancer.setCidrList(null); + assertNull(loadBalancer.getCidrList()); + } +} diff --git a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index f786626ee31..d8ea9b55071 100644 --- a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -2257,6 +2257,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } validateInputsForExternalNetworkProvider(lb, algorithm, lbProtocol); + + List cidrList = cmd.getCidrList(); + + if (cidrList != null) { + String cidrListStr = StringUtils.join(cidrList, ","); + if (!cidrListStr.isEmpty() && !NetUtils.isValidCidrList(cidrListStr)) { + throw new InvalidParameterValueException("Invalid CIDR list: " + cidrListStr); + } + lb.setCidrList(cidrListStr); + } + // Validate rule in LB provider LoadBalancingRule rule = getLoadBalancerRuleToApply(lb); if (!validateLbRule(rule)) { @@ -2266,10 +2277,12 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancerVO tmplbVo = _lbDao.findById(lbRuleId); boolean success = _lbDao.update(lbRuleId, lb); - // If algorithm or lb protocol is changed, have to reapply the lb config - boolean needToReApplyRule = (algorithm != null && !algorithm.equals(tmplbVo.getAlgorithm())) - || (lbProtocol != null && !lbProtocol.equals(tmplbVo.getLbProtocol())); - if (needToReApplyRule) { + // Check if algorithm, lb protocol, or cidrlist has changed, and reapply the lb config if needed + boolean algorithmChanged = !Objects.equals(algorithm, tmplbVo.getAlgorithm()); + boolean protocolChanged = !Objects.equals(lbProtocol, tmplbVo.getLbProtocol()); + boolean cidrListChanged = !Objects.equals(tmplbVo.getCidrList(), lb.getCidrList()); + + if (algorithmChanged || protocolChanged || cidrListChanged) { try { lb.setState(FirewallRule.State.Add); _lbDao.persist(lb); @@ -2293,9 +2306,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (lbBackup.getAlgorithm() != null) { lb.setAlgorithm(lbBackup.getAlgorithm()); } - if (lbBackup.getLbProtocol() != null) { - lb.setLbProtocol(lbBackup.getLbProtocol()); - } + + lb.setCidrList(lbBackup.getCidrList()); lb.setState(lbBackup.getState()); _lbDao.update(lb.getId(), lb); _lbDao.persist(lb);