Skip to content

Commit 19ae12a

Browse files
authored
NSX: Add passive monitor for NSX LB to test whether a server is available (#8533)
* NSX: Add passive monitor for NSX LB to test whether a server is available * Add active monitors too * fix build failure
1 parent f01bb5d commit 19ae12a

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ private NsxAnswer executeRequest(CreateNsxLoadBalancerRuleCommand cmd) {
421421
String ruleName = NsxControllerUtils.getLoadBalancerRuleName(tier1GatewayName, cmd.getLbId());
422422
try {
423423
nsxApiClient.createAndAddNsxLbVirtualServer(tier1GatewayName, cmd.getLbId(), cmd.getPublicIp(), cmd.getPublicPort(),
424-
cmd.getMemberList(), cmd.getAlgorithm(), cmd.getProtocol());
424+
cmd.getMemberList(), cmd.getAlgorithm(), cmd.getProtocol(), cmd.getPrivatePort());
425425
} catch (Exception e) {
426426
LOGGER.error(String.format("Failed to add NSX load balancer rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
427427
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));

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

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.vmware.nsx.model.TransportZoneListResult;
2323
import com.vmware.nsx_policy.infra.DhcpRelayConfigs;
2424
import com.vmware.nsx_policy.infra.LbAppProfiles;
25+
import com.vmware.nsx_policy.infra.LbMonitorProfiles;
2526
import com.vmware.nsx_policy.infra.LbPools;
2627
import com.vmware.nsx_policy.infra.LbServices;
2728
import com.vmware.nsx_policy.infra.LbVirtualServers;
@@ -44,10 +45,13 @@
4445
import com.vmware.nsx_policy.model.ICMPTypeServiceEntry;
4546
import com.vmware.nsx_policy.model.L4PortSetServiceEntry;
4647
import com.vmware.nsx_policy.model.LBAppProfileListResult;
48+
import com.vmware.nsx_policy.model.LBMonitorProfileListResult;
4749
import com.vmware.nsx_policy.model.LBPool;
4850
import com.vmware.nsx_policy.model.LBPoolListResult;
4951
import com.vmware.nsx_policy.model.LBPoolMember;
5052
import com.vmware.nsx_policy.model.LBService;
53+
import com.vmware.nsx_policy.model.LBTcpMonitorProfile;
54+
import com.vmware.nsx_policy.model.LBUdpMonitorProfile;
5155
import com.vmware.nsx_policy.model.LBVirtualServer;
5256
import com.vmware.nsx_policy.model.LBVirtualServerListResult;
5357
import com.vmware.nsx_policy.model.LocaleServicesListResult;
@@ -95,6 +99,7 @@
9599
import static org.apache.cloudstack.utils.NsxControllerUtils.getServiceEntryName;
96100
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerName;
97101
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerAlgorithm;
102+
import static org.apache.cloudstack.utils.NsxControllerUtils.getActiveMonitorProfileName;
98103

99104
public class NsxApiClient {
100105

@@ -113,6 +118,10 @@ public class NsxApiClient {
113118
protected static final String SEGMENTS_PATH = "/infra/segments";
114119
protected static final String DEFAULT_DOMAIN = "default";
115120
protected static final String GROUPS_PATH_PREFIX = "/infra/domains/default/groups";
121+
// TODO: Pass as global / zone-level setting?
122+
protected static final String NSX_LB_PASSIVE_MONITOR = "/infra/lb-monitor-profiles/default-passive-lb-monitor";
123+
protected static final String TCP_MONITOR_PROFILE = "LBTcpMonitorProfile";
124+
protected static final String UDP_MONITOR_PROFILE = "LBUdpMonitorProfile";
116125

117126
private enum PoolAllocation { ROUTING, LB_SMALL, LB_MEDIUM, LB_LARGE, LB_XLARGE }
118127

@@ -549,15 +558,19 @@ List<LBPoolMember> getLbPoolMembers(List<NsxLoadBalancerMember> memberList, Stri
549558
}
550559
return members;
551560
}
552-
public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String tier1GatewayName, String lbServerPoolName, String algorithm) {
561+
public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String tier1GatewayName, String lbServerPoolName,
562+
String algorithm, String privatePort, String protocol) {
553563
try {
564+
String activeMonitorPath = getLbActiveMonitorPath(lbServerPoolName, privatePort, protocol);
554565
List<LBPoolMember> members = getLbPoolMembers(memberList, tier1GatewayName);
555566
LbPools lbPools = (LbPools) nsxService.apply(LbPools.class);
556567
LBPool lbPool = new LBPool.Builder()
557568
.setId(lbServerPoolName)
558569
.setDisplayName(lbServerPoolName)
559570
.setAlgorithm(getLoadBalancerAlgorithm(algorithm))
560571
.setMembers(members)
572+
.setPassiveMonitorPath(NSX_LB_PASSIVE_MONITOR)
573+
.setActiveMonitorPaths(List.of(activeMonitorPath))
561574
.build();
562575
lbPools.patch(lbServerPoolName, lbPool);
563576
} catch (Error error) {
@@ -568,6 +581,32 @@ public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String
568581
}
569582
}
570583

584+
private String getLbActiveMonitorPath(String lbServerPoolName, String port, String protocol) {
585+
LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles) nsxService.apply(LbMonitorProfiles.class);
586+
String lbMonitorProfileId = getActiveMonitorProfileName(lbServerPoolName, port, protocol);
587+
if ("TCP".equals(protocol.toUpperCase(Locale.ROOT))) {
588+
LBTcpMonitorProfile lbTcpMonitorProfile = new LBTcpMonitorProfile.Builder(TCP_MONITOR_PROFILE)
589+
.setDisplayName(lbMonitorProfileId)
590+
.setMonitorPort(Long.parseLong(port))
591+
.build();
592+
lbActiveMonitor.patch(lbMonitorProfileId, lbTcpMonitorProfile);
593+
} else if ("UDP".equals(protocol.toUpperCase(Locale.ROOT))) {
594+
LBUdpMonitorProfile lbUdpMonitorProfile = new LBUdpMonitorProfile.Builder(UDP_MONITOR_PROFILE)
595+
.setDisplayName(lbMonitorProfileId)
596+
.setMonitorPort(Long.parseLong(port))
597+
.build();
598+
lbActiveMonitor.patch(lbMonitorProfileId, lbUdpMonitorProfile);
599+
}
600+
601+
LBMonitorProfileListResult listResult = listLBActiveMonitors(lbActiveMonitor);
602+
Optional<Structure> monitorProfile = listResult.getResults().stream().filter(profile -> profile._getDataValue().getField("id").toString().equals(lbMonitorProfileId)).findFirst();
603+
return monitorProfile.map(structure -> structure._getDataValue().getField("path").toString()).orElse(null);
604+
}
605+
606+
LBMonitorProfileListResult listLBActiveMonitors(LbMonitorProfiles lbActiveMonitor) {
607+
return lbActiveMonitor.list(null, false, null, null, null, null);
608+
}
609+
571610
public void createNsxLoadBalancer(String tier1GatewayName) {
572611
try {
573612
String lbName = getLoadBalancerName(tier1GatewayName);
@@ -593,10 +632,10 @@ public void createNsxLoadBalancer(String tier1GatewayName) {
593632
}
594633

595634
public void createAndAddNsxLbVirtualServer(String tier1GatewayName, long lbId, String publicIp, String publicPort,
596-
List<NsxLoadBalancerMember> memberList, String algorithm, String protocol) {
635+
List<NsxLoadBalancerMember> memberList, String algorithm, String protocol, String privatePort) {
597636
try {
598637
String lbServerPoolName = getServerPoolName(tier1GatewayName, lbId);
599-
createNsxLbServerPool(memberList, tier1GatewayName, lbServerPoolName, algorithm);
638+
createNsxLbServerPool(memberList, tier1GatewayName, lbServerPoolName, algorithm, privatePort, protocol);
600639
createNsxLoadBalancer(tier1GatewayName);
601640

602641
String lbVirtualServerName = getVirtualServerName(tier1GatewayName, lbId);
@@ -632,6 +671,14 @@ public void deleteNsxLbResources(String tier1GatewayName, long lbId) {
632671
String lbServerPoolName = getServerPoolName(tier1GatewayName, lbId);
633672
lbPools.delete(lbServerPoolName, false);
634673

674+
// delete associated LB Active monitor profile
675+
LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles) nsxService.apply(LbMonitorProfiles.class);
676+
LBMonitorProfileListResult listResult = listLBActiveMonitors(lbActiveMonitor);
677+
List<String> profileIds = listResult.getResults().stream().filter(profile -> profile._getDataValue().getField("id").toString().contains(lbServerPoolName))
678+
.map(profile -> profile._getDataValue().getField("id").toString()).collect(Collectors.toList());
679+
for(String profileId : profileIds) {
680+
lbActiveMonitor.delete(profileId, true);
681+
}
635682
// Delete load balancer
636683
LBVirtualServerListResult lbVsListResult = lbVirtualServers.list(null, null, null, null, null, null);
637684
LBPoolListResult lbPoolListResult = lbPools.list(null, null, null, null, null, null);

plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ public static String getServerPoolName(String tier1GatewayName, long lbId) {
122122
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-SP";
123123
}
124124

125+
public static String getActiveMonitorProfileName(String lbServerPoolName, String port, String protocol) {
126+
return lbServerPoolName + "-" + protocol + "-" + port + "-AM";
127+
}
128+
125129
public static String getVirtualServerName(String tier1GatewayName, long lbId) {
126130
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-VS";
127131
}

0 commit comments

Comments
 (0)