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 NSX-T ALB provider configuration support #398

Merged
merged 6 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
14 changes: 14 additions & 0 deletions .changes/v2.13.0/398-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* Added types `NsxtAlbController` and `types.NsxtAlbController` for handling NSX-T ALB Controllers with corresponding
functions `GetAllAlbControllers`, `GetAlbControllerByName`, `GetAlbControllerById`, `GetAlbControllerByUrl`,
`CreateNsxtAlbController`, `Update`, `Delete` [GH-398]
* Added types `NsxtAlbCloud` and `types.NsxtAlbCloud` for handling NSX-T ALB Clouds with corresponding functions
`GetAllAlbClouds`, `GetAlbCloudByName`, `GetAlbCloudById`, `CreateAlbCloud`, `Delete` [GH-398]
* Added type `NsxtAlbImportableCloud` and `types.NsxtAlbImportableCloud` for listing NSX-T ALB Importable Clouds with
corresponding functions `GetAllAlbImportableClouds`, `GetAlbImportableCloudByName`, `GetAlbImportableCloudById`
[GH-398]
* Added types `NsxtAlbServiceEngineGroup` and `types.NsxtAlbServiceEngineGroup` for handling NSX-T ALB Service Engine
Groups with corresponding functions `GetAllNsxtAlbServiceEngineGroups`, `GetAlbServiceEngineGroupByName`,
`GetAlbServiceEngineGroupById`, `CreateNsxtAlbServiceEngineGroup`, `Update`, `Delete`, `Sync` [GH-398]
* Added types `NsxtAlbImportableServiceEngineGroups` and `types.NsxtAlbImportableServiceEngineGroups` for listing NSX-T
ALB Importable Service Engine Groups with corresponding functions `GetAllAlbImportableServiceEngineGroups`,
`GetAlbImportableServiceEngineGroupByName`, `GetAlbImportableServiceEngineGroupById` [GH-398]
30 changes: 28 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 || 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 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 || 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 ALL

/*
* Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
Expand Down Expand Up @@ -171,6 +171,11 @@ type TestConfig struct {
ExternalNetwork string `yaml:"externalNetwork"`
EdgeGateway string `yaml:"edgeGateway"`
NsxtImportSegment string `yaml:"nsxtImportSegment"`

NsxtAlbControllerUrl string `yaml:"nsxtAlbControllerUrl"`
NsxtAlbControllerUser string `yaml:"nsxtAlbControllerUser"`
NsxtAlbControllerPassword string `yaml:"nsxtAlbControllerPassword"`
NsxtAlbImportableCloud string `yaml:"nsxtAlbImportableCloud"`
} `yaml:"nsxt"`
} `yaml:"vcd"`
Logging struct {
Expand Down Expand Up @@ -1836,6 +1841,27 @@ func skipNoNsxtConfiguration(vcd *TestVCD, check *C) {
}
}

func skipNoNsxtAlbConfiguration(vcd *TestVCD, check *C) {
skipNoNsxtConfiguration(vcd, check)
generalMessage := "Missing NSX-T ALB config: "

if vcd.config.VCD.Nsxt.NsxtAlbControllerUrl == "" {
check.Skip(generalMessage + "No NSX-T ALB Controller URL specified in configuration")
}

if vcd.config.VCD.Nsxt.NsxtAlbControllerUser == "" {
check.Skip(generalMessage + "No NSX-T ALB Controller Name specified in configuration")
}

if vcd.config.VCD.Nsxt.NsxtAlbControllerPassword == "" {
check.Skip(generalMessage + "No NSX-T ALB Controller Password specified in configuration")
}

if vcd.config.VCD.Nsxt.NsxtAlbImportableCloud == "" {
check.Skip(generalMessage + "No NSX-T ALB Controller Importable Cloud Name")
}
}

// skipOpenApiEndpointTest is a helper to skip tests for particular unsupported OpenAPI endpoints
func skipOpenApiEndpointTest(vcd *TestVCD, check *C, endpoint string) {
minimumRequiredApiVersion := endpointMinApiVersions[endpoint]
Expand Down
194 changes: 194 additions & 0 deletions govcd/nsxt_alb_clouds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright 2021 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
*/

package govcd

import (
"errors"
"fmt"
"net/url"

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

// NsxtAlbCloud allows users to use the virtual infrastructure provided by NSX Advanced Load Balancer, register your
// NSX-T Cloud instances with VMware Cloud Director. An NSX-T Cloud is a service provider-level construct that consists
// of an NSX-T Manager and an NSX-T Data Center transport zone. NSX-T Manager provides a system view and is the
// management component of NSX-T Data Center. An NSX-T Data Center transport zone dictates which hosts and virtual
// machines can participate in the use of a particular network. If there are multiple transport zones managed by the
// same NSX-T Manager, then a separate NSX-T Cloud encapsulates each pair of NSX-T Manager and NSX-T Data Center
// transport zone instances. An NSX-T Cloud has a one-to-one relationship with a network pool backed by an NSX-T Data
// Center transport zone.
type NsxtAlbCloud struct {
NsxtAlbCloud *types.NsxtAlbCloud
vcdClient *VCDClient
}

// GetAllAlbClouds returns all configured NSX-T ALB Clouds
func (vcdClient *VCDClient) GetAllAlbClouds(queryParameters url.Values) ([]*NsxtAlbCloud, error) {
client := vcdClient.Client
if !client.IsSysAdmin {
return nil, errors.New("handling NSX-T ALB Clouds require System user")
}

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

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

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

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

return wrappedResponses, nil
}

// GetAlbCloudByName returns NSX-T ALB Cloud by name
func (vcdClient *VCDClient) GetAlbCloudByName(name string) (*NsxtAlbCloud, error) {
queryParameters := copyOrNewUrlValues(nil)
queryParameters.Add("filter", "name=="+name)

albClouds, err := vcdClient.GetAllAlbClouds(queryParameters)
if err != nil {
return nil, fmt.Errorf("error reading NSX-T ALB Cloud with Name '%s': %s", name, err)
}

if len(albClouds) == 0 {
return nil, fmt.Errorf("%s could not find NSX-T ALB Cloud with Name '%s'", ErrorEntityNotFound, name)
}

if len(albClouds) > 1 {
return nil, fmt.Errorf("found more than 1 NSX-T ALB Cloud with Name '%s'", name)
}

return albClouds[0], nil
}

// GetAlbCloudById returns NSX-T ALB Cloud by ID
//
// Note. This function uses server side filtering instead of directly querying endpoint with specified ID because such
// endpoint does not exist
func (vcdClient *VCDClient) GetAlbCloudById(id string) (*NsxtAlbCloud, error) {

queryParameters := copyOrNewUrlValues(nil)
queryParameters.Add("filter", "id=="+id)

albCloud, err := vcdClient.GetAllAlbClouds(queryParameters)
if err != nil {
return nil, fmt.Errorf("error reading NSX-T ALB Cloud with ID '%s': %s", id, err)
}

if len(albCloud) == 0 {
return nil, fmt.Errorf("%s could not find NSX-T ALB Cloud by ID '%s'", ErrorEntityNotFound, id)
}

return albCloud[0], nil
}

// CreateAlbCloud creates NSX-T ALB Cloud
func (vcdClient *VCDClient) CreateAlbCloud(albCloudConfig *types.NsxtAlbCloud) (*NsxtAlbCloud, error) {
client := vcdClient.Client
if !client.IsSysAdmin {
return nil, errors.New("handling NSX-T ALB Clouds require System user")
}

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

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

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

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

return returnObject, nil
}

// Update is not supported up to at least VCD 10.3 therefore this function remains commented
//
// Update updates existing NSX-T ALB Cloud with new supplied albCloudConfig configuration
//func (nsxtAlbCloud *NsxtAlbCloud) Update(albCloudConfig *types.NsxtAlbCloud) (*NsxtAlbCloud, error) {
// client := nsxtAlbCloud.vcdClient.Client
// endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbCloud
// minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
// if err != nil {
// return nil, err
// }
//
// if albCloudConfig.ID == "" {
// return nil, fmt.Errorf("cannot update NSX-T ALB Cloud without ID")
// }
//
// urlRef, err := client.OpenApiBuildEndpoint(endpoint, albCloudConfig.ID)
// if err != nil {
// return nil, err
// }
//
// responseAlbCloud := &NsxtAlbCloud{
// NsxtAlbCloud: &types.NsxtAlbCloud{},
// vcdClient: nsxtAlbCloud.vcdClient,
// }
//
// err = client.OpenApiPutItem(minimumApiVersion, urlRef, nil, albCloudConfig, responseAlbCloud.NsxtAlbCloud, nil)
// if err != nil {
// return nil, fmt.Errorf("error updating NSX-T ALB Cloud: %s", err)
// }
//
// return responseAlbCloud, nil
//}

// Delete removes NSX-T ALB Cloud configuration
func (nsxtAlbCloud *NsxtAlbCloud) Delete() error {
client := nsxtAlbCloud.vcdClient.Client
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbCloud
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
if err != nil {
return err
}

if nsxtAlbCloud.NsxtAlbCloud.ID == "" {
return fmt.Errorf("cannot delete NSX-T ALB Cloud without ID")
}

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

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

return nil
}
122 changes: 122 additions & 0 deletions govcd/nsxt_alb_clouds_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//go:build alb || functional || ALL
// +build alb functional ALL

package govcd

import (
"fmt"
"net/url"

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

. "gopkg.in/check.v1"
)

func (vcd *TestVCD) Test_AlbClouds(check *C) {
if vcd.skipAdminTests {
check.Skip(fmt.Sprintf(TestRequiresSysAdminPrivileges, check.TestName()))
}
skipNoNsxtAlbConfiguration(vcd, check)

albController := spawnAlbController(vcd, check)
check.Assert(albController, NotNil)

importableCloud, err := albController.GetAlbImportableCloudByName(vcd.config.VCD.Nsxt.NsxtAlbImportableCloud)
check.Assert(err, IsNil)

albCloudConfig := &types.NsxtAlbCloud{
Name: check.TestName(),
Description: "alb-cloud-description",
LoadBalancerCloudBacking: types.NsxtAlbCloudBacking{
BackingId: importableCloud.NsxtAlbImportableCloud.ID,
BackingType: types.NsxtAlbCloudBackingTypeNsxtAlb,
LoadBalancerControllerRef: types.OpenApiReference{
ID: albController.NsxtAlbController.ID,
},
},
NetworkPoolRef: &types.OpenApiReference{
ID: importableCloud.NsxtAlbImportableCloud.NetworkPoolRef.ID,
},
}

createdAlbCloud, err := vcd.client.CreateAlbCloud(albCloudConfig)
check.Assert(err, IsNil)
openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbCloud + createdAlbCloud.NsxtAlbCloud.ID
AddToCleanupListOpenApi(createdAlbCloud.NsxtAlbCloud.Name, check.TestName(), openApiEndpoint)

// Get all clouds and ensure the needed one is found
allClouds, err := vcd.client.GetAllAlbClouds(nil)
check.Assert(err, IsNil)
var foundCreatedCloud bool
for cloudIndex := range allClouds {
if allClouds[cloudIndex].NsxtAlbCloud.ID == createdAlbCloud.NsxtAlbCloud.ID {
foundCreatedCloud = true
break
}
}
check.Assert(foundCreatedCloud, Equals, true)

// Filter lookup by name
filter := url.Values{}
filter.Add("filter", "name=="+createdAlbCloud.NsxtAlbCloud.Name)
allCloudsFiltered, err := vcd.client.GetAllAlbClouds(filter)
check.Assert(err, IsNil)
check.Assert(len(allCloudsFiltered), Equals, 1)
check.Assert(allCloudsFiltered[0].NsxtAlbCloud.ID, Equals, createdAlbCloud.NsxtAlbCloud.ID)

// Get by Name
albCloudByName, err := vcd.client.GetAlbCloudByName(createdAlbCloud.NsxtAlbCloud.Name)
check.Assert(err, IsNil)
check.Assert(albCloudByName.NsxtAlbCloud.Name, Equals, createdAlbCloud.NsxtAlbCloud.Name)

// Get by ID
albCloudById, err := vcd.client.GetAlbCloudById(createdAlbCloud.NsxtAlbCloud.ID)
check.Assert(err, IsNil)
check.Assert(albCloudById.NsxtAlbCloud.Name, Equals, createdAlbCloud.NsxtAlbCloud.Name)

// Cleanup
err = createdAlbCloud.Delete()
check.Assert(err, IsNil)

_, err = vcd.client.GetAlbCloudByName(createdAlbCloud.NsxtAlbCloud.Name)
check.Assert(ContainsNotFound(err), Equals, true)

err = albController.Delete()
check.Assert(err, IsNil)
}

// spawnAlbControllerAndCloud is a helper function to spawn NSX-T ALB Controller and Cloud
// It automatically adds these artefacts to clean up list
func spawnAlbControllerAndCloud(vcd *TestVCD, check *C) (*NsxtAlbController, *NsxtAlbCloud) {
skipNoNsxtAlbConfiguration(vcd, check)

albController := spawnAlbController(vcd, check)
check.Assert(albController, NotNil)

importableClouds, err := albController.GetAllAlbImportableClouds(nil)
check.Assert(err, IsNil)
check.Assert(len(importableClouds) > 0, Equals, true)

albCloudConfig := &types.NsxtAlbCloud{
Name: check.TestName(),
Description: "alb-cloud-description",
LoadBalancerCloudBacking: types.NsxtAlbCloudBacking{
BackingId: importableClouds[0].NsxtAlbImportableCloud.ID,
BackingType: types.NsxtAlbCloudBackingTypeNsxtAlb,
LoadBalancerControllerRef: types.OpenApiReference{
ID: albController.NsxtAlbController.ID,
},
},
NetworkPoolRef: &types.OpenApiReference{
ID: importableClouds[0].NsxtAlbImportableCloud.NetworkPoolRef.ID,
},
}

createdAlbCloud, err := vcd.client.CreateAlbCloud(albCloudConfig)
check.Assert(err, IsNil)

openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointAlbCloud + createdAlbCloud.NsxtAlbCloud.ID
AddToCleanupListOpenApi(createdAlbCloud.NsxtAlbCloud.Name, check.TestName(), openApiEndpoint)

return albController, createdAlbCloud
}
Loading