Skip to content

NSX: Add passive monitor for NSX LB to test whether a server is available #8533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ private NsxAnswer executeRequest(CreateNsxLoadBalancerRuleCommand cmd) {
String ruleName = NsxControllerUtils.getLoadBalancerRuleName(tier1GatewayName, cmd.getLbId());
try {
nsxApiClient.createAndAddNsxLbVirtualServer(tier1GatewayName, cmd.getLbId(), cmd.getPublicIp(), cmd.getPublicPort(),
cmd.getMemberList(), cmd.getAlgorithm(), cmd.getProtocol());
cmd.getMemberList(), cmd.getAlgorithm(), cmd.getProtocol(), cmd.getPrivatePort());
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX load balancer rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
Expand Down Expand Up @@ -485,7 +485,7 @@ private NsxAnswer executeRequest(DeleteNsxDistributedFirewallRulesCommand cmd) {
try {
nsxApiClient.deleteDistributedFirewallRules(segmentName, rules);
} catch (Exception e) {
LOGGER.error(String.format("Failed to create NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
LOGGER.error(String.format("Failed to delete NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.vmware.nsx.model.TransportZoneListResult;
import com.vmware.nsx_policy.infra.DhcpRelayConfigs;
import com.vmware.nsx_policy.infra.LbAppProfiles;
import com.vmware.nsx_policy.infra.LbMonitorProfiles;
import com.vmware.nsx_policy.infra.LbPools;
import com.vmware.nsx_policy.infra.LbServices;
import com.vmware.nsx_policy.infra.LbVirtualServers;
Expand All @@ -43,10 +44,13 @@
import com.vmware.nsx_policy.model.ICMPTypeServiceEntry;
import com.vmware.nsx_policy.model.L4PortSetServiceEntry;
import com.vmware.nsx_policy.model.LBAppProfileListResult;
import com.vmware.nsx_policy.model.LBMonitorProfileListResult;
import com.vmware.nsx_policy.model.LBPool;
import com.vmware.nsx_policy.model.LBPoolListResult;
import com.vmware.nsx_policy.model.LBPoolMember;
import com.vmware.nsx_policy.model.LBService;
import com.vmware.nsx_policy.model.LBTcpMonitorProfile;
import com.vmware.nsx_policy.model.LBUdpMonitorProfile;
import com.vmware.nsx_policy.model.LBVirtualServer;
import com.vmware.nsx_policy.model.LBVirtualServerListResult;
import com.vmware.nsx_policy.model.LocaleServicesListResult;
Expand Down Expand Up @@ -93,6 +97,7 @@
import static org.apache.cloudstack.utils.NsxControllerUtils.getServiceEntryName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerAlgorithm;
import static org.apache.cloudstack.utils.NsxControllerUtils.getActiveMonitorProfileName;

public class NsxApiClient {

Expand All @@ -111,6 +116,10 @@ public class NsxApiClient {
protected static final String SEGMENTS_PATH = "/infra/segments";
protected static final String DEFAULT_DOMAIN = "default";
protected static final String GROUPS_PATH_PREFIX = "/infra/domains/default/groups";
// TODO: Pass as global / zone-level setting?
protected static final String NSX_LB_PASSIVE_MONITOR = "/infra/lb-monitor-profiles/default-passive-lb-monitor";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, only this one should be a setting or other paths above as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly for everything, we'd need a better way of handling it that hard-coding it.

protected static final String TCP_MONITOR_PROFILE = "LBTcpMonitorProfile";
protected static final String UDP_MONITOR_PROFILE = "LBUdpMonitorProfile";

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

Expand Down Expand Up @@ -506,15 +515,19 @@ List<LBPoolMember> getLbPoolMembers(List<NsxLoadBalancerMember> memberList, Stri
}
return members;
}
public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String tier1GatewayName, String lbServerPoolName, String algorithm) {
public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String tier1GatewayName, String lbServerPoolName,
String algorithm, String privatePort, String protocol) {
try {
String activeMonitorPath = getLbActiveMonitorPath(lbServerPoolName, privatePort, protocol);
List<LBPoolMember> members = getLbPoolMembers(memberList, tier1GatewayName);
LbPools lbPools = (LbPools) nsxService.apply(LbPools.class);
LBPool lbPool = new LBPool.Builder()
.setId(lbServerPoolName)
.setDisplayName(lbServerPoolName)
.setAlgorithm(getLoadBalancerAlgorithm(algorithm))
.setMembers(members)
.setPassiveMonitorPath(NSX_LB_PASSIVE_MONITOR)
.setActiveMonitorPaths(List.of(activeMonitorPath))
.build();
lbPools.patch(lbServerPoolName, lbPool);
} catch (Error error) {
Expand All @@ -525,6 +538,32 @@ public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String
}
}

private String getLbActiveMonitorPath(String lbServerPoolName, String port, String protocol) {
LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles) nsxService.apply(LbMonitorProfiles.class);
String lbMonitorProfileId = getActiveMonitorProfileName(lbServerPoolName, port, protocol);
if ("TCP".equals(protocol.toUpperCase(Locale.ROOT))) {
LBTcpMonitorProfile lbTcpMonitorProfile = new LBTcpMonitorProfile.Builder(TCP_MONITOR_PROFILE)
.setDisplayName(lbMonitorProfileId)
.setMonitorPort(Long.parseLong(port))
.build();
lbActiveMonitor.patch(lbMonitorProfileId, lbTcpMonitorProfile);
} else if ("UDP".equals(protocol.toUpperCase(Locale.ROOT))) {
LBUdpMonitorProfile lbUdpMonitorProfile = new LBUdpMonitorProfile.Builder(UDP_MONITOR_PROFILE)
.setDisplayName(lbMonitorProfileId)
.setMonitorPort(Long.parseLong(port))
.build();
lbActiveMonitor.patch(lbMonitorProfileId, lbUdpMonitorProfile);
}

LBMonitorProfileListResult listResult = listLBActiveMonitors(lbActiveMonitor);
Optional<Structure> monitorProfile = listResult.getResults().stream().filter(profile -> profile._getDataValue().getField("id").toString().equals(lbMonitorProfileId)).findFirst();
return monitorProfile.map(structure -> structure._getDataValue().getField("path").toString()).orElse(null);
}

LBMonitorProfileListResult listLBActiveMonitors(LbMonitorProfiles lbActiveMonitor) {
return lbActiveMonitor.list(null, false, null, null, null, null);
}

public void createNsxLoadBalancer(String tier1GatewayName) {
try {
String lbName = getLoadBalancerName(tier1GatewayName);
Expand All @@ -550,10 +589,10 @@ public void createNsxLoadBalancer(String tier1GatewayName) {
}

public void createAndAddNsxLbVirtualServer(String tier1GatewayName, long lbId, String publicIp, String publicPort,
List<NsxLoadBalancerMember> memberList, String algorithm, String protocol) {
List<NsxLoadBalancerMember> memberList, String algorithm, String protocol, String privatePort) {
try {
String lbServerPoolName = getServerPoolName(tier1GatewayName, lbId);
createNsxLbServerPool(memberList, tier1GatewayName, lbServerPoolName, algorithm);
createNsxLbServerPool(memberList, tier1GatewayName, lbServerPoolName, algorithm, privatePort, protocol);
createNsxLoadBalancer(tier1GatewayName);

String lbVirtualServerName = getVirtualServerName(tier1GatewayName, lbId);
Expand Down Expand Up @@ -589,6 +628,14 @@ public void deleteNsxLbResources(String tier1GatewayName, long lbId) {
String lbServerPoolName = getServerPoolName(tier1GatewayName, lbId);
lbPools.delete(lbServerPoolName, false);

// delete associated LB Active monitor profile
LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles) nsxService.apply(LbMonitorProfiles.class);
LBMonitorProfileListResult listResult = listLBActiveMonitors(lbActiveMonitor);
List<String> profileIds = listResult.getResults().stream().filter(profile -> profile._getDataValue().getField("id").toString().contains(lbServerPoolName))
.map(profile -> profile._getDataValue().getField("id").toString()).collect(Collectors.toList());
for(String profileId : profileIds) {
lbActiveMonitor.delete(profileId, true);
}
// Delete load balancer
LBVirtualServerListResult lbVsListResult = lbVirtualServers.list(null, null, null, null, null, null);
LBPoolListResult lbPoolListResult = lbPools.list(null, null, null, null, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ public static String getServerPoolName(String tier1GatewayName, long lbId) {
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-SP";
}

public static String getActiveMonitorProfileName(String lbServerPoolName, String port, String protocol) {
return lbServerPoolName + "-" + protocol + "-" + port + "-AM";
}

public static String getVirtualServerName(String tier1GatewayName, long lbId) {
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-VS";
}
Expand Down