|
18 | 18 |
|
19 | 19 | import com.cloud.network.Network; |
20 | 20 | import com.cloud.network.SDNProviderNetworkRule; |
| 21 | +import com.cloud.utils.exception.CloudRuntimeException; |
21 | 22 | import com.vmware.nsx.cluster.Status; |
22 | 23 | import com.vmware.nsx.model.ClusterStatus; |
23 | 24 | import com.vmware.nsx.model.ControllerClusterStatus; |
| 25 | +import com.vmware.nsx_policy.infra.LbMonitorProfiles; |
| 26 | +import com.vmware.nsx_policy.infra.LbPools; |
| 27 | +import com.vmware.nsx_policy.infra.LbServices; |
| 28 | +import com.vmware.nsx_policy.infra.LbVirtualServers; |
24 | 29 | import com.vmware.nsx_policy.infra.domains.Groups; |
| 30 | +import com.vmware.nsx_policy.model.ApiError; |
25 | 31 | import com.vmware.nsx_policy.model.Group; |
| 32 | +import com.vmware.nsx_policy.model.LBIcmpMonitorProfile; |
| 33 | +import com.vmware.nsx_policy.model.LBTcpMonitorProfile; |
| 34 | +import com.vmware.nsx_policy.model.LBPool; |
| 35 | +import com.vmware.nsx_policy.model.LBPoolMember; |
| 36 | +import com.vmware.nsx_policy.model.LBVirtualServer; |
26 | 37 | import com.vmware.nsx_policy.model.PathExpression; |
27 | 38 | import com.vmware.vapi.bindings.Service; |
| 39 | +import com.vmware.vapi.bindings.Structure; |
| 40 | +import com.vmware.vapi.std.errors.Error; |
| 41 | +import com.vmware.vapi.std.errors.NotFound; |
| 42 | +import org.apache.cloudstack.resource.NsxLoadBalancerMember; |
| 43 | +import org.apache.cloudstack.utils.NsxControllerUtils; |
28 | 44 | import org.junit.Assert; |
29 | 45 | import org.junit.Before; |
30 | 46 | import org.junit.Test; |
|
36 | 52 | import java.util.List; |
37 | 53 | import java.util.function.Function; |
38 | 54 |
|
| 55 | +import static org.junit.Assert.assertThrows; |
| 56 | +import static org.junit.Assert.assertTrue; |
| 57 | +import static org.mockito.ArgumentMatchers.any; |
| 58 | +import static org.mockito.ArgumentMatchers.anyString; |
| 59 | +import static org.mockito.ArgumentMatchers.eq; |
| 60 | +import static org.mockito.Mockito.doThrow; |
| 61 | +import static org.mockito.Mockito.never; |
| 62 | +import static org.mockito.Mockito.verify; |
| 63 | +import static org.mockito.Mockito.when; |
| 64 | + |
39 | 65 | public class NsxApiClientTest { |
40 | 66 |
|
| 67 | + private static final String TIER_1_GATEWAY_NAME = "t1"; |
| 68 | + |
41 | 69 | @Mock |
42 | 70 | private Function<Class<? extends Service>, Service> nsxService; |
43 | 71 | @Mock |
@@ -108,4 +136,201 @@ public void testIsNsxControllerActive() { |
108 | 136 | Mockito.when(clusterStatus.getControlClusterStatus()).thenReturn(status); |
109 | 137 | Assert.assertTrue(client.isNsxControllerActive()); |
110 | 138 | } |
| 139 | + |
| 140 | + @Test |
| 141 | + public void testCreateNsxLbServerPoolExistingMonitorProfileSkipsMonitorPatch() { |
| 142 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L); |
| 143 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 144 | + |
| 145 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 146 | + LbMonitorProfiles lbMonitorProfiles = mockLbMonitorProfiles(); |
| 147 | + |
| 148 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 149 | + Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new NotFound(null, null)); |
| 150 | + |
| 151 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 152 | + |
| 153 | + verify(lbMonitorProfiles, never()).patch(anyString(), any(LBTcpMonitorProfile.class)); |
| 154 | + verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 155 | + } |
| 156 | + |
| 157 | + @Test |
| 158 | + public void testCreateNsxLbServerPoolMissingMonitorTCPProfilePerformsPatch() { |
| 159 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L); |
| 160 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 161 | + |
| 162 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 163 | + LbMonitorProfiles lbMonitorProfiles = Mockito.mock(LbMonitorProfiles.class); |
| 164 | + Structure monitorStructure = Mockito.mock(Structure.class, Mockito.RETURNS_DEEP_STUBS); |
| 165 | + |
| 166 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 167 | + Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles); |
| 168 | + Mockito.when(lbMonitorProfiles.get(anyString())).thenThrow(new NotFound(null, null)).thenReturn(monitorStructure); |
| 169 | + Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test"); |
| 170 | + Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new NotFound(null, null)); |
| 171 | + |
| 172 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 173 | + |
| 174 | + verify(lbMonitorProfiles).patch(anyString(), any(LBTcpMonitorProfile.class)); |
| 175 | + verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 176 | + } |
| 177 | + |
| 178 | + @Test |
| 179 | + public void testCreateNsxLbServerPoolMissingMonitorUDPProfilePerformsPatch() { |
| 180 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L); |
| 181 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 182 | + |
| 183 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 184 | + LbMonitorProfiles lbMonitorProfiles = Mockito.mock(LbMonitorProfiles.class); |
| 185 | + Structure monitorStructure = Mockito.mock(Structure.class, Mockito.RETURNS_DEEP_STUBS); |
| 186 | + |
| 187 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 188 | + Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles); |
| 189 | + Mockito.when(lbMonitorProfiles.get(anyString())).thenThrow(new NotFound(null, null)).thenReturn(monitorStructure); |
| 190 | + Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test"); |
| 191 | + Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new NotFound(null, null)); |
| 192 | + |
| 193 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "UDP"); |
| 194 | + |
| 195 | + verify(lbMonitorProfiles).patch(anyString(), any(LBIcmpMonitorProfile.class)); |
| 196 | + verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 197 | + } |
| 198 | + |
| 199 | + @Test |
| 200 | + public void testCreateNsxLbServerPoolPoolExistsWithSameMembersSkipsPatch() { |
| 201 | + long lbId = 1L; |
| 202 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId); |
| 203 | + List<NsxLoadBalancerMember> memberList = List.of( |
| 204 | + new NsxLoadBalancerMember(1L, "10.0.0.1", 80), |
| 205 | + new NsxLoadBalancerMember(2L, "10.0.0.2", 80) |
| 206 | + ); |
| 207 | + List<LBPoolMember> sameMembers = List.of( |
| 208 | + new LBPoolMember.Builder() |
| 209 | + .setDisplayName(NsxControllerUtils.getServerPoolMemberName(TIER_1_GATEWAY_NAME, 2L)) |
| 210 | + .setIpAddress("10.0.0.2") |
| 211 | + .setPort("80") |
| 212 | + .build(), |
| 213 | + new LBPoolMember.Builder() |
| 214 | + .setDisplayName(NsxControllerUtils.getServerPoolMemberName(TIER_1_GATEWAY_NAME, 1L)) |
| 215 | + .setIpAddress("10.0.0.1") |
| 216 | + .setPort("80") |
| 217 | + .build() |
| 218 | + ); |
| 219 | + |
| 220 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 221 | + LBPool existingPool = Mockito.mock(LBPool.class); |
| 222 | + |
| 223 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 224 | + Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool); |
| 225 | + Mockito.when(existingPool.getMembers()).thenReturn(sameMembers); |
| 226 | + |
| 227 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 228 | + |
| 229 | + verify(nsxService, never()).apply(LbMonitorProfiles.class); |
| 230 | + verify(lbPools, never()).patch(anyString(), any(LBPool.class)); |
| 231 | + } |
| 232 | + |
| 233 | + @Test |
| 234 | + public void testCreateNsxLbServerPoolPoolExistsWithDifferentMembersPerformsPatch() { |
| 235 | + long lbId = 1L; |
| 236 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId); |
| 237 | + List<NsxLoadBalancerMember> memberList = List.of( |
| 238 | + new NsxLoadBalancerMember(1L, "10.0.0.1", 80), |
| 239 | + new NsxLoadBalancerMember(2L, "10.0.0.2", 80) |
| 240 | + ); |
| 241 | + |
| 242 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 243 | + LBPool existingPool = Mockito.mock(LBPool.class); |
| 244 | + |
| 245 | + mockLbMonitorProfiles(); |
| 246 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 247 | + Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool); |
| 248 | + Mockito.when(existingPool.getMembers()).thenReturn(List.of( |
| 249 | + new LBPoolMember.Builder() |
| 250 | + .setDisplayName(NsxControllerUtils.getServerPoolMemberName(TIER_1_GATEWAY_NAME, 1L)) |
| 251 | + .setIpAddress("10.0.0.10") |
| 252 | + .setPort("80") |
| 253 | + .build() |
| 254 | + )); |
| 255 | + |
| 256 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 257 | + |
| 258 | + verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 259 | + } |
| 260 | + |
| 261 | + @Test |
| 262 | + public void testCreateNsxLbServerPoolPoolDoesNotExistPerformsPatch() { |
| 263 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L); |
| 264 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 265 | + |
| 266 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 267 | + |
| 268 | + mockLbMonitorProfiles(); |
| 269 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 270 | + Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new NotFound(null, null)); |
| 271 | + |
| 272 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 273 | + |
| 274 | + verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 275 | + } |
| 276 | + |
| 277 | + @Test |
| 278 | + public void testCreateAndAddNsxLbVirtualServerVirtualServerAlreadyExistsSkipsPatch() { |
| 279 | + long lbId = 1L; |
| 280 | + String lbVirtualServerName = NsxControllerUtils.getVirtualServerName(TIER_1_GATEWAY_NAME, lbId); |
| 281 | + String lbServiceName = NsxControllerUtils.getLoadBalancerName(TIER_1_GATEWAY_NAME); |
| 282 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 283 | + |
| 284 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 285 | + LbServices lbServices = Mockito.mock(LbServices.class); |
| 286 | + LbVirtualServers lbVirtualServers = Mockito.mock(LbVirtualServers.class); |
| 287 | + LBVirtualServer existingVs = Mockito.mock(LBVirtualServer.class); |
| 288 | + |
| 289 | + mockLbMonitorProfiles(); |
| 290 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 291 | + Mockito.when(nsxService.apply(LbServices.class)).thenReturn(lbServices); |
| 292 | + Mockito.when(nsxService.apply(LbVirtualServers.class)).thenReturn(lbVirtualServers); |
| 293 | + Mockito.when(lbPools.get(anyString())).thenThrow(new NotFound(null, null)); |
| 294 | + Mockito.when(lbServices.get(anyString())).thenReturn(null); |
| 295 | + Mockito.when(lbVirtualServers.get(lbVirtualServerName)).thenReturn(existingVs); |
| 296 | + |
| 297 | + client.createAndAddNsxLbVirtualServer(TIER_1_GATEWAY_NAME, lbId, "192.168.1.1", "443", |
| 298 | + memberList, "roundrobin", "TCP", "80"); |
| 299 | + |
| 300 | + verify(lbVirtualServers).get(lbVirtualServerName); |
| 301 | + verify(lbVirtualServers, never()).get(lbServiceName); |
| 302 | + verify(lbVirtualServers, never()).patch(anyString(), any(LBVirtualServer.class)); |
| 303 | + } |
| 304 | + |
| 305 | + @Test |
| 306 | + public void testCreateNsxLbServerPoolThrowsExceptionOnPatchError() { |
| 307 | + String lbServerPoolName = NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L); |
| 308 | + List<NsxLoadBalancerMember> memberList = List.of(new NsxLoadBalancerMember(1L, "10.0.0.1", 80)); |
| 309 | + |
| 310 | + LbPools lbPools = Mockito.mock(LbPools.class); |
| 311 | + Structure errorData = Mockito.mock(Structure.class); |
| 312 | + ApiError apiError = new ApiError(); |
| 313 | + apiError.setErrorData(errorData); |
| 314 | + |
| 315 | + mockLbMonitorProfiles(); |
| 316 | + Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools); |
| 317 | + Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new NotFound(null, null)); |
| 318 | + when(errorData._convertTo(ApiError.class)).thenReturn(apiError); |
| 319 | + doThrow(new Error(List.of(), errorData)).when(lbPools).patch(eq(lbServerPoolName), any(LBPool.class)); |
| 320 | + |
| 321 | + CloudRuntimeException thrownException = assertThrows(CloudRuntimeException.class, () -> { |
| 322 | + client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME, lbServerPoolName, "roundrobin", "80", "TCP"); |
| 323 | + }); |
| 324 | + assertTrue(thrownException.getMessage().startsWith("Failed to create NSX LB server pool, due to")); |
| 325 | + } |
| 326 | + |
| 327 | + private LbMonitorProfiles mockLbMonitorProfiles() { |
| 328 | + LbMonitorProfiles lbMonitorProfiles = Mockito.mock(LbMonitorProfiles.class); |
| 329 | + Structure monitorStructure = Mockito.mock(Structure.class, Mockito.RETURNS_DEEP_STUBS); |
| 330 | + |
| 331 | + Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles); |
| 332 | + Mockito.when(lbMonitorProfiles.get(anyString())).thenReturn(monitorStructure); |
| 333 | + Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test"); |
| 334 | + return lbMonitorProfiles; |
| 335 | + } |
111 | 336 | } |
0 commit comments