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

     1  //go:build network || nsxt || functional || openapi || ALL
     2  
     3  package govcd
     4  
     5  import (
     6  	"fmt"
     7  	"net/url"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    12  	. "gopkg.in/check.v1"
    13  )
    14  
    15  // Test_IpSpaceIpAllocation tests out IP Space integration with other components
    16  func (vcd *TestVCD) Test_IpSpaceIpAllocation(check *C) {
    17  	if vcd.skipAdminTests {
    18  		check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
    19  	}
    20  	skipNoNsxtConfiguration(vcd, check)
    21  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointIpSpaceIpAllocations)
    22  
    23  	ipSpace := createIpSpace(vcd, check)
    24  	extNet := createExternalNetwork(vcd, check)
    25  
    26  	// IP Space uplink (not directly referenced anywhere, but is required to make IP allocations)
    27  	ipSpaceUplink := createIpSpaceUplink(vcd, check, extNet.ExternalNetwork.ID, ipSpace.IpSpace.ID)
    28  
    29  	// Create NSX-T Edge Gateway
    30  	edgeGw := createNsxtEdgeGateway(vcd, check, extNet.ExternalNetwork.ID)
    31  
    32  	// Floating IP Allocation request
    33  	floatingIpAllocationRequest := &types.IpSpaceIpAllocationRequest{
    34  		Type:     "FLOATING_IP",
    35  		Quantity: addrOf(1),
    36  	}
    37  	performIpAllocationChecks(vcd, check, ipSpace.IpSpace.ID, edgeGw.EdgeGateway.ID, floatingIpAllocationRequest)
    38  
    39  	// Prefix allocation request
    40  	prefixAllocationRequest := &types.IpSpaceIpAllocationRequest{
    41  		Type:         "IP_PREFIX",
    42  		Quantity:     addrOf(1),
    43  		PrefixLength: addrOf(31),
    44  	}
    45  	performIpAllocationChecks(vcd, check, ipSpace.IpSpace.ID, edgeGw.EdgeGateway.ID, prefixAllocationRequest)
    46  
    47  	// Cleanup
    48  	err := edgeGw.Delete()
    49  	check.Assert(err, IsNil)
    50  
    51  	err = ipSpaceUplink.Delete()
    52  	check.Assert(err, IsNil)
    53  
    54  	err = extNet.Delete()
    55  	check.Assert(err, IsNil)
    56  
    57  	err = ipSpace.Delete()
    58  	check.Assert(err, IsNil)
    59  }
    60  
    61  func performIpAllocationChecks(vcd *TestVCD, check *C, ipSpaceId, edgeGatewayId string, ipSpaceAllocationRequest *types.IpSpaceIpAllocationRequest) {
    62  	// resulting slice must have 1 IP as the requested quantity is 1
    63  	ipAllocationResult, err := vcd.org.IpSpaceAllocateIp(ipSpaceId, ipSpaceAllocationRequest)
    64  	check.Assert(err, IsNil)
    65  	check.Assert(len(ipAllocationResult), Equals, 1)
    66  
    67  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + fmt.Sprintf(types.OpenApiEndpointIpSpaceIpAllocations, ipSpaceId) + ipAllocationResult[0].ID
    68  	PrependToCleanupListOpenApi("NSX-T IP Space IP Allocation", check.TestName(), openApiEndpoint)
    69  
    70  	// Check IP allocation suggestion endpoint
    71  	performIpSuggestionChecks(vcd, check, ipSpaceId, edgeGatewayId, ipSpaceAllocationRequest)
    72  
    73  	// Get IP Allocation
    74  	ipAllocation, err := vcd.org.GetIpSpaceAllocationByTypeAndValue(ipSpaceId, ipSpaceAllocationRequest.Type, ipAllocationResult[0].Value, nil)
    75  	check.Assert(err, IsNil)
    76  	check.Assert(ipAllocation, NotNil)
    77  	check.Assert(ipAllocation.IpSpaceIpAllocation.UsageState, Equals, types.IpSpaceIpAllocationUnused)
    78  
    79  	// Get IP Allocation by ID
    80  	ipAllocationById, err := vcd.org.GetIpSpaceAllocationById(ipSpaceId, ipAllocation.IpSpaceIpAllocation.ID)
    81  	check.Assert(err, IsNil)
    82  	check.Assert(ipAllocationById, NotNil)
    83  	check.Assert(ipAllocationById.IpSpaceIpAllocation, DeepEquals, ipAllocation.IpSpaceIpAllocation)
    84  
    85  	// Set the IP for manual usage
    86  	ipAllocation.IpSpaceIpAllocation.UsageState = types.IpSpaceIpAllocationUsedManual
    87  	ipAllocation.IpSpaceIpAllocation.Description = "Manual usage description"
    88  	updatedIpAllocationManual, err := ipAllocation.Update(ipAllocation.IpSpaceIpAllocation)
    89  	check.Assert(err, IsNil)
    90  	check.Assert(updatedIpAllocationManual.IpSpaceIpAllocation.ID, Equals, ipAllocation.IpSpaceIpAllocation.ID)
    91  	check.Assert(updatedIpAllocationManual.IpSpaceIpAllocation.UsageState, Equals, types.IpSpaceIpAllocationUsedManual)
    92  
    93  	// Removal manual allocation
    94  	ipAllocation.IpSpaceIpAllocation.UsageState = types.IpSpaceIpAllocationUnused
    95  	ipAllocation.IpSpaceIpAllocation.Description = ""
    96  	releasedIpAllocation, err := updatedIpAllocationManual.Update(ipAllocation.IpSpaceIpAllocation)
    97  	check.Assert(err, IsNil)
    98  	check.Assert(releasedIpAllocation, NotNil)
    99  	check.Assert(releasedIpAllocation.IpSpaceIpAllocation.UsageState, Equals, types.IpSpaceIpAllocationUnused)
   100  
   101  	err = updatedIpAllocationManual.Delete()
   102  	check.Assert(err, IsNil)
   103  
   104  	// Get IP Space by ID
   105  	ipSpace, err := vcd.client.GetIpSpaceById(ipSpaceId)
   106  	check.Assert(err, IsNil)
   107  
   108  	// Attempt to search for allocations when none exist
   109  	allAllocations, err := ipSpace.GetAllIpSpaceAllocations(ipSpaceAllocationRequest.Type, nil)
   110  	check.Assert(err, IsNil)
   111  	check.Assert(len(allAllocations), Equals, 0)
   112  
   113  	// allocate IP
   114  	allocationByIpSpaceResult, err := ipSpace.AllocateIp(vcd.org.Org.ID, vcd.org.Org.Name, ipSpaceAllocationRequest)
   115  	check.Assert(err, IsNil)
   116  	check.Assert(len(allocationByIpSpaceResult), Equals, 1)
   117  
   118  	// Remove
   119  	ipAllocationByIpSpaceResult, err := vcd.org.GetIpSpaceAllocationByTypeAndValue(ipSpaceId, ipSpaceAllocationRequest.Type, allocationByIpSpaceResult[0].Value, nil)
   120  	check.Assert(err, IsNil)
   121  	check.Assert(ipAllocation, NotNil)
   122  
   123  	err = ipAllocationByIpSpaceResult.Delete()
   124  	check.Assert(err, IsNil)
   125  
   126  }
   127  
   128  func performIpSuggestionChecks(vcd *TestVCD, check *C, ipSpaceId, edgeGatewayId string, ipSpaceAllocationRequest *types.IpSpaceIpAllocationRequest) {
   129  	// Get IP suggestions without additional filters
   130  	floatingIpSuggestions, err := vcd.client.GetAllIpSpaceFloatingIpSuggestions(edgeGatewayId, nil)
   131  	check.Assert(err, IsNil)
   132  	check.Assert(len(floatingIpSuggestions) > 0, Equals, true)
   133  	if ipSpaceAllocationRequest.Type == "FLOATING_IP" {
   134  		check.Assert(len(floatingIpSuggestions[0].UnusedValues), Equals, 1)
   135  	}
   136  
   137  	// Get IP suggestions only for IPv4
   138  	queryParams := url.Values{}
   139  	queryParams.Set("filter", "ipType==IPV4")
   140  	floatingIpSuggestionsWithFilterIpv4, err := vcd.client.GetAllIpSpaceFloatingIpSuggestions(edgeGatewayId, queryParams)
   141  	check.Assert(err, IsNil)
   142  	check.Assert(len(floatingIpSuggestionsWithFilterIpv4) > 0, Equals, true)
   143  	if ipSpaceAllocationRequest.Type == "FLOATING_IP" {
   144  		check.Assert(len(floatingIpSuggestionsWithFilterIpv4[0].UnusedValues), Equals, 1)
   145  	}
   146  
   147  	// Get IP suggestions only for IPv6
   148  	queryParams.Set("filter", "ipType==IPV6")
   149  	floatingIpSuggestionsWithFilterIpv6, err := vcd.client.GetAllIpSpaceFloatingIpSuggestions(edgeGatewayId, queryParams)
   150  	check.Assert(err, IsNil)
   151  	check.Assert(len(floatingIpSuggestionsWithFilterIpv6) > 0, Equals, false)
   152  
   153  	// check IP suggestions with invalid Edge Gateway - it returns ACCESS_TO_RESOURCE_IS_FORBIDDEN
   154  	// queryParams.Set("filter", fmt.Sprintf("gatewayId==%s", "urn:vcloud:gateway:00000000-0000-0000-0000-000000000000"))
   155  	floatingIpSuggestions2, err := vcd.client.GetAllIpSpaceFloatingIpSuggestions("urn:vcloud:gateway:00000000-0000-0000-0000-000000000000", nil)
   156  	check.Assert(strings.Contains(err.Error(), "ACCESS_TO_RESOURCE_IS_FORBIDDEN"), Equals, true)
   157  	check.Assert(floatingIpSuggestions2, IsNil)
   158  
   159  	// check with empty filter - it cannot be used this way (edge gateway is mandatory)
   160  	floatingIpSuggestions3, err := vcd.client.GetAllIpSpaceFloatingIpSuggestions("", nil)
   161  	check.Assert(strings.Contains(err.Error(), "edge gateway ID is mandatory"), Equals, true)
   162  	check.Assert(floatingIpSuggestions3, IsNil)
   163  }
   164  
   165  func createIpSpaceUplink(vcd *TestVCD, check *C, extNetId, ipSpaceId string) *IpSpaceUplink {
   166  	// Create Uplink configuration
   167  	uplinkConfig := &types.IpSpaceUplink{
   168  		Name:               check.TestName(),
   169  		Description:        "IP SPace Uplink for External Network (Provider Gateway)",
   170  		ExternalNetworkRef: &types.OpenApiReference{ID: extNetId},
   171  		IPSpaceRef:         &types.OpenApiReference{ID: ipSpaceId},
   172  	}
   173  
   174  	createdIpSpaceUplink, err := vcd.client.CreateIpSpaceUplink(uplinkConfig)
   175  	check.Assert(err, IsNil)
   176  	check.Assert(createdIpSpaceUplink, NotNil)
   177  
   178  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceUplinks + createdIpSpaceUplink.IpSpaceUplink.ID
   179  	AddToCleanupListOpenApi(createdIpSpaceUplink.IpSpaceUplink.Name, check.TestName(), openApiEndpoint)
   180  
   181  	time.Sleep(3 * time.Second)
   182  	err = vcd.client.Client.WaitForRouteAdvertisementTasks()
   183  	check.Assert(err, IsNil)
   184  
   185  	return createdIpSpaceUplink
   186  }
   187  
   188  func createNsxtEdgeGateway(vcd *TestVCD, check *C, extNetId string) *NsxtEdgeGateway {
   189  	egwDefinition := &types.OpenAPIEdgeGateway{
   190  		Name:        check.TestName(),
   191  		Description: "nsx-t-edge-description",
   192  		OrgVdc: &types.OpenApiReference{
   193  			ID: vcd.nsxtVdc.Vdc.ID,
   194  		},
   195  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{
   196  			types.EdgeGatewayUplinks{
   197  				UplinkID: extNetId,
   198  			},
   199  		},
   200  	}
   201  
   202  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
   203  	check.Assert(err, IsNil)
   204  	check.Assert(adminOrg, NotNil)
   205  
   206  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
   207  	check.Assert(err, IsNil)
   208  	check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
   209  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
   210  	// Using Prepend function so that Edge Gateway is removed before parent External Network is being removed
   211  	PrependToCleanupListOpenApi("NSX-T Edge Gateway", check.TestName(), openApiEndpoint)
   212  
   213  	return createdEdge
   214  }