-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Provider VDC creation functions * Add data structure for Provider VDC creation * Convert simple queries to cumulativeQuery calls * Add test for Provider VDC creation * Add resource pool retrieval functions * Add vCenter retrieval functions * Add provider network pool data structures * Add network pool retrieval methods * Add resource pools to TestConfig structure * Add PVDC methods Delete, IsEnabled, Disable, Enable * Add Update method to provider VDC * Add vsphere_storage_profile methods * Add second storage profile to TestConfig * Add structure for storage profiles * Fix optimistic tests with network pools When the Provider VDC uses a network pool from a NSX-T manager that contains more than one network pool, it acquires all network pools from that manager, even if the second network pool was created after the provider VDC * Add PvDC tests for all network pool handlings Signed-off-by: Giuseppe Maxia <[email protected]>
- Loading branch information
1 parent
be0efa9
commit 91abc52
Showing
23 changed files
with
1,757 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* Fixed [Issue #1066](https://github.com/vmware/terraform-provider-vcd/issues/1066) - Not possible to handle more than 128 storage profiles [GH-580] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
* Added method `VCDClient.QueryNsxtManagerByHref` to retrieve a NSX-T manager by its ID/HREF [GH-580] | ||
* Added method `VCDClient.CreateProviderVdc` to create a Provider VDC [GH-580] | ||
* Added method `VCDClient.ResourcePoolsFromIds` to convert list of IDs to resource pools [GH-580] | ||
* Added `ProviderVdcExtended` methods `AddResourcePools`, `AddStorageProfiles`, `Delete`, `DeleteResourcePools`,`DeleteStorageProfiles`,`Disable`,`Enable`,`GetResourcePools`,`IsEnabled`,`Rename`,`Update` to fully manage a provider VDC [GH-580] | ||
* Added method `NetworkPool.GetOpenApiUrl` to generate the full URL of a network pool [GH-580] | ||
* Added `ResourcePool` methods `GetAvailableHardwareVersions` and `GetDefaultHardwareVersion` to get hardware versions [GH-580] | ||
* Added `VCDClient` method `GetAllResourcePools` to retrieve all resource pools regardless of vCenter affiliation [GH-580] | ||
* Added `VCDClient` method `GetAllVcenters` to retrieve all vCenters [GH-580] | ||
* Added `VCDClient` methods `GetNetworkPoolById`,`GetNetworkPoolByName`,`GetNetworkPoolSummaries` to retrieve network pools [GH-580] | ||
* Added `VCDClient` methods `GetVcenterById`,`GetVcenterByName` to retrieve vCenters [GH-580] | ||
* Added `VCenter` methods `GetAllResourcePools`,`VCenter.GetResourcePoolById`,`VCenter.GetResourcePoolByName` to retrieve resource pools [GH-580] | ||
* Added `VCenter` methods `GetAllStorageProfiles`,`GetStorageProfileById`,`GetStorageProfileByName` to retrieve storage profiles [GH-580] | ||
* Added method `VCenter.GetVimServerUrl` to retrieve the full URL of a vCenter within a VCD [GH-580] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright 2023 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. | ||
*/ | ||
|
||
package govcd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"github.com/vmware/go-vcloud-director/v2/types/v56" | ||
"github.com/vmware/go-vcloud-director/v2/util" | ||
"io" | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
) | ||
|
||
// executeJsonRequest is a wrapper around regular API call operations, similar to client.ExecuteRequest, but with JSON payback | ||
// Returns a http.Response object, which, in case of success, has its body still unread | ||
// Caller function has the responsibility for closing the response body | ||
func (client Client) executeJsonRequest(href, httpMethod string, inputStructure any, errorMessage string) (*http.Response, error) { | ||
|
||
text, err := json.MarshalIndent(inputStructure, " ", " ") | ||
if err != nil { | ||
return nil, err | ||
} | ||
requestHref, err := url.Parse(href) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var resp *http.Response | ||
body := strings.NewReader(string(text)) | ||
apiVersion := client.APIVersion | ||
headAccept := http.Header{} | ||
headAccept.Set("Accept", fmt.Sprintf("application/*+json;version=%s", apiVersion)) | ||
headAccept.Set("Content-Type", "application/*+json") | ||
request := client.newRequest(nil, nil, httpMethod, *requestHref, body, apiVersion, headAccept) | ||
resp, err = client.Http.Do(request) | ||
if err != nil { | ||
return nil, fmt.Errorf(errorMessage, err) | ||
} | ||
|
||
if resp.StatusCode < 200 || resp.StatusCode >= 300 { | ||
body, _ := io.ReadAll(resp.Body) | ||
util.ProcessResponseOutput(util.CallFuncName(), resp, string(body)) | ||
var jsonError types.OpenApiError | ||
err = json.Unmarshal(body, &jsonError) | ||
// By default, we return the whole response body as error message. This may also contain the stack trace | ||
message := string(body) | ||
// if the body contains a valid JSON representation of the error, we return a more agile message, using the | ||
// exposed fields, and hiding the stack trace from view | ||
if err == nil { | ||
message = fmt.Sprintf("%s - %s", jsonError.MinorErrorCode, jsonError.Message) | ||
} | ||
util.ProcessResponseOutput(util.CallFuncName(), resp, string(body)) | ||
return resp, fmt.Errorf(errorMessage, message) | ||
} | ||
|
||
return checkRespWithErrType(types.BodyTypeJSON, resp, err, &types.Error{}) | ||
} | ||
|
||
// closeBody is a wrapper function that should be used with "defer" after calling executeJsonRequest | ||
func closeBody(resp *http.Response) { | ||
err := resp.Body.Close() | ||
if err != nil { | ||
util.Logger.Printf("error closing response body - Called by %s: %s\n", util.CallFuncName(), err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright 2023 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. | ||
*/ | ||
|
||
package govcd | ||
|
||
import ( | ||
"fmt" | ||
"github.com/vmware/go-vcloud-director/v2/types/v56" | ||
"net/url" | ||
) | ||
|
||
type NetworkPool struct { | ||
NetworkPool *types.NetworkPool | ||
vcdClient *VCDClient | ||
} | ||
|
||
// GetOpenApiUrl retrieves the full URL of a network pool | ||
func (np NetworkPool) GetOpenApiUrl() (string, error) { | ||
response, err := url.JoinPath(np.vcdClient.sessionHREF.String(), "admin", "extension", "networkPool", np.NetworkPool.Id) | ||
if err != nil { | ||
return "", err | ||
} | ||
return response, nil | ||
} | ||
|
||
// GetNetworkPoolSummaries retrieves the list of all available network pools | ||
func (vcdClient *VCDClient) GetNetworkPoolSummaries(queryParameters url.Values) ([]*types.NetworkPool, error) { | ||
client := vcdClient.Client | ||
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNetworkPoolSummaries | ||
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
urlRef, err := client.OpenApiBuildEndpoint(endpoint) | ||
if err != nil { | ||
return nil, err | ||
} | ||
typeResponse := []*types.NetworkPool{{}} | ||
err = client.OpenApiGetAllItems(apiVersion, urlRef, queryParameters, &typeResponse, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return typeResponse, nil | ||
} | ||
|
||
// GetNetworkPoolById retrieves Network Pool with a given ID | ||
func (vcdClient *VCDClient) GetNetworkPoolById(id string) (*NetworkPool, error) { | ||
if id == "" { | ||
return nil, fmt.Errorf("network pool lookup requires ID") | ||
} | ||
|
||
client := vcdClient.Client | ||
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointNetworkPools | ||
apiVersion, err := client.getOpenApiHighestElevatedVersion(endpoint) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
urlRef, err := client.OpenApiBuildEndpoint(endpoint, id) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
response := &NetworkPool{ | ||
vcdClient: vcdClient, | ||
NetworkPool: &types.NetworkPool{}, | ||
} | ||
|
||
err = client.OpenApiGetItem(apiVersion, urlRef, nil, response.NetworkPool, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return response, nil | ||
} | ||
|
||
// GetNetworkPoolByName retrieves a network pool with a given name | ||
// Note. It will return an error if multiple network pools exist with the same name | ||
func (vcdClient *VCDClient) GetNetworkPoolByName(name string) (*NetworkPool, error) { | ||
if name == "" { | ||
return nil, fmt.Errorf("network pool lookup requires name") | ||
} | ||
|
||
queryParameters := url.Values{} | ||
queryParameters.Add("filter", "name=="+name) | ||
|
||
filteredNetworkPools, err := vcdClient.GetNetworkPoolSummaries(queryParameters) | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting network pools: %s", err) | ||
} | ||
|
||
if len(filteredNetworkPools) == 0 { | ||
return nil, fmt.Errorf("no network pool found with name '%s' - %s", name, ErrorEntityNotFound) | ||
} | ||
|
||
if len(filteredNetworkPools) > 1 { | ||
return nil, fmt.Errorf("more than one network pool found with name '%s'", name) | ||
} | ||
|
||
return vcdClient.GetNetworkPoolById(filteredNetworkPools[0].Id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//go:build providervdc || functional || ALL | ||
|
||
package govcd | ||
|
||
import ( | ||
"fmt" | ||
"github.com/kr/pretty" | ||
. "gopkg.in/check.v1" | ||
) | ||
|
||
func (vcd *TestVCD) Test_GetNetworkPools(check *C) { | ||
|
||
if vcd.skipAdminTests { | ||
check.Skip("this test requires system administrator privileges") | ||
} | ||
knownNetworkPoolName := vcd.config.VCD.NsxtProviderVdc.NetworkPool | ||
networkPools, err := vcd.client.GetNetworkPoolSummaries(nil) | ||
check.Assert(err, IsNil) | ||
check.Assert(len(networkPools) > 0, Equals, true) | ||
|
||
checkNetworkPoolName := false | ||
foundNetworkPool := false | ||
if knownNetworkPoolName != "" { | ||
checkNetworkPoolName = true | ||
} | ||
|
||
for i, nps := range networkPools { | ||
if nps.Name == knownNetworkPoolName { | ||
foundNetworkPool = true | ||
} | ||
networkPoolById, err := vcd.client.GetNetworkPoolById(nps.Id) | ||
check.Assert(err, IsNil) | ||
check.Assert(networkPoolById, NotNil) | ||
check.Assert(networkPoolById.NetworkPool.Id, Equals, nps.Id) | ||
check.Assert(networkPoolById.NetworkPool.Name, Equals, nps.Name) | ||
|
||
networkPoolByName, err := vcd.client.GetNetworkPoolByName(nps.Name) | ||
check.Assert(err, IsNil) | ||
check.Assert(networkPoolByName, NotNil) | ||
check.Assert(networkPoolByName.NetworkPool.Id, Equals, nps.Id) | ||
check.Assert(networkPoolByName.NetworkPool.Name, Equals, nps.Name) | ||
if testVerbose { | ||
fmt.Printf("%d, %# v\n", i, pretty.Formatter(networkPoolByName.NetworkPool)) | ||
} | ||
} | ||
if checkNetworkPoolName { | ||
check.Assert(foundNetworkPool, Equals, true) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.