diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java index 3efbc315e1a..51799e25cda 100644 --- a/api/src/main/java/com/cloud/network/NetworkService.java +++ b/api/src/main/java/com/cloud/network/NetworkService.java @@ -56,6 +56,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.NicSecondaryIp; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; /** * The NetworkService interface is the "public" api to entities that make requests to the orchestration engine @@ -257,4 +258,9 @@ public interface NetworkService { PublicIpQuarantine updatePublicIpAddressInQuarantine(UpdateQuarantinedIpCmd cmd); void removePublicIpAddressFromQuarantine(RemoveQuarantinedIpCmd cmd); + + InternalLoadBalancerElementService getInternalLoadBalancerElementByType(VirtualRouterProvider.Type type); + InternalLoadBalancerElementService getInternalLoadBalancerElementByNetworkServiceProviderId(long networkProviderId); + InternalLoadBalancerElementService getInternalLoadBalancerElementById(long providerId); + List getInternalLoadBalancerElements(); } diff --git a/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java b/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java index 8c3243c99f4..852a650cfcd 100644 --- a/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java +++ b/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java @@ -21,6 +21,7 @@ import java.util.List; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.Vpc; public interface NetworkACLServiceProvider extends NetworkElement { @@ -32,4 +33,6 @@ public interface NetworkACLServiceProvider extends NetworkElement { */ boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException; + boolean reorderAclRules(Vpc vpc, List networks, List networkACLItems); + } diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java index 323fd4e6f64..b206cd011c1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java @@ -38,7 +38,6 @@ import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.annotation.AnnotationService; import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; import org.apache.cloudstack.query.QueryService; @@ -201,8 +200,6 @@ public abstract class BaseCmd { @Inject public AffinityGroupService _affinityGroupService; @Inject - public InternalLoadBalancerElementService _internalLbElementSvc; - @Inject public InternalLoadBalancerVMService _internalLbSvc; @Inject public NetworkModel _ntwkModel; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java index 18dfc87397a..c94d326ee62 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java @@ -17,11 +17,6 @@ package org.apache.cloudstack.api.command.admin.internallb; -import java.util.List; - -import javax.inject.Inject; - - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -47,9 +42,6 @@ import com.cloud.user.Account; responseHasSensitiveInfo = false) public class ConfigureInternalLoadBalancerElementCmd extends BaseAsyncCmd { - @Inject - private List _service; - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -98,7 +90,8 @@ public class ConfigureInternalLoadBalancerElementCmd extends BaseAsyncCmd { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { CallContext.current().setEventDetails("Internal load balancer element: " + id); - VirtualRouterProvider result = _service.get(0).configureInternalLoadBalancerElement(getId(), getEnabled()); + InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementById(id); + VirtualRouterProvider result = service.configureInternalLoadBalancerElement(getId(), getEnabled()); if (result != null) { InternalLoadBalancerElementResponse routerResponse = _responseGenerator.createInternalLbElementResponse(result); routerResponse.setResponseName(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java index 971f097fca5..924287b673b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java @@ -16,11 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.internallb; -import java.util.List; - -import javax.inject.Inject; - - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -45,9 +40,6 @@ import com.cloud.user.Account; responseHasSensitiveInfo = false) public class CreateInternalLoadBalancerElementCmd extends BaseAsyncCreateCmd { - @Inject - private List _service; - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -83,7 +75,8 @@ public class CreateInternalLoadBalancerElementCmd extends BaseAsyncCreateCmd { @Override public void execute() { CallContext.current().setEventDetails("Virtual router element Id: " + getEntityId()); - VirtualRouterProvider result = _service.get(0).getInternalLoadBalancerElement(getEntityId()); + InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(getNspId()); + VirtualRouterProvider result = service.getInternalLoadBalancerElement(getEntityId()); if (result != null) { InternalLoadBalancerElementResponse response = _responseGenerator.createInternalLbElementResponse(result); response.setResponseName(getCommandName()); @@ -95,7 +88,8 @@ public class CreateInternalLoadBalancerElementCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - VirtualRouterProvider result = _service.get(0).addInternalLoadBalancerElement(getNspId()); + InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(getNspId()); + VirtualRouterProvider result = service.addInternalLoadBalancerElement(getNspId()); if (result != null) { setEntityId(result.getId()); setEntityUuid(result.getUuid()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java index 6c2fadee737..b17cc22e746 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java @@ -17,11 +17,9 @@ package org.apache.cloudstack.api.command.admin.internallb; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import javax.inject.Inject; - - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; @@ -46,9 +44,6 @@ import com.cloud.network.VirtualRouterProvider; responseHasSensitiveInfo = false) public class ListInternalLoadBalancerElementsCmd extends BaseListCmd { - @Inject - private InternalLoadBalancerElementService _service; - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -86,12 +81,21 @@ public class ListInternalLoadBalancerElementsCmd extends BaseListCmd { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { - List providers = _service.searchForInternalLoadBalancerElements(getId(), getNspId(), getEnabled()); + List services; + if (id == null && nspId == null) { + services = _networkService.getInternalLoadBalancerElements(); + } else { + InternalLoadBalancerElementService elementService = id != null ? _networkService.getInternalLoadBalancerElementById(id) : _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(nspId); + services = Collections.singletonList(elementService); + } ListResponse response = new ListResponse(); List providerResponses = new ArrayList(); - for (VirtualRouterProvider provider : providers) { - InternalLoadBalancerElementResponse providerResponse = _responseGenerator.createInternalLbElementResponse(provider); - providerResponses.add(providerResponse); + for (InternalLoadBalancerElementService service : services) { + List providers = service.searchForInternalLoadBalancerElements(getId(), getNspId(), getEnabled()); + for (VirtualRouterProvider provider : providers) { + InternalLoadBalancerElementResponse providerResponse = _responseGenerator.createInternalLbElementResponse(provider); + providerResponses.add(providerResponse); + } } response.setResponses(providerResponses); response.setResponseName(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java b/api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java index 76706a4cfc9..1fff54f5f8f 100644 --- a/api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java +++ b/api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java @@ -52,4 +52,6 @@ public interface InternalLoadBalancerElementService extends PluggableService { * @return */ List searchForInternalLoadBalancerElements(Long id, Long ntwkSvsProviderId, Boolean enabled); + + VirtualRouterProvider.Type getProviderType(); } diff --git a/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index a36d1243155..49775fe41e1 100644 --- a/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -350,4 +350,12 @@ + + + + + + + + diff --git a/core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml index 8dbaf610581..2240d1f2606 100644 --- a/core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml +++ b/core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml @@ -103,4 +103,9 @@ + + + + + diff --git a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java index 4200ea8c601..de69b894183 100644 --- a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java +++ b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java @@ -19,6 +19,7 @@ package com.cloud.network.vpc; import java.util.List; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; import com.cloud.network.dao.NetworkVO; public interface NetworkACLManager { @@ -91,4 +92,6 @@ public interface NetworkACLManager { boolean revokeACLItemsForPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException; boolean applyACLToPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException; + + boolean reorderAclRules(VpcVO vpc, List networks, List networkACLItems); } diff --git a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java index 95513df9c86..5fc9480c610 100644 --- a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java +++ b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java @@ -698,6 +698,11 @@ NetworkACLServiceProvider, FirewallServiceProvider, ResourceStateAdapter { return true; } + @Override + public boolean reorderAclRules(Vpc vpc, List networks, List networkACLItems) { + return true; + } + @Override public boolean applyFWRules(Network network, List rules) diff --git a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java index 0bbc3e678d3..0a9b4a7131a 100644 --- a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java +++ b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java @@ -83,7 +83,9 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.network.router.NetworkHelper; +import org.springframework.stereotype.Component; +@Component public class InternalLoadBalancerElement extends AdapterBase implements LoadBalancingServiceProvider, InternalLoadBalancerElementService, IpDeployer { protected static final Map> capabilities = setCapabilities(); private static InternalLoadBalancerElement internalLbElement = null; @@ -112,14 +114,7 @@ public class InternalLoadBalancerElement extends AdapterBase implements LoadBala @Qualifier("networkHelper") protected NetworkHelper _networkHelper; - protected InternalLoadBalancerElement() { - } - - public static InternalLoadBalancerElement getInstance() { - if (internalLbElement == null) { - internalLbElement = new InternalLoadBalancerElement(); - } - return internalLbElement; + public InternalLoadBalancerElement() { } private boolean canHandle(Network config, Scheme lbScheme) { @@ -517,6 +512,11 @@ public class InternalLoadBalancerElement extends AdapterBase implements LoadBala return sc.list(); } + @Override + public Type getProviderType() { + return Type.InternalLbVm; + } + @Override public boolean applyIps(Network network, List ipAddress, Set services) throws ResourceUnavailableException { //do nothing here; this element just has to extend the ip deployer diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java index b73ed7feb60..85125bf3af6 100644 --- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java +++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java @@ -182,6 +182,11 @@ public class ContrailVpcElementImpl extends ContrailElementImpl implements Netwo return true; } + @Override + public boolean reorderAclRules(Vpc vpc, List networks, List networkACLItems) { + return true; + } + @Override public boolean applyACLItemsToPrivateGw(PrivateGateway privateGateway, List rules) diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java index 05a7d141a86..7aba83bb062 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java @@ -112,7 +112,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -712,18 +711,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns boolean success = true; for (NetworkACLItem rule : rules) { String privatePort = getPrivatePortRangeForACLRule(rule); - NsxNetworkRule networkRule = new NsxNetworkRule.Builder() - .setRuleId(rule.getId()) - .setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY")) - .setAclAction(transformActionValue(rule.getAction())) - .setTrafficType(rule.getTrafficType().toString()) - .setProtocol(rule.getProtocol().toUpperCase()) - .setPublicPort(String.valueOf(rule.getSourcePortStart())) - .setPrivatePort(privatePort) - .setIcmpCode(rule.getIcmpCode()) - .setIcmpType(rule.getIcmpType()) - .setService(Network.Service.NetworkACL) - .build(); + NsxNetworkRule networkRule = getNsxNetworkRuleForAcl(rule, privatePort); if (Arrays.asList(NetworkACLItem.State.Active, NetworkACLItem.State.Add).contains(rule.getState())) { success = success && nsxService.addFirewallRules(network, List.of(networkRule)); } else if (NetworkACLItem.State.Revoke == rule.getState()) { @@ -740,9 +728,38 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns return success; } - private void reorderRules(List rules) { - rules.sort((Comparator) (r1, r2) -> ((NetworkACLItem) r2).getNumber() - ((NetworkACLItem) r1).getNumber()); + @Override + public boolean reorderAclRules(Vpc vpc, List networks, List networkACLItems) { + List aclRulesList = new ArrayList<>(); + for (NetworkACLItem rule : networkACLItems) { + String privatePort = getPrivatePortRangeForACLRule(rule); + aclRulesList.add(getNsxNetworkRuleForAcl(rule, privatePort)); + } + for (Network network: networks) { + nsxService.deleteFirewallRules(network, aclRulesList); + } + boolean success = true; + for (Network network : networks) { + for (NsxNetworkRule aclRule : aclRulesList) { + success = success && nsxService.addFirewallRules(network, List.of(aclRule)); + } + } + return success; + } + private NsxNetworkRule getNsxNetworkRuleForAcl(NetworkACLItem rule, String privatePort) { + return new NsxNetworkRule.Builder() + .setRuleId(rule.getId()) + .setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY")) + .setAclAction(transformActionValue(rule.getAction())) + .setTrafficType(rule.getTrafficType().toString()) + .setProtocol(rule.getProtocol().toUpperCase()) + .setPublicPort(String.valueOf(rule.getSourcePortStart())) + .setPrivatePort(privatePort) + .setIcmpCode(rule.getIcmpCode()) + .setIcmpType(rule.getIcmpType()) + .setService(Network.Service.NetworkACL) + .build(); } @Override public boolean applyFWRules(Network network, List rules) throws ResourceUnavailableException { @@ -872,6 +889,11 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns return sc.list(); } + @Override + public VirtualRouterProvider.Type getProviderType() { + return VirtualRouterProvider.Type.Nsx; + } + @Override public List> getCommands() { List> cmdList = new ArrayList>(); diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/utils/NsxControllerUtilsTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/utils/NsxControllerUtilsTest.java index 58d7cfc4787..9139fdef68f 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/utils/NsxControllerUtilsTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/utils/NsxControllerUtilsTest.java @@ -30,7 +30,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class NsxControllerUtilsTest { diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 39bb81a17d5..629a6aa312f 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -46,7 +46,9 @@ import com.cloud.dc.VlanDetailsVO; import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.network.dao.NsxProviderDao; import com.cloud.network.dao.PublicIpQuarantineDao; +import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.element.NsxProviderVO; +import com.cloud.network.element.VirtualRouterProviderVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.dao.ServiceOfferingDao; import org.apache.cloudstack.acl.ControlledEntity.ACLType; @@ -84,6 +86,7 @@ import org.apache.cloudstack.network.NetworkPermissionVO; import org.apache.cloudstack.network.dao.NetworkPermissionDao; import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -356,8 +359,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C @Inject HostDao _hostDao; @Inject - InternalLoadBalancerElementService _internalLbElementSvc; - @Inject DataCenterVnetDao _dcVnetDao; @Inject AccountGuestVlanMapDao _accountGuestVlanMapDao; @@ -413,6 +414,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C PublicIpQuarantineDao publicIpQuarantineDao; @Inject NsxProviderDao nsxProviderDao; + @Inject + private VirtualRouterProviderDao virtualRouterProviderDao; + List internalLoadBalancerElementServices = new ArrayList<>(); + Map internalLoadBalancerElementServiceMap = new HashMap<>(); @Autowired @Qualifier("networkHelper") @@ -820,9 +825,19 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C @Override public boolean start() { + initializeInternalLoadBalancerElementsMap(); return true; } + private void initializeInternalLoadBalancerElementsMap() { + if (MapUtils.isEmpty(internalLoadBalancerElementServiceMap) && CollectionUtils.isNotEmpty(internalLoadBalancerElementServices)) { + for (InternalLoadBalancerElementService service : internalLoadBalancerElementServices) { + internalLoadBalancerElementServiceMap.put(service.getProviderType().name(), service); + } + s_logger.debug(String.format("Discovered internal loadbalancer elements configured on NetworkServiceImpl")); + } + } + @Override public boolean stop() { return true; @@ -5420,7 +5435,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C throw new CloudRuntimeException("Unable to find the Network Element implementing the " + Network.Provider.InternalLbVm.getName() + " Provider"); } - _internalLbElementSvc.addInternalLoadBalancerElement(nsp.getId()); + InternalLoadBalancerElementService service = getInternalLoadBalancerElementByNetworkServiceProviderId(nsp.getId()); + service.addInternalLoadBalancerElement(nsp.getId()); return nsp; } @@ -5741,6 +5757,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C _networkGurus = networkGurus; } + public void setInternalLoadBalancerElementServices(List services) { + this.internalLoadBalancerElementServices = services; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_UPDATE, eventDescription = "updating public ip address", async = true) public IpAddress updateIP(Long id, String customId, Boolean displayIp) { @@ -6082,6 +6102,34 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C _ipAddrMgr.removePublicIpAddressFromQuarantine(publicIpQuarantine.getId(), removalReason); } + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementByType(Type type) { + return internalLoadBalancerElementServiceMap.getOrDefault(type.name(), null); + } + + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementByNetworkServiceProviderId(long networkProviderId) { + PhysicalNetworkServiceProviderVO provider = _pNSPDao.findById(networkProviderId); + if (provider == null) { + String msg = String.format("Cannot find a network service provider with ID %s", networkProviderId); + s_logger.error(msg); + throw new CloudRuntimeException(msg); + } + Type type = provider.getProviderName().equalsIgnoreCase("nsx") ? Type.Nsx : Type.InternalLbVm; + return getInternalLoadBalancerElementByType(type); + } + + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementById(long providerId) { + VirtualRouterProviderVO provider = virtualRouterProviderDao.findById(providerId); + return getInternalLoadBalancerElementByType(provider.getType()); + } + + @Override + public List getInternalLoadBalancerElements() { + return new ArrayList<>(this.internalLoadBalancerElementServiceMap.values()); + } + /** * Retrieves the active quarantine for the given public IP address. It can find by the ID of the quarantine or the address of the public IP. * @throws CloudRuntimeException if it does not find an active quarantine for the given public IP. diff --git a/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java index 3d1920bcbc3..b8960629d80 100644 --- a/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java @@ -529,6 +529,11 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc return result; } + @Override + public boolean reorderAclRules(Vpc vpc, List networks, List networkACLItems) { + return true; + } + @Override protected Type getVirtualRouterProvider() { return Type.VPCVirtualRouter; diff --git a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java index bf659320264..d380b33dd52 100644 --- a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -368,6 +368,20 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana return applyACLToPrivateGw(gateway, rules); } + @Override + public boolean reorderAclRules(VpcVO vpc, List networks, List networkACLItems) { + List nsxElements = new ArrayList<>(); + nsxElements.add((NetworkACLServiceProvider) _ntwkModel.getElementImplementingProvider(Network.Provider.Nsx.getName())); + try { + for (final NetworkACLServiceProvider provider : nsxElements) { + return provider.reorderAclRules(vpc, networks, networkACLItems); + } + } catch (final Exception ex) { + s_logger.debug("Failed to reorder ACLs on NSX due to: " + ex.getLocalizedMessage()); + } + return false; + } + private boolean applyACLToPrivateGw(final PrivateGateway gateway, final List rules) throws ResourceUnavailableException { List vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName())); diff --git a/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java index 4d9bded1011..9ff6cf47acc 100644 --- a/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -991,14 +991,26 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ NetworkACLVO lockedAcl = _networkACLDao.acquireInLockTable(ruleBeingMoved.getAclId()); List allAclRules = getAllAclRulesSortedByNumber(lockedAcl.getId()); validateAclConsistency(moveNetworkAclItemCmd, lockedAcl, allAclRules); - + NetworkACLItem networkACLItem = null; if (previousRule == null) { - return moveRuleToTheTop(ruleBeingMoved, allAclRules); + networkACLItem = moveRuleToTheTop(ruleBeingMoved, allAclRules); + } else if (nextRule == null) { + networkACLItem = moveRuleToTheBottom(ruleBeingMoved, allAclRules); + } else { + networkACLItem = moveRuleBetweenAclRules(ruleBeingMoved, allAclRules, previousRule, nextRule); } - if (nextRule == null) { - return moveRuleToTheBottom(ruleBeingMoved, allAclRules); + VpcVO vpc = _vpcDao.findById(lockedAcl.getVpcId()); + if (Objects.isNull(vpc)) { + return networkACLItem; } - return moveRuleBetweenAclRules(ruleBeingMoved, allAclRules, previousRule, nextRule); + final DataCenter dc = _entityMgr.findById(DataCenter.class, vpc.getZoneId()); + final NsxProviderVO nsxProvider = nsxProviderDao.findByZoneId(dc.getId()); + List networks = _networkDao.listByAclId(lockedAcl.getId()); + if (Objects.nonNull(nsxProvider) && !networks.isEmpty()) { + allAclRules = getAllAclRulesSortedByNumber(lockedAcl.getId()); + _networkAclMgr.reorderAclRules(vpc, networks, allAclRules); + } + return networkACLItem; } finally { _networkACLDao.releaseFromLockTable(ruleBeingMoved.getAclId()); } diff --git a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index 9656d544fbb..c80c2947a99 100644 --- a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -165,6 +165,7 @@ + diff --git a/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java b/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java index 0d0deca792a..1f39cf3a97e 100644 --- a/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java +++ b/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java @@ -34,7 +34,6 @@ import java.util.Map; import com.cloud.dc.DataCenter; import com.cloud.exception.PermissionDeniedException; import com.cloud.network.dao.NsxProviderDao; -import com.cloud.network.element.NsxProviderVO; import com.cloud.network.vpc.dao.VpcDao; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ServerApiException; @@ -138,8 +137,6 @@ public class NetworkACLServiceImplTest { private VpcVO vpcVOMock; @Mock DataCenter dataCenterVO; - @Mock - NsxProviderVO nsxProviderVO; @Mock private Account accountMock; diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java index 25fe3e68987..106fc7fa543 100644 --- a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java @@ -26,6 +26,7 @@ import javax.naming.ConfigurationException; import com.cloud.dc.DataCenter; import com.cloud.network.PublicIpQuarantine; +import com.cloud.network.VirtualRouterProvider; import com.cloud.utils.fsm.NoTransitionException; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin; @@ -46,6 +47,7 @@ import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.springframework.stereotype.Component; import com.cloud.deploy.DataCenterDeployment; @@ -1086,4 +1088,24 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches public void removePublicIpAddressFromQuarantine(RemoveQuarantinedIpCmd cmd) { } + + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementByType(VirtualRouterProvider.Type type) { + return null; + } + + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementByNetworkServiceProviderId(long networkProviderId) { + return null; + } + + @Override + public InternalLoadBalancerElementService getInternalLoadBalancerElementById(long providerId) { + return null; + } + + @Override + public List getInternalLoadBalancerElements() { + return null; + } }