github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/vdc_group_common_test.go (about) 1 //go:build network || functional || openapi || vdcGroup || nsxt || gateway || ALL 2 3 /* 4 * Copyright 2022 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 5 */ 6 7 package govcd 8 9 import ( 10 "fmt" 11 "net/url" 12 13 "github.com/vmware/go-vcloud-director/v2/types/v56" 14 . "gopkg.in/check.v1" 15 ) 16 17 func (vcd *TestVCD) Test_NsxtVdcGroupOrgNetworks(check *C) { 18 skipNoNsxtConfiguration(vcd, check) 19 skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways) 20 vcd.skipIfNotSysAdmin(check) 21 22 adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org) 23 check.Assert(adminOrg, NotNil) 24 check.Assert(err, IsNil) 25 26 org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org) 27 check.Assert(org, NotNil) 28 check.Assert(err, IsNil) 29 30 nsxtExternalNetwork, err := GetExternalNetworkV2ByName(vcd.client, vcd.config.VCD.Nsxt.ExternalNetwork) 31 check.Assert(err, IsNil) 32 check.Assert(nsxtExternalNetwork, NotNil) 33 34 vdc, vdcGroup := test_CreateVdcGroup(check, adminOrg, vcd) 35 check.Assert(vdc, NotNil) 36 check.Assert(vdcGroup, NotNil) 37 38 egwDefinition := &types.OpenAPIEdgeGateway{ 39 Name: "nsx-t-edge", 40 Description: "nsx-t-edge-description", 41 OwnerRef: &types.OpenApiReference{ 42 ID: vdc.Vdc.ID, 43 }, 44 EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{ 45 UplinkID: nsxtExternalNetwork.ExternalNetwork.ID, 46 Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{ 47 Gateway: "1.1.1.1", 48 PrefixLength: 24, 49 Enabled: true, 50 }}}, 51 Connected: true, 52 Dedicated: false, 53 }}, 54 } 55 56 // Create Edge Gateway in VDC 57 createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition) 58 check.Assert(err, IsNil) 59 check.Assert(createdEdge, NotNil) 60 check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`) 61 openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID 62 PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint) 63 64 // Move Edge Gateway to VDC Group 65 movedGateway, err := createdEdge.MoveToVdcOrVdcGroup(vdcGroup.VdcGroup.Id) 66 check.Assert(err, IsNil) 67 check.Assert(movedGateway, NotNil) 68 check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id) 69 check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdcGroup:.*`) 70 71 mapOfNetworkConfigs := make(map[string]*types.OpenApiOrgVdcNetwork, 3) 72 mapOfNetworkConfigs["isolated"] = buildIsolatedOrgVdcNetworkConfig(check, vcd, vdcGroup.VdcGroup.Id) 73 mapOfNetworkConfigs["imported"] = buildImportedOrgVdcNetworkConfig(check, vcd, vdcGroup.VdcGroup.Id) 74 mapOfNetworkConfigs["routed"] = buildRoutedOrgVdcNetworkConfig(check, vcd, movedGateway, vdcGroup.VdcGroup.Id) 75 76 sliceOfCreatedNetworkConfigs := make(map[string]*OpenApiOrgVdcNetwork, 3) 77 for index, orgVdcNetworkConfig := range mapOfNetworkConfigs { 78 orgVdcNet, err := org.CreateOpenApiOrgVdcNetwork(orgVdcNetworkConfig) 79 check.Assert(err, IsNil) 80 check.Assert(orgVdcNet, NotNil) 81 check.Assert(orgVdcNet.OpenApiOrgVdcNetwork.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id) 82 83 sliceOfCreatedNetworkConfigs[index] = orgVdcNet 84 85 // Use generic "OpenApiEntity" resource cleanup type 86 openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworks + orgVdcNet.OpenApiOrgVdcNetwork.ID 87 PrependToCleanupListOpenApi(orgVdcNet.OpenApiOrgVdcNetwork.Name, check.TestName(), openApiEndpoint) 88 89 check.Assert(orgVdcNet.GetType(), Equals, orgVdcNetworkConfig.NetworkType) 90 } 91 92 // Move Edge Gateway back to VDC 93 movedBackToVdcEdge, err := movedGateway.MoveToVdcOrVdcGroup(vdc.Vdc.ID) 94 check.Assert(err, IsNil) 95 check.Assert(movedBackToVdcEdge, NotNil) 96 check.Assert(movedBackToVdcEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`) 97 98 // Routed networks migrate to/from VDC Groups together with Edge Gateway therefore we need to 99 // check that routed network owner ID is the same as Edge Gateway. Routed network must be 100 // retrieved again so that it reflects latest information. 101 routedOrgNetwork, err := org.GetOpenApiOrgVdcNetworkById(sliceOfCreatedNetworkConfigs["routed"].OpenApiOrgVdcNetwork.ID) 102 check.Assert(err, IsNil) 103 check.Assert(routedOrgNetwork, NotNil) 104 check.Assert(routedOrgNetwork.OpenApiOrgVdcNetwork.OwnerRef.ID, Equals, movedBackToVdcEdge.EdgeGateway.OwnerRef.ID) 105 106 // Remove all created networks 107 for _, network := range sliceOfCreatedNetworkConfigs { 108 err = network.Delete() 109 check.Assert(err, IsNil) 110 } 111 112 // Remove Edge Gateway 113 err = movedGateway.Delete() 114 check.Assert(err, IsNil) 115 116 // Remove VDC group and VDC 117 err = vdcGroup.Delete() 118 check.Assert(err, IsNil) 119 task, err := vdc.Delete(true, true) 120 check.Assert(err, IsNil) 121 err = task.WaitTaskCompletion() 122 check.Assert(err, IsNil) 123 } 124 125 func buildIsolatedOrgVdcNetworkConfig(check *C, vcd *TestVCD, ownerId string) *types.OpenApiOrgVdcNetwork { 126 isolatedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{ 127 Name: check.TestName() + "-isolated", 128 Description: check.TestName() + "-description", 129 130 OwnerRef: &types.OpenApiReference{ID: ownerId}, 131 132 NetworkType: types.OrgVdcNetworkTypeIsolated, 133 Subnets: types.OrgVdcNetworkSubnets{ 134 Values: []types.OrgVdcNetworkSubnetValues{ 135 { 136 Gateway: "4.1.1.1", 137 PrefixLength: 25, 138 DNSServer1: "8.8.8.8", 139 DNSServer2: "8.8.4.4", 140 DNSSuffix: "bar.foo", 141 IPRanges: types.OrgVdcNetworkSubnetIPRanges{ 142 Values: []types.OrgVdcNetworkSubnetIPRangeValues{ 143 { 144 StartAddress: "4.1.1.20", 145 EndAddress: "4.1.1.30", 146 }, 147 { 148 StartAddress: "4.1.1.40", 149 EndAddress: "4.1.1.50", 150 }, 151 { 152 StartAddress: "4.1.1.88", 153 EndAddress: "4.1.1.92", 154 }, 155 }}, 156 }, 157 }, 158 }, 159 } 160 161 return isolatedOrgVdcNetworkConfig 162 } 163 164 func buildImportedOrgVdcNetworkConfig(check *C, vcd *TestVCD, ownerId string) *types.OpenApiOrgVdcNetwork { 165 logicalSwitch, err := vcd.nsxtVdc.GetNsxtImportableSwitchByName(vcd.config.VCD.Nsxt.NsxtImportSegment) 166 check.Assert(err, IsNil) 167 168 importedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{ 169 Name: check.TestName() + "-imported", 170 Description: check.TestName() + "-description", 171 172 OwnerRef: &types.OpenApiReference{ID: ownerId}, 173 174 NetworkType: types.OrgVdcNetworkTypeOpaque, 175 // BackingNetworkId contains NSX-T logical switch ID for Imported networks 176 BackingNetworkId: logicalSwitch.NsxtImportableSwitch.ID, 177 178 Subnets: types.OrgVdcNetworkSubnets{ 179 Values: []types.OrgVdcNetworkSubnetValues{ 180 { 181 Gateway: "2.1.1.1", 182 PrefixLength: 24, 183 DNSServer1: "8.8.8.8", 184 DNSServer2: "8.8.4.4", 185 DNSSuffix: "foo.bar", 186 IPRanges: types.OrgVdcNetworkSubnetIPRanges{ 187 Values: []types.OrgVdcNetworkSubnetIPRangeValues{ 188 { 189 StartAddress: "2.1.1.20", 190 EndAddress: "2.1.1.30", 191 }, 192 { 193 StartAddress: "2.1.1.40", 194 EndAddress: "2.1.1.50", 195 }, 196 }}, 197 }, 198 }, 199 }, 200 } 201 202 return importedOrgVdcNetworkConfig 203 } 204 205 func buildRoutedOrgVdcNetworkConfig(check *C, vcd *TestVCD, edgeGateway *NsxtEdgeGateway, ownerId string) *types.OpenApiOrgVdcNetwork { 206 routedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{ 207 Name: check.TestName() + "-routed", 208 Description: check.TestName() + "-description", 209 210 OwnerRef: &types.OpenApiReference{ID: ownerId}, 211 212 NetworkType: types.OrgVdcNetworkTypeRouted, 213 214 // Connection is used for "routed" network 215 Connection: &types.Connection{ 216 RouterRef: types.OpenApiReference{ 217 ID: edgeGateway.EdgeGateway.ID, 218 }, 219 ConnectionType: "INTERNAL", 220 }, 221 Subnets: types.OrgVdcNetworkSubnets{ 222 Values: []types.OrgVdcNetworkSubnetValues{ 223 { 224 Gateway: "3.1.1.1", 225 PrefixLength: 24, 226 DNSServer1: "8.8.8.8", 227 DNSServer2: "8.8.4.4", 228 DNSSuffix: "foo.bar", 229 IPRanges: types.OrgVdcNetworkSubnetIPRanges{ 230 Values: []types.OrgVdcNetworkSubnetIPRangeValues{ 231 { 232 StartAddress: "3.1.1.20", 233 EndAddress: "3.1.1.30", 234 }, 235 { 236 StartAddress: "3.1.1.40", 237 EndAddress: "3.1.1.50", 238 }, 239 { 240 StartAddress: "3.1.1.60", 241 EndAddress: "3.1.1.62", 242 }, { 243 StartAddress: "3.1.1.72", 244 EndAddress: "3.1.1.74", 245 }, { 246 StartAddress: "3.1.1.84", 247 EndAddress: "3.1.1.85", 248 }, 249 }}, 250 }, 251 }, 252 }, 253 } 254 255 return routedOrgVdcNetworkConfig 256 } 257 258 func test_CreateVdcGroup(check *C, adminOrg *AdminOrg, vcd *TestVCD) (*Vdc, *VdcGroup) { 259 createdVdc := createNewVdc(vcd, check, check.TestName()) 260 261 createdVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(), 262 map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(createdVdc.vdcName()))}}) 263 check.Assert(err, IsNil) 264 check.Assert(createdVdcAsCandidate, NotNil) 265 check.Assert(len(createdVdcAsCandidate) == 1, Equals, true) 266 267 existingVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(), 268 map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(vcd.nsxtVdc.vdcName()))}}) 269 check.Assert(err, IsNil) 270 check.Assert(existingVdcAsCandidate, NotNil) 271 check.Assert(len(existingVdcAsCandidate) == 1, Equals, true) 272 273 vdcGroupConfig := &types.VdcGroup{ 274 Name: check.TestName() + "Group", 275 OrgId: adminOrg.orgId(), 276 ParticipatingOrgVdcs: []types.ParticipatingOrgVdcs{ 277 types.ParticipatingOrgVdcs{ 278 VdcRef: types.OpenApiReference{ 279 ID: createdVdc.vdcId(), 280 }, 281 SiteRef: (createdVdcAsCandidate)[0].SiteRef, 282 OrgRef: (createdVdcAsCandidate)[0].OrgRef, 283 }, 284 types.ParticipatingOrgVdcs{ 285 VdcRef: types.OpenApiReference{ 286 ID: vcd.nsxtVdc.vdcId(), 287 }, 288 SiteRef: (existingVdcAsCandidate)[0].SiteRef, 289 OrgRef: (existingVdcAsCandidate)[0].OrgRef, 290 }, 291 }, 292 LocalEgress: false, 293 UniversalNetworkingEnabled: false, 294 NetworkProviderType: "NSX_T", 295 Type: "LOCAL", 296 //DfwEnabled: true, // ignored by API 297 } 298 299 vdcGroup, err := adminOrg.CreateVdcGroup(vdcGroupConfig) 300 check.Assert(err, IsNil) 301 check.Assert(vdcGroup, NotNil) 302 check.Assert(vdcGroup.IsNsxt(), Equals, true) 303 304 openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroups + vdcGroup.VdcGroup.Id 305 PrependToCleanupListOpenApi(vdcGroup.VdcGroup.Name, check.TestName(), openApiEndpoint) 306 307 return createdVdc, vdcGroup 308 } 309 310 func createNewVdc(vcd *TestVCD, check *C, vdcName string) *Vdc { 311 adminOrg, err := vcd.client.GetAdminOrgByName(vcd.org.Org.Name) 312 check.Assert(err, IsNil) 313 check.Assert(adminOrg, NotNil) 314 315 pVdcs, err := QueryProviderVdcByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.Name) 316 check.Assert(err, IsNil) 317 318 if len(pVdcs) == 0 { 319 check.Skip(fmt.Sprintf("No NSX-T Provider VDC found with name '%s'", vcd.config.VCD.NsxtProviderVdc.Name)) 320 } 321 providerVdcHref := pVdcs[0].HREF 322 pvdcStorageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.NsxtProviderVdc.StorageProfile, providerVdcHref) 323 check.Assert(err, IsNil) 324 check.Assert(pvdcStorageProfile, NotNil) 325 providerVdcStorageProfileHref := pvdcStorageProfile.HREF 326 327 networkPools, err := QueryNetworkPoolByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.NetworkPool) 328 check.Assert(err, IsNil) 329 if len(networkPools) == 0 { 330 check.Skip(fmt.Sprintf("No network pool found with name '%s'", vcd.config.VCD.NsxtProviderVdc.NetworkPool)) 331 } 332 333 networkPoolHref := networkPools[0].HREF 334 trueValue := true 335 vdcConfiguration := &types.VdcConfiguration{ 336 Name: vdcName, 337 Xmlns: types.XMLNamespaceVCloud, 338 AllocationModel: "Flex", 339 ComputeCapacity: []*types.ComputeCapacity{ 340 &types.ComputeCapacity{ 341 CPU: &types.CapacityWithUsage{ 342 Units: "MHz", 343 Allocated: 1024, 344 Limit: 1024, 345 }, 346 Memory: &types.CapacityWithUsage{ 347 Allocated: 1024, 348 Limit: 1024, 349 Units: "MB", 350 }, 351 }, 352 }, 353 VdcStorageProfile: []*types.VdcStorageProfileConfiguration{&types.VdcStorageProfileConfiguration{ 354 Enabled: addrOf(true), 355 Units: "MB", 356 Limit: 1024, 357 Default: true, 358 ProviderVdcStorageProfile: &types.Reference{ 359 HREF: providerVdcStorageProfileHref, 360 }, 361 }, 362 }, 363 NetworkPoolReference: &types.Reference{ 364 HREF: networkPoolHref, 365 }, 366 ProviderVdcReference: &types.Reference{ 367 HREF: providerVdcHref, 368 }, 369 IsEnabled: true, 370 IsThinProvision: true, 371 UsesFastProvisioning: true, 372 IsElastic: &trueValue, 373 IncludeMemoryOverhead: &trueValue, 374 } 375 376 vdc, err := adminOrg.CreateOrgVdc(vdcConfiguration) 377 check.Assert(err, IsNil) 378 check.Assert(vdc, NotNil) 379 380 AddToCleanupList(vdcConfiguration.Name, "vdc", vcd.org.Org.Name, check.TestName()) 381 return vdc 382 }