Skip to content

Commit 9313d39

Browse files
Pearl1594nvazquez
andcommitted
Nsx: Support internal LB (#4)
* NSX: Support internal LB service in NSX * add lb removal logic * Fix UI issue hiding internal LB tab * Refactor method name --------- Co-authored-by: nvazquez <[email protected]>
1 parent 8beaa44 commit 9313d39

File tree

14 files changed

+176
-18
lines changed

14 files changed

+176
-18
lines changed

api/src/main/java/com/cloud/network/VirtualRouterProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
public interface VirtualRouterProvider extends InternalIdentity, Identity {
2323
public enum Type {
24-
VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, NetScalerVm
24+
VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, NetScalerVm, Nsx
2525
}
2626

2727
public Type getType();

api/src/main/java/com/cloud/offering/NetworkOffering.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public enum NsxMode {
5858
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
5959
public static final String DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE = "DefaultTungstenSharedNetworkOfferingWithSGService";
6060
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC = "DefaultNATNSXNetworkOfferingForVpc";
61+
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC_WITH_ILB = "DefaultNATNSXNetworkOfferingForVpcWithInternalLB";
6162
public static final String DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC = "DefaultRoutedNSXNetworkOfferingForVpc";
6263
public static final String DEFAULT_NAT_NSX_OFFERING = "DefaultNATNSXNetworkOffering";
6364
public static final String DEFAULT_ROUTED_NSX_OFFERING = "DefaultRoutedNSXNetworkOffering";

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ public class ApiConstants {
825825
public static final String FOR_VPC = "forvpc";
826826
public static final String FOR_NSX = "fornsx";
827827
public static final String NSX_SUPPORT_LB = "nsxsupportlb";
828+
public static final String NSX_SUPPORTS_INTERNAL_LB = "nsxsupportsinternallb";
828829
public static final String FOR_TUNGSTEN = "fortungsten";
829830
public static final String SHRINK_OK = "shrinkok";
830831
public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
@@ -963,6 +964,7 @@ public class ApiConstants {
963964
public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc";
964965
public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet";
965966
public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
967+
public static final String SUPPORTS_INTERNAL_LB = "supportsinternallb";
966968
public static final String SUPPORTS_VM_AUTOSCALING = "supportsvmautoscaling";
967969
public static final String REGION_LEVEL_VPC = "regionlevelvpc";
968970
public static final String STRECHED_L2_SUBNET = "strechedl2subnet";

api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
160160
since = "4.20.0")
161161
private Boolean nsxSupportsLbService;
162162

163+
@Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
164+
type = CommandType.BOOLEAN,
165+
description = "true if network offering for NSX network offering supports Internal Load balancer service.",
166+
since = "4.20.0")
167+
private Boolean nsxSupportsInternalLbService;
168+
163169
@Parameter(name = ApiConstants.FOR_TUNGSTEN,
164170
type = CommandType.BOOLEAN,
165171
description = "true if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
@@ -306,6 +312,10 @@ public boolean getNsxSupportsLbService() {
306312
return BooleanUtils.isTrue(nsxSupportsLbService);
307313
}
308314

315+
public boolean getNsxSupportsInternalLbService() {
316+
return BooleanUtils.isTrue(nsxSupportsInternalLbService);
317+
}
318+
309319
public Boolean getForTungsten() {
310320
return forTungsten;
311321
}

api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations {
135135
@Param(description = "true if network offering supports public access for guest networks", since = "4.10.0")
136136
private Boolean supportsPublicAccess;
137137

138+
@SerializedName(ApiConstants.SUPPORTS_INTERNAL_LB)
139+
@Param(description = "true if network offering supports public access for guest networks", since = "4.20.0")
140+
private Boolean supportsInternalLb;
141+
138142
@SerializedName(ApiConstants.DOMAIN_ID)
139143
@Param(description = "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.")
140144
private String domainId;
@@ -259,6 +263,10 @@ public void setSupportsPublicAccess(Boolean supportsPublicAccess) {
259263
this.supportsPublicAccess = supportsPublicAccess;
260264
}
261265

266+
public void setSupportsInternalLb(Boolean supportsInternalLb) {
267+
this.supportsInternalLb = supportsInternalLb;
268+
}
269+
262270
public String getDomainId() {
263271
return domainId;
264272
}

plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,9 @@ private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) {
308308

309309
private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) {
310310
String tier1Id = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
311+
String lbName = NsxControllerUtils.getLoadBalancerName(tier1Id);
311312
try {
313+
nsxApiClient.deleteLoadBalancer(lbName);
312314
nsxApiClient.deleteTier1Gateway(tier1Id);
313315
} catch (Exception e) {
314316
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));

plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,7 @@ public void deleteNsxLbResources(String tier1GatewayName, long lbId) {
707707
LBPoolListResult lbPoolListResult = lbPools.list(null, null, null, null, null, null);
708708
if (CollectionUtils.isEmpty(lbVsListResult.getResults()) && CollectionUtils.isEmpty(lbPoolListResult.getResults())) {
709709
String lbName = getLoadBalancerName(tier1GatewayName);
710-
LbServices lbServices = (LbServices) nsxService.apply(LbServices.class);
711-
lbServices.delete(lbName, true);
710+
deleteLoadBalancer(lbName);
712711
}
713712

714713
} catch (Error error) {
@@ -719,6 +718,11 @@ public void deleteNsxLbResources(String tier1GatewayName, long lbId) {
719718
}
720719
}
721720

721+
public void deleteLoadBalancer(String lbName) {
722+
LbServices lbServices = (LbServices) nsxService.apply(LbServices.class);
723+
lbServices.delete(lbName, true);
724+
}
725+
722726
private String getLbPoolPath(String lbPoolName) {
723727
try {
724728
LbPools lbPools = (LbPools) nsxService.apply(LbPools.class);

plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@
4444
import com.cloud.network.Networks;
4545
import com.cloud.network.PhysicalNetworkServiceProvider;
4646
import com.cloud.network.PublicIpAddress;
47+
import com.cloud.network.VirtualRouterProvider;
4748
import com.cloud.network.dao.IPAddressDao;
4849
import com.cloud.network.dao.IPAddressVO;
4950
import com.cloud.network.dao.LoadBalancerVMMapDao;
5051
import com.cloud.network.dao.LoadBalancerVMMapVO;
5152
import com.cloud.network.dao.NetworkDao;
5253
import com.cloud.network.dao.NetworkVO;
5354
import com.cloud.network.dao.PhysicalNetworkDao;
55+
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
5456
import com.cloud.network.dao.PhysicalNetworkVO;
57+
import com.cloud.network.dao.VirtualRouterProviderDao;
5558
import com.cloud.network.element.DhcpServiceProvider;
5659
import com.cloud.network.element.DnsServiceProvider;
5760
import com.cloud.network.element.FirewallServiceProvider;
@@ -60,9 +63,12 @@
6063
import com.cloud.network.element.NetworkACLServiceProvider;
6164
import com.cloud.network.element.PortForwardingServiceProvider;
6265
import com.cloud.network.element.StaticNatServiceProvider;
66+
import com.cloud.network.element.VirtualRouterElement;
67+
import com.cloud.network.element.VirtualRouterProviderVO;
6368
import com.cloud.network.element.VpcProvider;
6469
import com.cloud.network.lb.LoadBalancingRule;
6570
import com.cloud.network.rules.FirewallRule;
71+
import com.cloud.network.rules.LoadBalancerContainer;
6672
import com.cloud.network.rules.PortForwardingRule;
6773
import com.cloud.network.rules.StaticNat;
6874
import com.cloud.network.vpc.NetworkACLItem;
@@ -82,6 +88,8 @@
8288
import com.cloud.uservm.UserVm;
8389
import com.cloud.utils.Pair;
8490
import com.cloud.utils.component.AdapterBase;
91+
import com.cloud.utils.db.QueryBuilder;
92+
import com.cloud.utils.db.SearchCriteria;
8593
import com.cloud.utils.exception.CloudRuntimeException;
8694
import com.cloud.vm.NicProfile;
8795
import com.cloud.vm.ReservationContext;
@@ -90,6 +98,10 @@
9098
import com.cloud.vm.dao.VMInstanceDao;
9199
import net.sf.ehcache.config.InvalidConfigurationException;
92100
import org.apache.cloudstack.StartupNsxCommand;
101+
import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
102+
import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
103+
import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
104+
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
93105
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
94106
import org.apache.cloudstack.resource.NsxNetworkRule;
95107
import org.apache.cloudstack.resource.NsxOpObject;
@@ -111,7 +123,7 @@
111123
@Component
112124
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
113125
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
114-
LoadBalancingServiceProvider, FirewallServiceProvider, ResourceStateAdapter, Listener {
126+
LoadBalancingServiceProvider, FirewallServiceProvider, InternalLoadBalancerElementService, ResourceStateAdapter, Listener {
115127

116128

117129
@Inject
@@ -142,6 +154,10 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
142154
VpcDao vpcDao;
143155
@Inject
144156
LoadBalancerVMMapDao lbVmMapDao;
157+
@Inject
158+
VirtualRouterProviderDao vrProviderDao;
159+
@Inject
160+
PhysicalNetworkServiceProviderDao pNtwkSvcProviderDao;
145161

146162
private static final Logger LOGGER = Logger.getLogger(NsxElement.class);
147163

@@ -159,7 +175,16 @@ private static Map<Network.Service, Map<Network.Capability, String>> initCapabil
159175
capabilities.put(Network.Service.Dns, dnsCapabilities);
160176

161177
capabilities.put(Network.Service.StaticNat, null);
162-
capabilities.put(Network.Service.Lb, null);
178+
179+
// Set capabilities for LB service
180+
Map<Network.Capability, String> lbCapabilities = new HashMap<Network.Capability, String>();
181+
lbCapabilities.put(Network.Capability.SupportedLBAlgorithms, "roundrobin,leastconn");
182+
lbCapabilities.put(Network.Capability.SupportedLBIsolation, "dedicated");
183+
lbCapabilities.put(Network.Capability.SupportedProtocols, "tcp, udp");
184+
lbCapabilities.put(Network.Capability.SupportedStickinessMethods, VirtualRouterElement.getHAProxyStickinessCapability());
185+
lbCapabilities.put(Network.Capability.LbSchemes, String.join(",", LoadBalancerContainer.Scheme.Internal.name(), LoadBalancerContainer.Scheme.Public.name()));
186+
187+
capabilities.put(Network.Service.Lb, lbCapabilities);
163188
capabilities.put(Network.Service.PortForwarding, null);
164189
capabilities.put(Network.Service.NetworkACL, null);
165190

@@ -633,7 +658,8 @@ public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) thro
633658
.setNetworkResourceName(nsxObject.getNetworkResourceName())
634659
.setVpcResource(nsxObject.isVpcResource())
635660
.setMemberList(lbMembers)
636-
.setPublicIp(publicIp.getAddress().addr())
661+
.setPublicIp(LoadBalancerContainer.Scheme.Public == loadBalancingRule.getScheme() ?
662+
publicIp.getAddress().addr() : loadBalancingRule.getSourceIp().addr())
637663
.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()))
638664
.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()))
639665
.setRuleId(loadBalancingRule.getId())
@@ -778,4 +804,74 @@ protected List<String> transformCidrListValues(List<String> sourceCidrList) {
778804
}
779805
return list;
780806
}
807+
808+
@Override
809+
public VirtualRouterProvider configureInternalLoadBalancerElement(long id, boolean enable) {
810+
VirtualRouterProviderVO element = vrProviderDao.findById(id);
811+
if (element == null || element.getType() != VirtualRouterProvider.Type.Nsx) {
812+
throw new InvalidParameterValueException("Can't find " + getName() + " " +
813+
"element with network service provider id " + id + " to be used as a provider for " +
814+
getName());
815+
}
816+
817+
element.setEnabled(enable);
818+
element = vrProviderDao.persist(element);
819+
820+
return element;
821+
}
822+
823+
@Override
824+
public VirtualRouterProvider addInternalLoadBalancerElement(long ntwkSvcProviderId) {
825+
VirtualRouterProviderVO element = vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, VirtualRouterProvider.Type.Nsx);
826+
if (element != null) {
827+
LOGGER.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId);
828+
return null;
829+
}
830+
831+
PhysicalNetworkServiceProvider provider = pNtwkSvcProviderDao.findById(ntwkSvcProviderId);
832+
if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) {
833+
throw new InvalidParameterValueException("Invalid network service provider is specified");
834+
}
835+
836+
element = new VirtualRouterProviderVO(ntwkSvcProviderId, VirtualRouterProvider.Type.Nsx);
837+
element = vrProviderDao.persist(element);
838+
return element;
839+
}
840+
841+
@Override
842+
public VirtualRouterProvider getInternalLoadBalancerElement(long id) {
843+
VirtualRouterProvider provider = vrProviderDao.findById(id);
844+
if (provider == null || provider.getType() != VirtualRouterProvider.Type.Nsx) {
845+
throw new InvalidParameterValueException("Unable to find " + getName() + " by id");
846+
}
847+
return provider;
848+
}
849+
850+
@Override
851+
public List<? extends VirtualRouterProvider> searchForInternalLoadBalancerElements(Long id, Long ntwkSvsProviderId, Boolean enabled) {
852+
QueryBuilder<VirtualRouterProviderVO> sc = QueryBuilder.create(VirtualRouterProviderVO.class);
853+
if (id != null) {
854+
sc.and(sc.entity().getId(), SearchCriteria.Op.EQ, id);
855+
}
856+
if (ntwkSvsProviderId != null) {
857+
sc.and(sc.entity().getNspId(), SearchCriteria.Op.EQ, ntwkSvsProviderId);
858+
}
859+
if (enabled != null) {
860+
sc.and(sc.entity().isEnabled(), SearchCriteria.Op.EQ, enabled);
861+
}
862+
863+
//return only Internal LB elements
864+
sc.and(sc.entity().getType(), SearchCriteria.Op.EQ, VirtualRouterProvider.Type.Nsx);
865+
866+
return sc.list();
867+
}
868+
869+
@Override
870+
public List<Class<?>> getCommands() {
871+
List<Class<?>> cmdList = new ArrayList<Class<?>>();
872+
cmdList.add(CreateInternalLoadBalancerElementCmd.class);
873+
cmdList.add(ConfigureInternalLoadBalancerElementCmd.class);
874+
cmdList.add(ListInternalLoadBalancerElementsCmd.class);
875+
return cmdList;
876+
}
781877
}

server/src/main/java/com/cloud/api/query/dao/NetworkOfferingJoinDaoImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public NetworkOfferingResponse newNetworkOfferingResponse(NetworkOffering offeri
108108
networkOfferingResponse.setConcurrentConnections(offering.getConcurrentConnections());
109109
networkOfferingResponse.setSupportsStrechedL2Subnet(offering.isSupportingStrechedL2());
110110
networkOfferingResponse.setSupportsPublicAccess(offering.isSupportingPublicAccess());
111+
networkOfferingResponse.setSupportsInternalLb(offering.isInternalLb());
111112
networkOfferingResponse.setCreated(offering.getCreated());
112113
if (offering.getGuestType() != null) {
113114
networkOfferingResponse.setGuestIpType(offering.getGuestType().toString());

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5956,6 +5956,7 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd)
59565956
Boolean forNsx = cmd.isForNsx();
59575957
Boolean forTungsten = cmd.getForTungsten();
59585958
String nsxMode = cmd.getNsxMode();
5959+
boolean nsxSupportInternalLbSvc = cmd.getNsxSupportsInternalLbService();
59595960
Integer maxconn = null;
59605961
boolean enableKeepAlive = false;
59615962
String servicePackageuuid = cmd.getServicePackageId();
@@ -6274,6 +6275,11 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd)
62746275

62756276
final NetworkOfferingVO offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false,
62766277
serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, forTungsten, forNsx, nsxMode, domainIds, zoneIds, enable, internetProtocol);
6278+
if (Boolean.TRUE.equals(forNsx) && nsxSupportInternalLbSvc) {
6279+
offering.setInternalLb(true);
6280+
offering.setPublicLb(false);
6281+
_networkOfferingDao.update(offering.getId(), offering);
6282+
}
62776283
CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
62786284
CallContext.current().putContextParameter(NetworkOffering.class, offering.getId());
62796285
return offering;

0 commit comments

Comments
 (0)