github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/nsxt_edgegateway_test.go (about)

     1  //go:build network || nsxt || functional || openapi || ALL
     2  
     3  package govcd
     4  
     5  import (
     6  	"fmt"
     7  	"net/netip"
     8  	"net/url"
     9  
    10  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    11  	. "gopkg.in/check.v1"
    12  )
    13  
    14  func (vcd *TestVCD) Test_NsxtEdgeCreate(check *C) {
    15  	skipNoNsxtConfiguration(vcd, check)
    16  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)
    17  	vcd.skipIfNotSysAdmin(check)
    18  
    19  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
    20  	check.Assert(err, IsNil)
    21  	check.Assert(adminOrg, NotNil)
    22  
    23  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
    24  	check.Assert(err, IsNil)
    25  	check.Assert(org, NotNil)
    26  
    27  	nsxvVdc, err := adminOrg.GetVDCByName(vcd.config.VCD.Vdc, false)
    28  	check.Assert(err, IsNil)
    29  	check.Assert(nsxvVdc, NotNil)
    30  	nsxtVdc, err := adminOrg.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
    31  	if ContainsNotFound(err) {
    32  		check.Skip(fmt.Sprintf("No NSX-T VDC (%s) found - skipping test", vcd.config.VCD.Nsxt.Vdc))
    33  	}
    34  	check.Assert(err, IsNil)
    35  	check.Assert(nsxtVdc, NotNil)
    36  
    37  	nsxtExternalNetwork, err := GetExternalNetworkV2ByName(vcd.client, vcd.config.VCD.Nsxt.ExternalNetwork)
    38  	check.Assert(err, IsNil)
    39  	check.Assert(nsxtExternalNetwork, NotNil)
    40  
    41  	egwDefinition := &types.OpenAPIEdgeGateway{
    42  		Name:        "nsx-t-edge",
    43  		Description: "nsx-t-edge-description",
    44  		OrgVdc: &types.OpenApiReference{
    45  			ID: nsxtVdc.Vdc.ID,
    46  		},
    47  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{
    48  			UplinkID: nsxtExternalNetwork.ExternalNetwork.ID,
    49  			Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
    50  				Gateway:      "1.1.1.1",
    51  				PrefixLength: 24,
    52  				Enabled:      true,
    53  			}}},
    54  			Connected: true,
    55  			Dedicated: false,
    56  		}},
    57  	}
    58  
    59  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
    60  	check.Assert(err, IsNil)
    61  	check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
    62  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
    63  	AddToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)
    64  
    65  	createdEdge.EdgeGateway.Name = "renamed-edge"
    66  	updatedEdge, err := createdEdge.Update(createdEdge.EdgeGateway)
    67  	check.Assert(err, IsNil)
    68  	check.Assert(updatedEdge.EdgeGateway.Name, Equals, "renamed-edge")
    69  
    70  	// FIQL filtering test
    71  	queryParams := url.Values{}
    72  	queryParams.Add("filter", "name==renamed-edge")
    73  	//
    74  	egws, err := adminOrg.GetAllNsxtEdgeGateways(queryParams)
    75  	check.Assert(err, IsNil)
    76  	check.Assert(len(egws) >= 1, Equals, true)
    77  
    78  	// Lookup using different available methods
    79  	e1, err := adminOrg.GetNsxtEdgeGatewayByName(updatedEdge.EdgeGateway.Name)
    80  	check.Assert(err, IsNil)
    81  	check.Assert(e1, NotNil)
    82  	e2, err := org.GetNsxtEdgeGatewayByName(updatedEdge.EdgeGateway.Name)
    83  	check.Assert(err, IsNil)
    84  	check.Assert(e2, NotNil)
    85  	e3, err := nsxtVdc.GetNsxtEdgeGatewayByName(updatedEdge.EdgeGateway.Name)
    86  	check.Assert(err, IsNil)
    87  	check.Assert(e3, NotNil)
    88  	e4, err := adminOrg.GetNsxtEdgeGatewayById(updatedEdge.EdgeGateway.ID)
    89  	check.Assert(err, IsNil)
    90  	check.Assert(e4, NotNil)
    91  	e5, err := org.GetNsxtEdgeGatewayById(updatedEdge.EdgeGateway.ID)
    92  	check.Assert(err, IsNil)
    93  	check.Assert(e5, NotNil)
    94  	e6, err := nsxtVdc.GetNsxtEdgeGatewayById(updatedEdge.EdgeGateway.ID)
    95  	check.Assert(err, IsNil)
    96  	check.Assert(e6, NotNil)
    97  
    98  	// Try to search for NSX-T edge gateway in NSX-V VDC and expect it to be not found
    99  	expectNil, err := nsxvVdc.GetNsxtEdgeGatewayByName(updatedEdge.EdgeGateway.Name)
   100  	check.Assert(ContainsNotFound(err), Equals, true)
   101  	check.Assert(expectNil, IsNil)
   102  	expectNil, err = nsxvVdc.GetNsxtEdgeGatewayById(updatedEdge.EdgeGateway.ID)
   103  	check.Assert(ContainsNotFound(err), Equals, true)
   104  	check.Assert(expectNil, IsNil)
   105  
   106  	// Ensure all methods found the same edge gateway
   107  	check.Assert(e1.EdgeGateway.ID, Equals, e2.EdgeGateway.ID)
   108  	check.Assert(e1.EdgeGateway.ID, Equals, e3.EdgeGateway.ID)
   109  	check.Assert(e1.EdgeGateway.ID, Equals, e4.EdgeGateway.ID)
   110  	check.Assert(e1.EdgeGateway.ID, Equals, e5.EdgeGateway.ID)
   111  	check.Assert(e1.EdgeGateway.ID, Equals, e6.EdgeGateway.ID)
   112  
   113  	// Try out GetUsedIpAddresses function
   114  	usedIPs, err := updatedEdge.GetUsedIpAddresses(nil)
   115  	check.Assert(err, IsNil)
   116  	check.Assert(usedIPs, NotNil)
   117  
   118  	ipAddr, err := updatedEdge.GetUnusedExternalIPAddresses(1, netip.Prefix{}, false)
   119  	// Expect an error as no ranges were assigned
   120  	check.Assert(err, NotNil)
   121  	check.Assert(ipAddr, DeepEquals, []netip.Addr(nil))
   122  
   123  	// Try a refresh operation
   124  	err = updatedEdge.Refresh()
   125  	check.Assert(err, IsNil)
   126  	check.Assert(updatedEdge.EdgeGateway.ID, Equals, e1.EdgeGateway.ID)
   127  
   128  	// Cleanup
   129  	err = updatedEdge.Delete()
   130  	check.Assert(err, IsNil)
   131  }
   132  
   133  func (vcd *TestVCD) Test_NsxtEdgeVdcGroup(check *C) {
   134  	skipNoNsxtConfiguration(vcd, check)
   135  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)
   136  	vcd.skipIfNotSysAdmin(check)
   137  
   138  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   139  	check.Assert(err, IsNil)
   140  	check.Assert(adminOrg, NotNil)
   141  
   142  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
   143  	check.Assert(err, IsNil)
   144  	check.Assert(org, NotNil)
   145  
   146  	nsxtExternalNetwork, err := GetExternalNetworkV2ByName(vcd.client, vcd.config.VCD.Nsxt.ExternalNetwork)
   147  	check.Assert(err, IsNil)
   148  	check.Assert(nsxtExternalNetwork, NotNil)
   149  
   150  	vdc, vdcGroup := test_CreateVdcGroup(check, adminOrg, vcd)
   151  
   152  	egwDefinition := &types.OpenAPIEdgeGateway{
   153  		Name:        "nsx-t-edge",
   154  		Description: "nsx-t-edge-description",
   155  		OwnerRef: &types.OpenApiReference{
   156  			ID: vdc.Vdc.ID,
   157  		},
   158  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{
   159  			UplinkID: nsxtExternalNetwork.ExternalNetwork.ID,
   160  			Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
   161  				Gateway:      "1.1.1.1",
   162  				PrefixLength: 24,
   163  				Enabled:      true,
   164  			}}},
   165  			Connected: true,
   166  			Dedicated: false,
   167  		}},
   168  	}
   169  
   170  	// Create Edge Gateway in VDC
   171  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
   172  	check.Assert(err, IsNil)
   173  	check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)
   174  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
   175  	PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)
   176  
   177  	check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
   178  	check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Equals, egwDefinition.OwnerRef.ID)
   179  
   180  	// Move Edge Gateway to VDC Group
   181  	movedGateway, err := createdEdge.MoveToVdcOrVdcGroup(vdcGroup.VdcGroup.Id)
   182  	check.Assert(err, IsNil)
   183  	check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id)
   184  	check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdcGroup:.*`)
   185  
   186  	// Get by name and owner ID
   187  	edgeByNameAndOwnerId, err := org.GetNsxtEdgeGatewayByNameAndOwnerId(createdEdge.EdgeGateway.Name, vdcGroup.VdcGroup.Id)
   188  	check.Assert(err, IsNil)
   189  
   190  	// Check lookup of Edge Gateways in VDC Groups
   191  	edgeInVdcGroup, err := vdcGroup.GetNsxtEdgeGatewayByName(createdEdge.EdgeGateway.Name)
   192  	check.Assert(err, IsNil)
   193  
   194  	// Ensure both methods for retrieval get the same object
   195  	check.Assert(edgeByNameAndOwnerId.EdgeGateway, DeepEquals, edgeInVdcGroup.EdgeGateway)
   196  
   197  	// Masking known variables that have change for deep check
   198  	edgeInVdcGroup.EdgeGateway.OwnerRef.Name = ""
   199  	check.Assert(edgeInVdcGroup.EdgeGateway, DeepEquals, createdEdge.EdgeGateway)
   200  
   201  	// Move Edge Gateway back to VDC from VDC Group
   202  	egwDefinition.OwnerRef.ID = vdc.Vdc.ID
   203  	egwDefinition.ID = movedGateway.EdgeGateway.ID
   204  
   205  	movedBackToVdcEdge, err := movedGateway.Update(egwDefinition)
   206  	check.Assert(err, IsNil)
   207  	check.Assert(movedBackToVdcEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)
   208  
   209  	// Ignore known to differ fields, but check that whole Edge Gateway structure remains the same
   210  	// as it is important to perform update operations without impacting configuration itself
   211  
   212  	// Fields to ignore on both sides
   213  	createdEdge.EdgeGateway.OrgVdc = movedBackToVdcEdge.EdgeGateway.OrgVdc
   214  	createdEdge.EdgeGateway.OwnerRef = movedBackToVdcEdge.EdgeGateway.OwnerRef
   215  	check.Assert(movedBackToVdcEdge.EdgeGateway, DeepEquals, createdEdge.EdgeGateway)
   216  
   217  	// Remove Edge Gateway
   218  	err = movedBackToVdcEdge.Delete()
   219  	check.Assert(err, IsNil)
   220  
   221  	// Remove VDC Group
   222  	err = vdcGroup.Delete()
   223  	check.Assert(err, IsNil)
   224  
   225  	// Remove VDC
   226  	err = vdc.DeleteWait(true, true)
   227  	check.Assert(err, IsNil)
   228  }
   229  
   230  func (vcd *TestVCD) Test_NsxtEdgeGatewayUsedAndUnusedIPs(check *C) {
   231  	skipNoNsxtConfiguration(vcd, check)
   232  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)
   233  	vcd.skipIfNotSysAdmin(check)
   234  
   235  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   236  	check.Assert(err, IsNil)
   237  	check.Assert(adminOrg, NotNil)
   238  
   239  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
   240  	check.Assert(err, IsNil)
   241  	check.Assert(org, NotNil)
   242  
   243  	nsxvVdc, err := adminOrg.GetVDCByName(vcd.config.VCD.Vdc, false)
   244  	check.Assert(err, IsNil)
   245  	check.Assert(nsxvVdc, NotNil)
   246  	nsxtVdc, err := adminOrg.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
   247  	if ContainsNotFound(err) {
   248  		check.Skip(fmt.Sprintf("No NSX-T VDC (%s) found - skipping test", vcd.config.VCD.Nsxt.Vdc))
   249  	}
   250  	check.Assert(err, IsNil)
   251  	check.Assert(nsxtVdc, NotNil)
   252  
   253  	// NSX-T details
   254  	man, err := vcd.client.QueryNsxtManagerByName(vcd.config.VCD.Nsxt.Manager)
   255  	check.Assert(err, IsNil)
   256  	nsxtManagerId, err := BuildUrnWithUuid("urn:vcloud:nsxtmanager:", extractUuid(man[0].HREF))
   257  	check.Assert(err, IsNil)
   258  
   259  	tier0RouterVrf, err := vcd.client.GetImportableNsxtTier0RouterByName(vcd.config.VCD.Nsxt.Tier0router, nsxtManagerId)
   260  	check.Assert(err, IsNil)
   261  	backingId := tier0RouterVrf.NsxtTier0Router.ID
   262  
   263  	netNsxt := &types.ExternalNetworkV2{
   264  		Name: check.TestName(),
   265  		Subnets: types.ExternalNetworkV2Subnets{Values: []types.ExternalNetworkV2Subnet{
   266  			{
   267  				Gateway:      "1.1.1.1",
   268  				PrefixLength: 24,
   269  				IPRanges: types.ExternalNetworkV2IPRanges{Values: []types.ExternalNetworkV2IPRange{
   270  					{
   271  						StartAddress: "1.1.1.3",
   272  						EndAddress:   "1.1.1.25",
   273  					},
   274  				}},
   275  				Enabled: true,
   276  			},
   277  		}},
   278  		NetworkBackings: types.ExternalNetworkV2Backings{Values: []types.ExternalNetworkV2Backing{
   279  			{
   280  				BackingID: backingId,
   281  				NetworkProvider: types.NetworkProvider{
   282  					ID: nsxtManagerId,
   283  				},
   284  				BackingTypeValue: types.ExternalNetworkBackingTypeNsxtTier0Router,
   285  			},
   286  		}},
   287  	}
   288  	createdNet, err := CreateExternalNetworkV2(vcd.client, netNsxt)
   289  	check.Assert(err, IsNil)
   290  
   291  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks + createdNet.ExternalNetwork.ID
   292  	AddToCleanupListOpenApi(createdNet.ExternalNetwork.Name, check.TestName(), openApiEndpoint)
   293  
   294  	egwDefinition := &types.OpenAPIEdgeGateway{
   295  		Name: check.TestName(),
   296  		OrgVdc: &types.OpenApiReference{
   297  			ID: nsxtVdc.Vdc.ID,
   298  		},
   299  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{
   300  			UplinkID: createdNet.ExternalNetwork.ID,
   301  			Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
   302  				Gateway:      createdNet.ExternalNetwork.Subnets.Values[0].Gateway,
   303  				PrefixLength: createdNet.ExternalNetwork.Subnets.Values[0].PrefixLength,
   304  				Enabled:      true,
   305  				IPRanges: &types.OpenApiIPRanges{
   306  					Values: []types.OpenApiIPRangeValues{
   307  						{
   308  							StartAddress: createdNet.ExternalNetwork.Subnets.Values[0].IPRanges.Values[0].StartAddress,
   309  							EndAddress:   createdNet.ExternalNetwork.Subnets.Values[0].IPRanges.Values[0].EndAddress,
   310  						},
   311  					},
   312  				},
   313  			}}},
   314  			Connected: true,
   315  			Dedicated: false,
   316  		}},
   317  	}
   318  
   319  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
   320  	check.Assert(err, IsNil)
   321  	check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
   322  	openApiEndpoint = types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
   323  	PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)
   324  
   325  	// Try out GetUsedIpAddresses function
   326  	usedIPs, err := createdEdge.GetUsedIpAddresses(nil)
   327  	check.Assert(err, IsNil)
   328  	check.Assert(usedIPs, NotNil)
   329  
   330  	// Edge Gateway always allocates 1 IP as its primary
   331  	check.Assert(usedIPs[0].IPAddress, Equals, "1.1.1.3")
   332  	check.Assert(usedIPs[0].Category, Equals, "PRIMARY_IP")
   333  
   334  	// Attempt to get 1 unallocated IP
   335  	ipAddr, err := createdEdge.GetUnusedExternalIPAddresses(1, netip.Prefix{}, false)
   336  	check.Assert(err, IsNil)
   337  	ipsCompared := compareEachIpElementAndOrder(ipAddr, []netip.Addr{netip.MustParseAddr("1.1.1.4")})
   338  	check.Assert(ipsCompared, Equals, true)
   339  
   340  	// Attempt to get 10 unallocated IPs
   341  	ipAddr, err = createdEdge.GetUnusedExternalIPAddresses(10, netip.Prefix{}, true)
   342  	check.Assert(err, IsNil)
   343  	ipsCompared = compareEachIpElementAndOrder(ipAddr, []netip.Addr{
   344  		netip.MustParseAddr("1.1.1.4"),
   345  		netip.MustParseAddr("1.1.1.5"),
   346  		netip.MustParseAddr("1.1.1.6"),
   347  		netip.MustParseAddr("1.1.1.7"),
   348  		netip.MustParseAddr("1.1.1.8"),
   349  		netip.MustParseAddr("1.1.1.9"),
   350  		netip.MustParseAddr("1.1.1.10"),
   351  		netip.MustParseAddr("1.1.1.11"),
   352  		netip.MustParseAddr("1.1.1.12"),
   353  		netip.MustParseAddr("1.1.1.13"),
   354  	})
   355  	check.Assert(ipsCompared, Equals, true)
   356  
   357  	// Attempt to get IP but filter it off by prefix
   358  	ipAddr, err = createdEdge.GetUnusedExternalIPAddresses(1, netip.MustParsePrefix("192.168.1.1/24"), false)
   359  	// Expect an error because Edge Gateway does not have IPs from required subnet 192.168.1.1/24
   360  	check.Assert(err, NotNil)
   361  	check.Assert(ipAddr, IsNil)
   362  
   363  	// Attempt to get all unused IPs
   364  	allIps, err := createdEdge.GetAllUnusedExternalIPAddresses(true)
   365  	check.Assert(err, IsNil)
   366  	ipsCompared = compareEachIpElementAndOrder(allIps, []netip.Addr{
   367  		netip.MustParseAddr("1.1.1.4"),
   368  		netip.MustParseAddr("1.1.1.5"),
   369  		netip.MustParseAddr("1.1.1.6"),
   370  		netip.MustParseAddr("1.1.1.7"),
   371  		netip.MustParseAddr("1.1.1.8"),
   372  		netip.MustParseAddr("1.1.1.9"),
   373  		netip.MustParseAddr("1.1.1.10"),
   374  		netip.MustParseAddr("1.1.1.11"),
   375  		netip.MustParseAddr("1.1.1.12"),
   376  		netip.MustParseAddr("1.1.1.13"),
   377  		netip.MustParseAddr("1.1.1.14"),
   378  		netip.MustParseAddr("1.1.1.15"),
   379  		netip.MustParseAddr("1.1.1.16"),
   380  		netip.MustParseAddr("1.1.1.17"),
   381  		netip.MustParseAddr("1.1.1.18"),
   382  		netip.MustParseAddr("1.1.1.19"),
   383  		netip.MustParseAddr("1.1.1.20"),
   384  		netip.MustParseAddr("1.1.1.21"),
   385  		netip.MustParseAddr("1.1.1.22"),
   386  		netip.MustParseAddr("1.1.1.23"),
   387  		netip.MustParseAddr("1.1.1.24"),
   388  		netip.MustParseAddr("1.1.1.25"),
   389  	})
   390  	check.Assert(ipsCompared, Equals, true)
   391  	check.Assert(len(allIps), Equals, 22)
   392  
   393  	// Verify that GetAllocatedIpCount returns correct number of allocated IPs
   394  	totalAllocationIpCount, err := createdEdge.GetAllocatedIpCount(true)
   395  	check.Assert(err, IsNil)
   396  	check.Assert(totalAllocationIpCount, NotNil)
   397  	check.Assert(totalAllocationIpCount, Equals, 23) // 22 unused IPs + 1 primary
   398  
   399  	// Try to deallocate more IPs than allocated
   400  	failedDeallocationIpCount, err := createdEdge.QuickDeallocateIpCount(24)
   401  	check.Assert(err, NotNil)
   402  	check.Assert(failedDeallocationIpCount, IsNil)
   403  
   404  	// Check that failed deallocation did not change the number of allocated IPs
   405  	allocatedIpCountAfterFailedDeallocation, err := createdEdge.GetAllocatedIpCount(true)
   406  	check.Assert(err, IsNil)
   407  	check.Assert(allocatedIpCountAfterFailedDeallocation, NotNil)
   408  	check.Assert(allocatedIpCountAfterFailedDeallocation, Equals, 23) // 22 unused IPs + 1 primary
   409  
   410  	// Try to deallocate all IPs including primary. Expect a failure as an Edge Gateway must always
   411  	// have a primary IP
   412  	failedDeallocationIpCount, err = createdEdge.QuickDeallocateIpCount(23)
   413  	check.Assert(err, NotNil)
   414  	check.Assert(failedDeallocationIpCount, IsNil)
   415  
   416  	// Deallocate 22 IP addresses
   417  	deallocatedEdge, err := createdEdge.QuickDeallocateIpCount(22)
   418  	check.Assert(err, IsNil)
   419  
   420  	allocatedIpCountAfterDeallocation, err := deallocatedEdge.GetAllocatedIpCount(true)
   421  	check.Assert(err, IsNil)
   422  	check.Assert(allocatedIpCountAfterDeallocation, NotNil)
   423  	check.Assert(allocatedIpCountAfterDeallocation, Equals, 1) // 1 primary
   424  
   425  	// Cleanup
   426  	err = createdEdge.Delete()
   427  	check.Assert(err, IsNil)
   428  
   429  	err = createdNet.Delete()
   430  	check.Assert(err, IsNil)
   431  }
   432  
   433  // compareEachIpElementAndOrder performs comparison of IPs in a slice as default check.Assert
   434  // functions is not able to perform this comparison
   435  func compareEachIpElementAndOrder(ipSlice1, ipSlice2 []netip.Addr) bool {
   436  	if len(ipSlice1) != len(ipSlice2) {
   437  		return false
   438  	}
   439  
   440  	for index := range ipSlice1 {
   441  		if ipSlice1[index] != ipSlice2[index] {
   442  			return false
   443  		}
   444  	}
   445  
   446  	return true
   447  }
   448  
   449  // Test_NsxtEdgeQoS tests QoS config (NSX-T Edge Gateway Rate Limiting) retrieval and update
   450  func (vcd *TestVCD) Test_NsxtEdgeQoS(check *C) {
   451  	if vcd.skipAdminTests {
   452  		check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
   453  	}
   454  	skipNoNsxtConfiguration(vcd, check)
   455  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointQosProfiles)
   456  	if vcd.config.VCD.Nsxt.GatewayQosProfile == "" {
   457  		check.Skip("No NSX-T Edge Gateway QoS Profile configured")
   458  	}
   459  
   460  	// Get QoS profile to use
   461  	nsxtManagers, err := vcd.client.QueryNsxtManagerByName(vcd.config.VCD.Nsxt.Manager)
   462  	check.Assert(err, IsNil)
   463  	check.Assert(len(nsxtManagers), Equals, 1)
   464  
   465  	uuid, err := GetUuidFromHref(nsxtManagers[0].HREF, true)
   466  	check.Assert(err, IsNil)
   467  	urn, err := BuildUrnWithUuid("urn:vcloud:nsxtmanager:", uuid)
   468  	check.Assert(err, IsNil)
   469  
   470  	qosProfile, err := vcd.client.GetNsxtEdgeGatewayQosProfileByDisplayName(urn, vcd.config.VCD.Nsxt.GatewayQosProfile)
   471  	check.Assert(err, IsNil)
   472  	check.Assert(qosProfile, NotNil)
   473  
   474  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
   475  	check.Assert(err, IsNil)
   476  	nsxtVdc, err := org.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
   477  	check.Assert(err, IsNil)
   478  	edge, err := nsxtVdc.GetNsxtEdgeGatewayByName(vcd.config.VCD.Nsxt.EdgeGateway)
   479  	check.Assert(err, IsNil)
   480  
   481  	// Fetch current QoS config
   482  	qosConfig, err := edge.GetQoS()
   483  	check.Assert(err, IsNil)
   484  	check.Assert(qosConfig, NotNil)
   485  	check.Assert(qosConfig.EgressProfile, IsNil)
   486  	check.Assert(qosConfig.IngressProfile, IsNil)
   487  
   488  	// Create new QoS config
   489  	newQosConfig := &types.NsxtEdgeGatewayQos{
   490  		IngressProfile: &types.OpenApiReference{ID: qosProfile.NsxtEdgeGatewayQosProfile.ID},
   491  		EgressProfile:  &types.OpenApiReference{ID: qosProfile.NsxtEdgeGatewayQosProfile.ID},
   492  	}
   493  
   494  	// Update QoS config
   495  	updatedEdgeQosConfig, err := edge.UpdateQoS(newQosConfig)
   496  	check.Assert(err, IsNil)
   497  	check.Assert(updatedEdgeQosConfig, NotNil)
   498  
   499  	// Check that updates were applied
   500  	check.Assert(updatedEdgeQosConfig.EgressProfile.ID, Equals, newQosConfig.EgressProfile.ID)
   501  	check.Assert(updatedEdgeQosConfig.IngressProfile.ID, Equals, newQosConfig.IngressProfile.ID)
   502  
   503  	// Remove QoS config
   504  	updatedEdgeQosConfig, err = edge.UpdateQoS(&types.NsxtEdgeGatewayQos{})
   505  	check.Assert(err, IsNil)
   506  	check.Assert(updatedEdgeQosConfig, NotNil)
   507  }
   508  
   509  func (vcd *TestVCD) Test_NsxtEdgeDhcpForwarder(check *C) {
   510  	if vcd.skipAdminTests {
   511  		check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
   512  	}
   513  	skipNoNsxtConfiguration(vcd, check)
   514  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGatewayDhcpForwarder)
   515  
   516  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
   517  	check.Assert(err, IsNil)
   518  	nsxtVdc, err := org.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
   519  	check.Assert(err, IsNil)
   520  	edge, err := nsxtVdc.GetNsxtEdgeGatewayByName(vcd.config.VCD.Nsxt.EdgeGateway)
   521  	check.Assert(err, IsNil)
   522  	AddToCleanupList(vcd.config.VCD.Nsxt.EdgeGateway, "nsxtDhcpForwarder", vcd.config.VCD.Org, check.TestName())
   523  
   524  	// Fetch current DHCP forwarder config
   525  	dhcpForwarderConfig, err := edge.GetDhcpForwarder()
   526  	check.Assert(err, IsNil)
   527  	check.Assert(dhcpForwarderConfig.Enabled, Equals, false)
   528  	check.Assert(dhcpForwarderConfig.DhcpServers, DeepEquals, []string(nil))
   529  
   530  	// Create new DHCP Forwarder config
   531  	testDhcpServers := []string{
   532  		"1.1.1.1",
   533  		"192.168.2.254",
   534  		"fe80::abcd",
   535  	}
   536  
   537  	newDhcpForwarderConfig := &types.NsxtEdgeGatewayDhcpForwarder{
   538  		Enabled:     true,
   539  		DhcpServers: testDhcpServers,
   540  	}
   541  
   542  	// Update DHCP forwarder config
   543  	updatedEdgeDhcpForwarderConfig, err := edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
   544  	check.Assert(err, IsNil)
   545  	check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)
   546  
   547  	// Check that updates were applied
   548  	check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
   549  	check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)
   550  
   551  	// remove the last dhcp server from the list
   552  	testDhcpServers = testDhcpServers[0:2]
   553  	newDhcpForwarderConfig.DhcpServers = testDhcpServers
   554  
   555  	updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
   556  	check.Assert(err, IsNil)
   557  	check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)
   558  
   559  	// Check that updates were applied
   560  	check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
   561  	check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)
   562  
   563  	// Add servers to the list
   564  	testDhcpServers = append(testDhcpServers, "192.254.0.2")
   565  	newDhcpForwarderConfig.DhcpServers = testDhcpServers
   566  
   567  	updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
   568  	check.Assert(err, IsNil)
   569  	check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)
   570  
   571  	// Check that updates were applied
   572  	check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, true)
   573  	check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)
   574  
   575  	// Disable DHCP forwarder config
   576  	newDhcpForwarderConfig.Enabled = false
   577  
   578  	// Update DHCP forwarder config
   579  	updatedEdgeDhcpForwarderConfig, err = edge.UpdateDhcpForwarder(newDhcpForwarderConfig)
   580  	check.Assert(err, IsNil)
   581  	check.Assert(updatedEdgeDhcpForwarderConfig, NotNil)
   582  
   583  	// Check that updates were applied
   584  	check.Assert(updatedEdgeDhcpForwarderConfig.Enabled, Equals, false)
   585  	check.Assert(updatedEdgeDhcpForwarderConfig.DhcpServers, DeepEquals, testDhcpServers)
   586  
   587  	_, err = edge.UpdateDhcpForwarder(&types.NsxtEdgeGatewayDhcpForwarder{})
   588  	check.Assert(err, IsNil)
   589  }
   590  
   591  // Test_NsxtEdgeSlaacProfile tests SLAAC profile (NSX-T Edge Gateway DHCPv6) retrieval and update
   592  func (vcd *TestVCD) Test_NsxtEdgeSlaacProfile(check *C) {
   593  	if vcd.skipAdminTests {
   594  		check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
   595  	}
   596  	skipNoNsxtConfiguration(vcd, check)
   597  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGatewaySlaacProfile)
   598  
   599  	edge, err := vcd.nsxtVdc.GetNsxtEdgeGatewayByName(vcd.config.VCD.Nsxt.EdgeGateway)
   600  	check.Assert(err, IsNil)
   601  	AddToCleanupList(vcd.config.VCD.Nsxt.EdgeGateway, "slaacProfile", vcd.config.VCD.Org, check.TestName())
   602  
   603  	// Fetch current SLAAC Profile
   604  	slaacProfile, err := edge.GetSlaacProfile()
   605  	check.Assert(err, IsNil)
   606  	check.Assert(slaacProfile, NotNil)
   607  	check.Assert(slaacProfile.Enabled, Equals, false)
   608  
   609  	// Create new SLAAC config in SLAAC mode
   610  	newSlaacProfile := &types.NsxtEdgeGatewaySlaacProfile{
   611  		Enabled: true,
   612  		Mode:    "SLAAC",
   613  		DNSConfig: types.NsxtEdgeGatewaySlaacProfileDNSConfig{
   614  			DNSServerIpv6Addresses: []string{"2001:4860:4860::8888", "2001:4860:4860::8844"},
   615  			DomainNames:            []string{"non-existing.org.tld", "fake.org.tld"},
   616  		},
   617  	}
   618  
   619  	// Update SLAAC profile
   620  	updatedSlaacProfile, err := edge.UpdateSlaacProfile(newSlaacProfile)
   621  	check.Assert(err, IsNil)
   622  	check.Assert(updatedSlaacProfile, NotNil)
   623  	check.Assert(updatedSlaacProfile, DeepEquals, newSlaacProfile)
   624  
   625  	// Create new SLAAC config in DHCPv6 mode
   626  	newSlaacProfileDhcpv6 := &types.NsxtEdgeGatewaySlaacProfile{
   627  		Enabled: true,
   628  		Mode:    "DHCPv6",
   629  		DNSConfig: types.NsxtEdgeGatewaySlaacProfileDNSConfig{
   630  			DNSServerIpv6Addresses: []string{},
   631  			DomainNames:            []string{},
   632  		},
   633  	}
   634  
   635  	// Update SLAAC profile
   636  	updatedSlaacProfileDhcpv6, err := edge.UpdateSlaacProfile(newSlaacProfileDhcpv6)
   637  	check.Assert(err, IsNil)
   638  	check.Assert(updatedSlaacProfileDhcpv6, NotNil)
   639  	check.Assert(updatedSlaacProfileDhcpv6, DeepEquals, newSlaacProfileDhcpv6)
   640  
   641  	// Cleanup
   642  	updatedSlaacProfile, err = edge.UpdateSlaacProfile(&types.NsxtEdgeGatewaySlaacProfile{Enabled: false, Mode: "DISABLED"})
   643  	check.Assert(err, IsNil)
   644  	check.Assert(updatedSlaacProfile, NotNil)
   645  }
   646  
   647  // Test_NsxtEdgeCreateWithT0AndExternalNetworks checks that IP Allocation counts and External
   648  // Network attachment works well with NSX-T T0 Gateway backed external network
   649  func (vcd *TestVCD) Test_NsxtEdgeCreateWithT0AndExternalNetworks(check *C) {
   650  	test_NsxtEdgeCreateWithExternalNetworks(vcd, check, vcd.config.VCD.Nsxt.Tier0router, types.ExternalNetworkBackingTypeNsxtTier0Router)
   651  }
   652  
   653  // Test_NsxtEdgeCreateWithT0VrfAndExternalNetworks checks that IP Allocation counts and External
   654  // Network attachment works well with NSX-T T0 VRF Gateway backed external network
   655  func (vcd *TestVCD) Test_NsxtEdgeCreateWithT0VrfAndExternalNetworks(check *C) {
   656  	test_NsxtEdgeCreateWithExternalNetworks(vcd, check, vcd.config.VCD.Nsxt.Tier0routerVrf, types.ExternalNetworkBackingTypeNsxtVrfTier0Router)
   657  }
   658  
   659  func test_NsxtEdgeCreateWithExternalNetworks(vcd *TestVCD, check *C, backingRouter, backingRouterType string) {
   660  	if vcd.client.Client.APIVCDMaxVersionIs("< 37.1") {
   661  		check.Skip("Segment Backed External Network uplinks are supported in VCD 10.4.1+")
   662  	}
   663  
   664  	if vcd.config.VCD.Nsxt.NsxtImportSegment == "" || vcd.config.VCD.Nsxt.NsxtImportSegment2 == "" {
   665  		check.Skip("NSX-T Imported Segments are not configured")
   666  	}
   667  
   668  	skipNoNsxtConfiguration(vcd, check)
   669  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)
   670  	vcd.skipIfNotSysAdmin(check)
   671  
   672  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   673  	check.Assert(err, IsNil)
   674  	check.Assert(adminOrg, NotNil)
   675  
   676  	nsxtVdc, err := adminOrg.GetVDCByName(vcd.config.VCD.Nsxt.Vdc, false)
   677  	if ContainsNotFound(err) {
   678  		check.Skip(fmt.Sprintf("No NSX-T VDC (%s) found - skipping test", vcd.config.VCD.Nsxt.Vdc))
   679  	}
   680  	check.Assert(err, IsNil)
   681  	check.Assert(nsxtVdc, NotNil)
   682  
   683  	// Setup 2 NSX-T Segment backed External Networks and 1 T0 or T0 VRF backed networks
   684  	nsxtManager, err := vcd.client.QueryNsxtManagerByName(vcd.config.VCD.Nsxt.Manager)
   685  	check.Assert(err, IsNil)
   686  	nsxtManagerId, err := BuildUrnWithUuid("urn:vcloud:nsxtmanager:", extractUuid(nsxtManager[0].HREF))
   687  	check.Assert(err, IsNil)
   688  
   689  	//	T0 backed external network
   690  	backingExtNet := getBackingIdByNameAndType(check, backingRouter, backingRouterType, vcd, nsxtManagerId)
   691  	nsxtExternalNetworkCfg := t0vrfBackedExternalNetworkConfig(vcd, check.TestName()+"-t0", "89.1.1", backingRouterType, backingExtNet, nsxtManagerId)
   692  	nsxtExternalNetwork, err := CreateExternalNetworkV2(vcd.client, nsxtExternalNetworkCfg)
   693  	check.Assert(err, IsNil)
   694  	check.Assert(nsxtExternalNetwork, NotNil)
   695  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks + nsxtExternalNetwork.ExternalNetwork.ID
   696  	AddToCleanupListOpenApi(nsxtExternalNetwork.ExternalNetwork.Name, check.TestName(), openApiEndpoint)
   697  
   698  	// First NSX-T Segment backed network
   699  	backingId1 := getBackingIdByNameAndType(check, vcd.config.VCD.Nsxt.NsxtImportSegment, types.ExternalNetworkBackingTypeNsxtSegment, vcd, nsxtManagerId)
   700  	segmentBackedNet1Cfg := t0vrfBackedExternalNetworkConfig(vcd, check.TestName()+"-1", "1.1.1", types.ExternalNetworkBackingTypeNsxtSegment, backingId1, nsxtManagerId)
   701  	segmentBackedNet1, err := CreateExternalNetworkV2(vcd.client, segmentBackedNet1Cfg)
   702  	check.Assert(err, IsNil)
   703  	check.Assert(segmentBackedNet1, NotNil)
   704  	openApiEndpoint = types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks + segmentBackedNet1.ExternalNetwork.ID
   705  	AddToCleanupListOpenApi(segmentBackedNet1.ExternalNetwork.Name, check.TestName(), openApiEndpoint)
   706  
   707  	// Second NSX-T Segment backed network
   708  	backingId2 := getBackingIdByNameAndType(check, vcd.config.VCD.Nsxt.NsxtImportSegment2, types.ExternalNetworkBackingTypeNsxtSegment, vcd, nsxtManagerId)
   709  	segmentBackedNet2Cfg := t0vrfBackedExternalNetworkConfig(vcd, check.TestName()+"-2", "4.4.4", types.ExternalNetworkBackingTypeNsxtSegment, backingId2, nsxtManagerId)
   710  	segmentBackedNet2, err := CreateExternalNetworkV2(vcd.client, segmentBackedNet2Cfg)
   711  	check.Assert(err, IsNil)
   712  	check.Assert(segmentBackedNet2, NotNil)
   713  	openApiEndpoint = types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointExternalNetworks + segmentBackedNet2.ExternalNetwork.ID
   714  	AddToCleanupListOpenApi(segmentBackedNet1.ExternalNetwork.Name, check.TestName(), openApiEndpoint)
   715  	// Setup 2 NSX-T Segment backed External Networks and 1 T0 or T0 VRF backed networks
   716  
   717  	egwDefinition := &types.OpenAPIEdgeGateway{
   718  		Name:        "nsx-t-edge",
   719  		Description: "nsx-t-edge-description",
   720  		OrgVdc: &types.OpenApiReference{
   721  			ID: nsxtVdc.Vdc.ID,
   722  		},
   723  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{
   724  			{
   725  				UplinkID: nsxtExternalNetwork.ExternalNetwork.ID,
   726  				Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
   727  					Gateway:      "5.1.1.1",
   728  					PrefixLength: 24,
   729  					Enabled:      true,
   730  				}}},
   731  				Connected: true,
   732  				Dedicated: false,
   733  			},
   734  			{
   735  				UplinkID: segmentBackedNet1.ExternalNetwork.ID,
   736  				Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
   737  					Gateway:              "1.1.1.1",
   738  					PrefixLength:         24,
   739  					Enabled:              true,
   740  					AutoAllocateIPRanges: true,
   741  					PrimaryIP:            "1.1.1.5",
   742  					TotalIPCount:         addrOf(4),
   743  				}}},
   744  				Connected: true,
   745  				Dedicated: false,
   746  			},
   747  			{
   748  				UplinkID: segmentBackedNet2.ExternalNetwork.ID,
   749  				Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
   750  					Gateway:              "4.4.4.1",
   751  					PrefixLength:         24,
   752  					Enabled:              true,
   753  					AutoAllocateIPRanges: true,
   754  					TotalIPCount:         addrOf(7),
   755  				}}},
   756  				Connected: true,
   757  				Dedicated: false,
   758  			},
   759  		},
   760  	}
   761  
   762  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
   763  	check.Assert(err, IsNil)
   764  	check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
   765  	openApiEndpoint = types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
   766  	PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)
   767  
   768  	// Retrieve edge gateway
   769  	retrievedEdge, err := adminOrg.GetNsxtEdgeGatewayById(createdEdge.EdgeGateway.ID)
   770  	check.Assert(err, IsNil)
   771  	check.Assert(retrievedEdge, NotNil)
   772  
   773  	// Check IP allocation in NSX-T Segment backed networks
   774  	totalAllocatedIpCountSegmentBacked, err := retrievedEdge.GetAllocatedIpCountByUplinkType(false, types.ExternalNetworkBackingTypeNsxtSegment)
   775  	check.Assert(err, IsNil)
   776  	check.Assert(totalAllocatedIpCountSegmentBacked, Equals, (4 + 7))
   777  
   778  	// Check IP allocation in NSX-T T0 backed networks
   779  	totalAllocatedIpCountT0backed, err := retrievedEdge.GetAllocatedIpCountByUplinkType(false, backingRouterType)
   780  	check.Assert(err, IsNil)
   781  	check.Assert(totalAllocatedIpCountT0backed, Equals, 1)
   782  
   783  	totalAllocatedIpCountForPrimaryUplink, err := retrievedEdge.GetPrimaryNetworkAllocatedIpCount(false)
   784  	check.Assert(err, IsNil)
   785  	check.Assert(totalAllocatedIpCountForPrimaryUplink, Equals, 1)
   786  
   787  	// Check IP allocation for all subnets
   788  	totalAllocatedIpCount, err := retrievedEdge.GetAllocatedIpCount(false)
   789  	check.Assert(err, IsNil)
   790  	check.Assert(totalAllocatedIpCount, Equals, (1 + 4 + 7))
   791  
   792  	createdEdge.EdgeGateway.Name = check.TestName() + "-renamed-edge"
   793  	updatedEdge, err := createdEdge.Update(createdEdge.EdgeGateway)
   794  	check.Assert(err, IsNil)
   795  	check.Assert(updatedEdge.EdgeGateway.Name, Equals, createdEdge.EdgeGateway.Name)
   796  
   797  	// Check IP allocation in NSX-T Segment backed networks
   798  	totalAllocatedIpCountSegmentBacked, err = updatedEdge.GetAllocatedIpCountByUplinkType(false, types.ExternalNetworkBackingTypeNsxtSegment)
   799  	check.Assert(err, IsNil)
   800  	check.Assert(totalAllocatedIpCountSegmentBacked, Equals, (4 + 7))
   801  
   802  	// Check IP allocation in NSX-T T0 backed networks
   803  	totalAllocatedIpCountT0backed, err = updatedEdge.GetAllocatedIpCountByUplinkType(false, backingRouterType)
   804  	check.Assert(err, IsNil)
   805  	check.Assert(totalAllocatedIpCountT0backed, Equals, 1)
   806  
   807  	// Check IP allocation for all subnets
   808  	totalAllocatedIpCount, err = updatedEdge.GetAllocatedIpCount(false)
   809  	check.Assert(err, IsNil)
   810  	check.Assert(totalAllocatedIpCount, Equals, (1 + 4 + 7))
   811  
   812  	// Cleanup
   813  	err = updatedEdge.Delete()
   814  	check.Assert(err, IsNil)
   815  
   816  	err = segmentBackedNet2.Delete()
   817  	check.Assert(err, IsNil)
   818  
   819  	err = segmentBackedNet1.Delete()
   820  	check.Assert(err, IsNil)
   821  
   822  	err = nsxtExternalNetwork.Delete()
   823  	check.Assert(err, IsNil)
   824  
   825  }
   826  
   827  func t0vrfBackedExternalNetworkConfig(vcd *TestVCD, name, ipPrefix string, backingType, backingId, NetworkProviderId string) *types.ExternalNetworkV2 {
   828  	net := &types.ExternalNetworkV2{
   829  		Name: name,
   830  		Subnets: types.ExternalNetworkV2Subnets{Values: []types.ExternalNetworkV2Subnet{
   831  			{
   832  				Gateway:      ipPrefix + ".1",
   833  				PrefixLength: 24,
   834  				IPRanges: types.ExternalNetworkV2IPRanges{Values: []types.ExternalNetworkV2IPRange{
   835  					{
   836  						StartAddress: ipPrefix + ".3",
   837  						EndAddress:   ipPrefix + ".50",
   838  					},
   839  				}},
   840  				Enabled: true,
   841  			},
   842  		}},
   843  		NetworkBackings: types.ExternalNetworkV2Backings{Values: []types.ExternalNetworkV2Backing{
   844  			{
   845  				BackingID: backingId,
   846  				NetworkProvider: types.NetworkProvider{
   847  					ID: NetworkProviderId,
   848  				},
   849  				BackingTypeValue: backingType,
   850  			},
   851  		}},
   852  	}
   853  
   854  	return net
   855  }