diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java index 655bd823325..ec4de6b3ef7 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java @@ -421,7 +421,7 @@ public class NsxResource implements ServerResource { 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())); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java index 20df24f8976..d4ac0e7a7e2 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java @@ -22,6 +22,7 @@ import com.vmware.nsx.model.TransportZone; 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; @@ -44,10 +45,13 @@ import com.vmware.nsx_policy.model.GroupListResult; 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; @@ -95,6 +99,7 @@ import static org.apache.cloudstack.utils.NsxControllerUtils.getVirtualServerNam 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 { @@ -113,6 +118,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"; + 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 } @@ -549,8 +558,10 @@ public class NsxApiClient { } return members; } - public void createNsxLbServerPool(List memberList, String tier1GatewayName, String lbServerPoolName, String algorithm) { + public void createNsxLbServerPool(List memberList, String tier1GatewayName, String lbServerPoolName, + String algorithm, String privatePort, String protocol) { try { + String activeMonitorPath = getLbActiveMonitorPath(lbServerPoolName, privatePort, protocol); List members = getLbPoolMembers(memberList, tier1GatewayName); LbPools lbPools = (LbPools) nsxService.apply(LbPools.class); LBPool lbPool = new LBPool.Builder() @@ -558,6 +569,8 @@ public class NsxApiClient { .setDisplayName(lbServerPoolName) .setAlgorithm(getLoadBalancerAlgorithm(algorithm)) .setMembers(members) + .setPassiveMonitorPath(NSX_LB_PASSIVE_MONITOR) + .setActiveMonitorPaths(List.of(activeMonitorPath)) .build(); lbPools.patch(lbServerPoolName, lbPool); } catch (Error error) { @@ -568,6 +581,32 @@ public class NsxApiClient { } } + 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 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); @@ -593,10 +632,10 @@ public class NsxApiClient { } public void createAndAddNsxLbVirtualServer(String tier1GatewayName, long lbId, String publicIp, String publicPort, - List memberList, String algorithm, String protocol) { + List 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); @@ -632,6 +671,14 @@ public class NsxApiClient { 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 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); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java index 7a4d5cfcc8b..0dd3c8ba1e4 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java @@ -122,6 +122,10 @@ public class NsxControllerUtils { 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"; }