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 }