Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Dainius Serplis <dserplis@vmware.com>
  • Loading branch information
Didainius committed Mar 1, 2022
1 parent 0c10769 commit 8ad182b
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 161 deletions.
52 changes: 22 additions & 30 deletions govcd/nsxt_edgegateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ func (vdc *Vdc) GetNsxtEdgeGatewayByName(name string) (*NsxtEdgeGateway, error)
return returnSingleNsxtEdgeGateway(name, allEdges)
}

// GetNsxtEdgeGatewayByName allows to retrieve NSX-T edge gateway by Name for specific VDC Group
func (vdcGroup *VdcGroup) GetNsxtEdgeGatewayByName(name string) (*NsxtEdgeGateway, error) {
queryParameters := url.Values{}
queryParameters.Add("filter", "name=="+name)

allEdges, err := vdcGroup.GetAllNsxtEdgeGateways(queryParameters)
if err != nil {
return nil, fmt.Errorf("unable to retrieve Edge Gateway by name '%s': %s", name, err)
}

return returnSingleNsxtEdgeGateway(name, allEdges)
}

// GetAllNsxtEdgeGateways allows to retrieve all NSX-T edge gateways for Org Admins
func (adminOrg *AdminOrg) GetAllNsxtEdgeGateways(queryParameters url.Values) ([]*NsxtEdgeGateway, error) {
return getAllNsxtEdgeGateways(adminOrg.client, queryParameters)
Expand All @@ -117,6 +130,12 @@ func (vdc *Vdc) GetAllNsxtEdgeGateways(queryParameters url.Values) ([]*NsxtEdgeG
return getAllNsxtEdgeGateways(vdc.client, filteredQueryParams)
}

// GetAllNsxtEdgeGateways allows to retrieve all NSX-T edge gateways for specific VDC
func (vdcGroup *VdcGroup) GetAllNsxtEdgeGateways(queryParameters url.Values) ([]*NsxtEdgeGateway, error) {
filteredQueryParams := queryParameterFilterAnd("ownerRef.id=="+vdcGroup.VdcGroup.Id, queryParameters)
return getAllNsxtEdgeGateways(vdcGroup.client, filteredQueryParams)
}

// CreateNsxtEdgeGateway allows to create NSX-T edge gateway for Org admins
func (adminOrg *AdminOrg) CreateNsxtEdgeGateway(edgeGatewayConfig *types.OpenAPIEdgeGateway) (*NsxtEdgeGateway, error) {
if !adminOrg.client.IsSysAdmin {
Expand Down Expand Up @@ -215,43 +234,16 @@ func (egw *NsxtEdgeGateway) Delete() error {
// * Move from VDC to VDC Group
// * Move from VDC Group to VDC (which is part of that VDC Group)
//
// This function is just an Update operation with OwnerRef changed to vdcGroupId, but it is more
// convenient to use it.
// Note. NSX-T Edge Gateway cannot be moved directly from one VDC to another
func (egw *NsxtEdgeGateway) MoveToVdc(vdcGroupId string) (*NsxtEdgeGateway, error) {
if !egw.client.IsSysAdmin {
return nil, fmt.Errorf("only System Administrator can update Edge Gateway")
}

endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways
minimumApiVersion, err := egw.client.getOpenApiHighestElevatedVersion(endpoint)
if err != nil {
return nil, err
}

if egw.EdgeGateway.ID == "" {
return nil, fmt.Errorf("cannot update Edge Gateway without ID")
}

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

edgeGatewayConfig := egw.EdgeGateway
edgeGatewayConfig.OwnerRef = &types.OpenApiReference{ID: vdcGroupId}
// Explicitly unset VDC field because using it fails
edgeGatewayConfig.OrgVdc = nil

returnEgw := &NsxtEdgeGateway{
EdgeGateway: &types.OpenAPIEdgeGateway{},
client: egw.client,
}

err = egw.client.OpenApiPutItem(minimumApiVersion, urlRef, nil, edgeGatewayConfig, returnEgw.EdgeGateway, nil)
if err != nil {
return nil, fmt.Errorf("error updating Edge Gateway: %s", err)
}

return returnEgw, nil
return egw.Update(edgeGatewayConfig)
}

// getNsxtEdgeGatewayById is a private parent for wrapped functions:
Expand Down
75 changes: 75 additions & 0 deletions govcd/nsxt_edgegateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,78 @@ func (vcd *TestVCD) Test_NsxtEdgeCreate(check *C) {
err = updatedEdge.Delete()
check.Assert(err, IsNil)
}

func (vcd *TestVCD) Test_NsxtEdgeVdcGroup(check *C) {
skipNoNsxtConfiguration(vcd, check)
skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)

adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
check.Assert(err, IsNil)

nsxtExternalNetwork, err := GetExternalNetworkV2ByName(vcd.client, vcd.config.VCD.Nsxt.ExternalNetwork)
check.Assert(err, IsNil)

vdc, vdcGroup := test_CreateVdcGroup(check, adminOrg, vcd)

egwDefinition := &types.OpenAPIEdgeGateway{
Name: "nsx-t-edge",
Description: "nsx-t-edge-description",
OwnerRef: &types.OpenApiReference{
ID: vdc.Vdc.ID,
},
EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{
UplinkID: nsxtExternalNetwork.ExternalNetwork.ID,
Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
Gateway: "1.1.1.1",
PrefixLength: 24,
Enabled: true,
}}},
Connected: true,
Dedicated: false,
}},
}

// Create Edge Gateway in VDC
createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
check.Assert(err, IsNil)
check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)
openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)

check.Assert(createdEdge.EdgeGateway.Name, Equals, egwDefinition.Name)
check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Equals, egwDefinition.OwnerRef.ID)

// Move Edge Gateway to VDC Group
movedGateway, err := createdEdge.MoveToVdc(vdcGroup.VdcGroup.Id)
check.Assert(err, IsNil)
check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id)
check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdcGroup:.*`)

// Check lookup of Edge Gateways in VDC Groups
edgeInVdcGroup, err := vdcGroup.GetNsxtEdgeGatewayByName(createdEdge.EdgeGateway.Name)
check.Assert(err, IsNil)

// Masking known variables that have change for deep check
edgeInVdcGroup.EdgeGateway.OwnerRef.Name = ""
check.Assert(edgeInVdcGroup.EdgeGateway, DeepEquals, createdEdge.EdgeGateway)

// Move Edge Gateway back to VDC from VDC Group
egwDefinition.OwnerRef.ID = vdc.Vdc.ID
egwDefinition.ID = movedGateway.EdgeGateway.ID

movedBackToVdcEdge, err := movedGateway.Update(egwDefinition)
check.Assert(err, IsNil)
check.Assert(movedBackToVdcEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)

// Ignore known to differ fields, but check that whole Edge Gateway structure remains the same
// as it is important to perform update operations without impacting configuration itself

// Fields to ignore on both sides
createdEdge.EdgeGateway.OrgVdc = movedBackToVdcEdge.EdgeGateway.OrgVdc
createdEdge.EdgeGateway.OwnerRef = movedBackToVdcEdge.EdgeGateway.OwnerRef
check.Assert(movedBackToVdcEdge.EdgeGateway, DeepEquals, createdEdge.EdgeGateway)

// Remove Edge Gateway
err = movedBackToVdcEdge.Delete()
check.Assert(err, IsNil)
}
12 changes: 12 additions & 0 deletions govcd/vdc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,18 @@ func (vdc *Vdc) IsNsxt() bool {
return networkProviderCapability == types.VdcCapabilityNetworkProviderNsxt
}

// IsNsxv is a convenience function to check if VDC is backed by NSX-V pVdc
// If error occurs - it returns false
func (vdc *Vdc) IsNsxv() bool {
vdcCapabilities, err := vdc.GetCapabilities()
if err != nil {
return false
}

networkProviderCapability := getCapabilityValue(vdcCapabilities, "networkProvider")
return networkProviderCapability == types.VdcCapabilityNetworkProviderNsxv
}

// getCapabilityValue helps to lookup a specific capability in []types.VdcCapability by provided fieldName
func getCapabilityValue(capabilities []types.VdcCapability, fieldName string) string {
for _, field := range capabilities {
Expand Down
4 changes: 2 additions & 2 deletions govcd/vdc_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ func OwnerIsVdcGroup(urn string) bool {
return false
}

if strings.ToLower(ownerType) == strings.ToLower("vdcGroup") {
if strings.EqualFold(ownerType, types.UrnTypeVdcGroup) {
return true
}

Expand All @@ -570,7 +570,7 @@ func OwnerIsVdc(urn string) bool {
return false
}

if strings.ToLower(ownerType) == strings.ToLower("vdc") {
if strings.EqualFold(ownerType, types.UrnTypeVdc) {
return true
}

Expand Down
143 changes: 143 additions & 0 deletions govcd/vdc_group_common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
//go:build network || functional || openapi || vdcGroup || nsxt || gateway || ALL
// +build network functional openapi vdcGroup nsxt gateway ALL

/*
* Copyright 2022 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"
. "gopkg.in/check.v1"
)

func test_CreateVdcGroup(check *C, adminOrg *AdminOrg, vcd *TestVCD) (*Vdc, *VdcGroup) {
createdVdc := createNewVdc(vcd, check, check.TestName())

createdVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(),
map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(createdVdc.vdcName()))}})
check.Assert(err, IsNil)
check.Assert(createdVdcAsCandidate, NotNil)
check.Assert(len(createdVdcAsCandidate) == 1, Equals, true)

existingVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(),
map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(vcd.nsxtVdc.vdcName()))}})
check.Assert(err, IsNil)
check.Assert(existingVdcAsCandidate, NotNil)
check.Assert(len(existingVdcAsCandidate) == 1, Equals, true)

vdcGroupConfig := &types.VdcGroup{
Name: check.TestName() + "Group",
OrgId: adminOrg.orgId(),
ParticipatingOrgVdcs: []types.ParticipatingOrgVdcs{
types.ParticipatingOrgVdcs{
VdcRef: types.OpenApiReference{
ID: createdVdc.vdcId(),
},
SiteRef: (createdVdcAsCandidate)[0].SiteRef,
OrgRef: (createdVdcAsCandidate)[0].OrgRef,
},
types.ParticipatingOrgVdcs{
VdcRef: types.OpenApiReference{
ID: vcd.nsxtVdc.vdcId(),
},
SiteRef: (existingVdcAsCandidate)[0].SiteRef,
OrgRef: (existingVdcAsCandidate)[0].OrgRef,
},
},
LocalEgress: false,
UniversalNetworkingEnabled: false,
NetworkProviderType: "NSX_T",
Type: "LOCAL",
//DfwEnabled: true, // ignored by API
}

vdcGroup, err := adminOrg.CreateVdcGroup(vdcGroupConfig)
check.Assert(err, IsNil)
check.Assert(vdcGroup, NotNil)
check.Assert(vdcGroup.IsNsxt(), Equals, true)

openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroups + vdcGroup.VdcGroup.Id
PrependToCleanupListOpenApi(vdcGroup.VdcGroup.Name, check.TestName(), openApiEndpoint)

return createdVdc, vdcGroup
}

func createNewVdc(vcd *TestVCD, check *C, vdcName string) *Vdc {
adminOrg, err := vcd.client.GetAdminOrgByName(vcd.org.Org.Name)
check.Assert(err, IsNil)
check.Assert(adminOrg, NotNil)

pVdcs, err := QueryProviderVdcByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.Name)
check.Assert(err, IsNil)

if len(pVdcs) == 0 {
check.Skip(fmt.Sprintf("No NSX-T Provider VDC found with name '%s'", vcd.config.VCD.NsxtProviderVdc.Name))
}
providerVdcHref := pVdcs[0].HREF

pvdcStorageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.NsxtProviderVdc.StorageProfile, providerVdcHref)

check.Assert(err, IsNil)
providerVdcStorageProfileHref := pvdcStorageProfile.HREF

networkPools, err := QueryNetworkPoolByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.NetworkPool)
check.Assert(err, IsNil)
if len(networkPools) == 0 {
check.Skip(fmt.Sprintf("No network pool found with name '%s'", vcd.config.VCD.NsxtProviderVdc.NetworkPool))
}

networkPoolHref := networkPools[0].HREF
trueValue := true
vdcConfiguration := &types.VdcConfiguration{
Name: vdcName,
Xmlns: types.XMLNamespaceVCloud,
AllocationModel: "Flex",
ComputeCapacity: []*types.ComputeCapacity{
&types.ComputeCapacity{
CPU: &types.CapacityWithUsage{
Units: "MHz",
Allocated: 1024,
Limit: 1024,
},
Memory: &types.CapacityWithUsage{
Allocated: 1024,
Limit: 1024,
Units: "MB",
},
},
},
VdcStorageProfile: []*types.VdcStorageProfileConfiguration{&types.VdcStorageProfileConfiguration{
Enabled: takeBoolPointer(true),
Units: "MB",
Limit: 1024,
Default: true,
ProviderVdcStorageProfile: &types.Reference{
HREF: providerVdcStorageProfileHref,
},
},
},
NetworkPoolReference: &types.Reference{
HREF: networkPoolHref,
},
ProviderVdcReference: &types.Reference{
HREF: providerVdcHref,
},
IsEnabled: true,
IsThinProvision: true,
UsesFastProvisioning: true,
IsElastic: &trueValue,
IncludeMemoryOverhead: &trueValue,
}

vdc, err := adminOrg.CreateOrgVdc(vdcConfiguration)
check.Assert(vdc, NotNil)
check.Assert(err, IsNil)

AddToCleanupList(vdcConfiguration.Name, "vdc", vcd.org.Org.Name, check.TestName())
return vdc
}
Loading

0 comments on commit 8ad182b

Please sign in to comment.