Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NSX-T ALB Pools #414

Merged
merged 8 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changes/v2.14.0/410-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Added types `VdcGroup`, `types.VdcGroup`, `types.ParticipatingOrgVdcs`, `types.CandidateVdc`, `types.DfwPolicies` and `types.DefaultPolicy` for handling VDC groups with corresponding
methods `adminOrg.CreateNsxtVdcGroup`, `adminOrg.CreateVdcGroup`, `adminOrg.GetAllNsxtVdcGroupCandidates`, `adminOrg.GetAllVdcGroupCandidates`, `adminOrg.GetAllVdcGroups`, `adminOrg.GetVdcGroupByName`, `adminOrg.GetVdcGroupById`, `vdcGroup.Update`, `vdcGroup.GenericUpdate`, `vdcGroup.Delete`, `vdcGroup.DisableDefaultPolicy`, `vdcGroup.EnableDefaultPolicy`, `vdcGroup.GetDfwPolicies`, `vdcGroup.DeActivateDfw`, `vdcGroup.ActivateDfw`, `vdcGroup.UpdateDefaultDfwPolicies`, `vdcGroup.UpdateDfwPolicies` [GH-410]
3 changes: 3 additions & 0 deletions .changes/v2.14.0/414-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* Added support for ALB Pool to NSX-T Edge Gateway via type `NsxtAlbPool` and functions `GetAllAlbPools`,
`GetAllAlbPoolSummaries`, `GetAlbPoolByName`, `GetAlbPoolById`, `CreateNsxtAlbPool`, `nsxtAlbPool.Update`,
`nsxtAlbPool.Delete` [GH-414]
2 changes: 2 additions & 0 deletions govcd/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ At least one of the following tags should be defined:
* user: Runs user related tests
* vapp: Runs vapp related tests
* vdc: Runs vdc related tests
* vdcGroup: Runs vdc group related tests
* certificate Runs certificate related tests
* vm: Runs vm related tests

Examples:
Expand Down
4 changes: 2 additions & 2 deletions govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build api || openapi || functional || catalog || vapp || gateway || network || org || query || extnetwork || task || vm || vdc || system || disk || lb || lbAppRule || lbAppProfile || lbServerPool || lbServiceMonitor || lbVirtualServer || user || search || nsxv || nsxt || auth || affinity || role || alb || certificate || ALL
// +build api openapi functional catalog vapp gateway network org query extnetwork task vm vdc system disk lb lbAppRule lbAppProfile lbServerPool lbServiceMonitor lbVirtualServer user search nsxv nsxt auth affinity role alb certificate ALL
//go:build api || openapi || functional || catalog || vapp || gateway || network || org || query || extnetwork || task || vm || vdc || system || disk || lb || lbAppRule || lbAppProfile || lbServerPool || lbServiceMonitor || lbVirtualServer || user || search || nsxv || nsxt || auth || affinity || role || alb || certificate || vdcGroup || ALL
// +build api openapi functional catalog vapp gateway network org query extnetwork task vm vdc system disk lb lbAppRule lbAppProfile lbServerPool lbServiceMonitor lbVirtualServer user search nsxv nsxt auth affinity role alb certificate vdcGroup ALL

/*
* Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
Expand Down
36 changes: 17 additions & 19 deletions govcd/certificate_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ package govcd

import (
"fmt"
"net/url"
"strings"

"github.com/vmware/go-vcloud-director/v2/types/v56"
"net/url"
)

// Certificate is a structure defining a certificate in VCD
Expand Down Expand Up @@ -186,42 +184,42 @@ func (adminOrg *AdminOrg) GetAllCertificatesFromLibrary(queryParameters url.Valu
// https://github.com/golang/go/issues/4013
// https://github.com/czos/goamz/pull/11/files
func getCertificateFromLibraryByName(client *Client, name string, additionalHeader map[string]string) (*Certificate, error) {
var params = url.Values{}

slowSearch := false
versionWithNoBug, err := client.VersionEqualOrGreater("10.3", 3)
slowSearch, params, err := shouldDoSlowSearch("alias", name, client)
if err != nil {
return nil, err
}
if (!versionWithNoBug && (strings.Contains(name, ",") || strings.Contains(name, ";"))) ||
strings.Contains(name, " ") || strings.Contains(name, "+") || strings.Contains(name, "*") {
slowSearch = true
} else {
params.Set("filter", fmt.Sprintf("alias==%s", url.QueryEscape(name)))
params.Set("filterEncoded", "true")
}

var foundCertificates []*Certificate
certificates, err := getAllCertificateFromLibrary(client, params, additionalHeader)
if err != nil {
return nil, err
}
if len(certificates) == 0 {
return nil, ErrorEntityNotFound
}
foundCertificates = append(foundCertificates, certificates[0])

if slowSearch {
foundCertificates = nil
for _, certificate := range certificates {
if certificate.CertificateLibrary.Alias == name {
return certificate, nil
foundCertificates = append(foundCertificates, certificate)
}
}
return nil, ErrorEntityNotFound
if len(foundCertificates) == 0 {
return nil, ErrorEntityNotFound
}
if len(foundCertificates) > 1 {
return nil, fmt.Errorf("more than one certificate found with name '%s'", name)
}
}

if len(certificates) > 1 {
return nil, fmt.Errorf("more than one certificate found with name '%s'", name)
if len(certificates) > 1 && !slowSearch {
{
return nil, fmt.Errorf("more than one certificate found with name '%s'", name)
}
}
return certificates[0], nil
return foundCertificates[0], nil
}

// GetCertificateFromLibraryByName retrieves certificate from certificate library by given name
Expand Down
8 changes: 0 additions & 8 deletions govcd/certificate_management_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ import (
. "gopkg.in/check.v1"
)

var (
//go:embed test-resources/cert.pem
certificate string

//go:embed test-resources/key.pem
privateKey string
)

func (vcd *TestVCD) Test_CertificateInLibrary(check *C) {
if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
Expand Down
20 changes: 20 additions & 0 deletions govcd/certificates_embedded_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build functional || openapi || certificate || alb || nsxt || ALL
// +build functional openapi certificate alb nsxt ALL

/*
* Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
*/

package govcd

import (
_ "embed"
)

var (
//go:embed test-resources/cert.pem
certificate string

//go:embed test-resources/key.pem
privateKey string
)
10 changes: 0 additions & 10 deletions govcd/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,16 +858,6 @@ func extractIdsFromOpenApiReferences(refs []types.OpenApiReference) []string {
return resultStrings
}

// contains checks if a slice contains element
func contains(s []string, element string) bool {
for _, a := range s {
if a == element {
return true
}
}
return false
}

// checkSkipWhenApiToken skips the test if the connection was established using an API token
func (vcd *TestVCD) checkSkipWhenApiToken(check *C) {
if vcd.client.Client.UsingAccessToken {
Expand Down
215 changes: 215 additions & 0 deletions govcd/nsxt_alb_pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
*/

package govcd

import (
"fmt"
"net/url"

"github.com/vmware/go-vcloud-director/v2/types/v56"
)

// NsxtAlbPool defines configuration of a single NSX-T ALB Pool. Pools maintain the list of servers assigned to them and
// perform health monitoring, load balancing, persistence. A pool may only be used or referenced by only one virtual
// service at a time.
type NsxtAlbPool struct {
NsxtAlbPool *types.NsxtAlbPool
vcdClient *VCDClient
}

// GetAllAlbPoolSummaries retrieves partial information for type `NsxtAlbPool`, but it is the only way to retrieve all ALB
// pools for Edge Gateway
func (vcdClient *VCDClient) GetAllAlbPoolSummaries(edgeGatewayId string, queryParameters url.Values) ([]*NsxtAlbPool, error) {
client := vcdClient.Client

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPoolSummaries
apiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return nil, err
}

urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, edgeGatewayId))
if err != nil {
return nil, err
}

typeResponses := []*types.NsxtAlbPool{{}}
err = client.OpenApiGetAllItems(apiVersion, urlRef, queryParameters, &typeResponses, nil)
if err != nil {
return nil, err
}

// Wrap all typeResponses into NsxtAlbPool types with client
wrappedResponses := make([]*NsxtAlbPool, len(typeResponses))
for sliceIndex := range typeResponses {
wrappedResponses[sliceIndex] = &NsxtAlbPool{
NsxtAlbPool: typeResponses[sliceIndex],
vcdClient: vcdClient,
}
}

return wrappedResponses, nil
}

// GetAllAlbPools uses GetAllAlbPoolSummaries behind the scenes and the fetches complete data for all ALB Pools. This
// has performance penalty because each ALB Pool is fetched individually.
func (vcdClient *VCDClient) GetAllAlbPools(edgeGatewayId string, queryParameters url.Values) ([]*NsxtAlbPool, error) {
allAlbPoolSummaries, err := vcdClient.GetAllAlbPoolSummaries(edgeGatewayId, queryParameters)
if err != nil {
return nil, fmt.Errorf("error retrieving all ALB Pool summaries: %s", err)
}

// Loop over all Summaries and retrieve complete information
allAlbPools := make([]*NsxtAlbPool, len(allAlbPoolSummaries))
for index := range allAlbPoolSummaries {

allAlbPools[index], err = vcdClient.GetAlbPoolById(allAlbPoolSummaries[index].NsxtAlbPool.ID)
if err != nil {
return nil, fmt.Errorf("error retrieving complete ALB Pool: %s", err)
}

}

return allAlbPools, nil
}

// GetAlbPoolByName fetches ALB Pool By Name
func (vcdClient *VCDClient) GetAlbPoolByName(edgeGatewayId string, name string) (*NsxtAlbPool, error) {
queryParameters := copyOrNewUrlValues(nil)
queryParameters.Add("filter", "name=="+name)

allAlbPools, err := vcdClient.GetAllAlbPools(edgeGatewayId, queryParameters)
if err != nil {
return nil, fmt.Errorf("error retrieving ALB Pool with Name '%s': %s", name, err)
}

if len(allAlbPools) == 0 {
return nil, fmt.Errorf("%s: could not find ALB Pool with Name '%s'", ErrorEntityNotFound, name)
}

if len(allAlbPools) > 1 {
return nil, fmt.Errorf("found more than 1 ALB Pool with Name '%s'", name)
}

return allAlbPools[0], nil
}

// GetAlbPoolById fetches ALB Pool By Id
func (vcdClient *VCDClient) GetAlbPoolById(id string) (*NsxtAlbPool, error) {
client := vcdClient.Client

if id == "" {
return nil, fmt.Errorf("ID is required to lookup NSX-T ALB Pool by ID")
}

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools
apiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return nil, err
}

urlRef, err := client.OpenApiBuildEndpoint(endpoint, id)
if err != nil {
return nil, err
}

typeResponse := &types.NsxtAlbPool{}
err = client.OpenApiGetItem(apiVersion, urlRef, nil, &typeResponse, nil)
if err != nil {
return nil, err
}

wrappedResponse := &NsxtAlbPool{
NsxtAlbPool: typeResponse,
vcdClient: vcdClient,
}

return wrappedResponse, nil
}

// CreateNsxtAlbPool creates NSX-T ALB Pool based on supplied configuration
func (vcdClient *VCDClient) CreateNsxtAlbPool(albPoolConfig *types.NsxtAlbPool) (*NsxtAlbPool, error) {
client := vcdClient.Client

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return nil, err
}

urlRef, err := client.OpenApiBuildEndpoint(endpoint)
if err != nil {
return nil, err
}

returnObject := &NsxtAlbPool{
NsxtAlbPool: &types.NsxtAlbPool{},
vcdClient: vcdClient,
}

err = client.OpenApiPostItem(minimumApiVersion, urlRef, nil, albPoolConfig, returnObject.NsxtAlbPool, nil)
if err != nil {
return nil, fmt.Errorf("error creating NSX-T ALB Pool: %s", err)
}

return returnObject, nil
}

// Update updates NSX-T ALB Pool based on supplied configuration
func (nsxtAlbPool *NsxtAlbPool) Update(albPoolConfig *types.NsxtAlbPool) (*NsxtAlbPool, error) {
client := nsxtAlbPool.vcdClient.Client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return nil, err
}

if albPoolConfig.ID == "" {
return nil, fmt.Errorf("cannot update NSX-T ALB Pool without ID")
}

urlRef, err := client.OpenApiBuildEndpoint(endpoint, albPoolConfig.ID)
if err != nil {
return nil, err
}

responseAlbController := &NsxtAlbPool{
NsxtAlbPool: &types.NsxtAlbPool{},
vcdClient: nsxtAlbPool.vcdClient,
}

err = client.OpenApiPutItem(minimumApiVersion, urlRef, nil, albPoolConfig, responseAlbController.NsxtAlbPool, nil)
if err != nil {
return nil, fmt.Errorf("error updating NSX-T ALB Pool: %s", err)
}

return responseAlbController, nil
}

// Delete deletes NSX-T ALB Pool
func (nsxtAlbPool *NsxtAlbPool) Delete() error {
client := nsxtAlbPool.vcdClient.Client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbPools
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return err
}

if nsxtAlbPool.NsxtAlbPool.ID == "" {
return fmt.Errorf("cannot delete NSX-T ALB Pool without ID")
}

urlRef, err := client.OpenApiBuildEndpoint(endpoint, nsxtAlbPool.NsxtAlbPool.ID)
if err != nil {
return err
}

err = client.OpenApiDeleteItem(minimumApiVersion, urlRef, nil, nil)
if err != nil {
return fmt.Errorf("error deleting NSX-T ALB Pool: %s", err)
}

return nil
}
Loading