Skip to content

Commit

Permalink
Add backing_components_use_constraint field
Browse files Browse the repository at this point in the history
Add ability of using multiple port groups

Signed-off-by: Giuseppe Maxia <[email protected]>
  • Loading branch information
Giuseppe Maxia committed Oct 23, 2023
1 parent 005d0cd commit 673d85a
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 34 deletions.
38 changes: 27 additions & 11 deletions vcd/resource_vcd_network_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ func resourceVcdNetworkPool() *schema.Resource {
Computed: true,
Description: "Type of network provider",
},
"backing_components_use_constraint": {
Type: schema.TypeString,
Optional: true,
Default: types.BackingUseExplicit,
ValidateFunc: validation.StringInSlice([]string{
string(types.BackingUseExplicit),
string(types.BackingUseWhenOnlyOne),
string(types.BackingUseFirstAvailable)}, false),
Description: "Defines how backing components are accepted",
},
"backing": {
Type: schema.TypeList,
MaxItems: 1,
Expand All @@ -152,10 +162,9 @@ func resourceVcdNetworkPool() *schema.Resource {
Elem: resourceNetworkPoolBacking("resource"),
},
"port_groups": {
Type: schema.TypeList,
Type: schema.TypeSet,
Optional: true,
Computed: true,
MaxItems: 1,
Description: "Backing port groups",
Elem: resourceNetworkPoolBacking("resource"),
},
Expand Down Expand Up @@ -184,6 +193,7 @@ func resourceNetworkPoolCreate(ctx context.Context, d *schema.ResourceData, meta
vcdClient := meta.(*VCDClient)
networkPoolName := d.Get("name").(string)
networkPoolDescription := d.Get("description").(string)
backingComponentsUseConstraint := d.Get("backing_components_use_constraint").(string)

networkPoolType := d.Get("type").(string)
networkPoolProviderId := d.Get("network_provider_id").(string)
Expand Down Expand Up @@ -244,7 +254,7 @@ func resourceNetworkPoolCreate(ctx context.Context, d *schema.ResourceData, meta
networkPoolDescription,
networkPoolProvider.Name,
transportZoneName,
types.BackingUseFirstAvailable) // TODO: update to user choice
types.BackingUseConstraint(backingComponentsUseConstraint))
case types.NetworkPoolVlanType:
var dsName string
var ranges []types.VlanIdRange
Expand All @@ -261,21 +271,27 @@ func resourceNetworkPoolCreate(ctx context.Context, d *schema.ResourceData, meta
networkPoolProvider.Name,
dsName,
ranges,
types.BackingUseFirstAvailable) // TODO: update to user choice
types.BackingUseConstraint(backingComponentsUseConstraint))
case types.NetworkPoolPortGroupType:
var pgName string
var pgNames []string
if backing != nil {
for _, pg := range backing.PortGroupRefs {
pgName = pg.Name
break
pgNames = append(pgNames, pg.Name)
}
}
if len(pgNames) == 0 {
if backingComponentsUseConstraint != string(types.BackingUseExplicit) {
pgNames = append(pgNames, "")
} else {
return diag.Errorf("no port group names detected in 'backing' structure")
}
}
networkPool, err = vcdClient.CreateNetworkPoolPortGroup(
networkPoolName,
networkPoolDescription,
networkPoolProvider.Name,
pgName,
types.BackingUseFirstAvailable) // TODO: update to user choice
pgNames,
types.BackingUseConstraint(backingComponentsUseConstraint))
}

if err != nil {
Expand Down Expand Up @@ -444,8 +460,8 @@ func getNetworkPoolBacking(d *schema.ResourceData) (*types.NetworkPoolBacking, e
backing.TransportZoneRef.Name = tzMap["name"].(string)
}
case "port_groups":
pgRawList := value.([]any)
for _, m := range pgRawList {
pgRawList := value.(*schema.Set)
for _, m := range pgRawList.List() {
pgMap := m.(map[string]any)
backing.PortGroupRefs = append(backing.PortGroupRefs, types.OpenApiReference{Name: pgMap["name"].(string)})
}
Expand Down
146 changes: 123 additions & 23 deletions vcd/resource_vcd_network_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package vcd

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/vmware/go-vcloud-director/v2/types/v56"
"net/url"
"testing"
Expand All @@ -15,7 +17,8 @@ type networkPoolData struct {
poolType string
networkProviderId string
backingType string
backingName string
backingNames []string
backingConstraint types.BackingUseConstraint
}

func TestAccVcdResourceNetworkPool(t *testing.T) {
Expand Down Expand Up @@ -57,27 +60,41 @@ func TestAccVcdResourceNetworkPool(t *testing.T) {
t.Skipf("error getting port groups: %s", err)
}

var usableTransportZones []string
for _, tz := range transportZones {
if tz.AlreadyImported {
continue
}
usableTransportZones = append(usableTransportZones, tz.Name)
runNetworkPoolTest(t, networkPoolData{
name: t.Name() + "-geneve-name",
description: t.Name() + "-geneve-name description",
poolType: types.NetworkPoolGeneveType,
networkProviderId: nsxtManagerId,
backingType: "transport_zone",
backingName: tz.Name,
backingNames: []string{tz.Name},
})
}
if len(transportZones) > 0 {
if len(usableTransportZones) > 0 {
runNetworkPoolTest(t, networkPoolData{
name: t.Name() + "-geneve-none",
description: t.Name() + "-geneve-none description",
name: t.Name() + "-geneve-none-first",
description: t.Name() + "-geneve-none-first description",
poolType: types.NetworkPoolGeneveType,
networkProviderId: nsxtManagerId,
backingType: "none",
backingName: "none",
backingNames: []string{"none"},
backingConstraint: types.BackingUseFirstAvailable,
})
}
if len(usableTransportZones) == 1 {
runNetworkPoolTest(t, networkPoolData{
name: t.Name() + "-geneve-none-one",
description: t.Name() + "-geneve-none-one description",
poolType: types.NetworkPoolGeneveType,
networkProviderId: nsxtManagerId,
backingType: "none",
backingNames: []string{"none"},
backingConstraint: types.BackingUseWhenOnlyOne,
})
}
for _, ds := range distributedSwitches {
Expand All @@ -87,7 +104,7 @@ func TestAccVcdResourceNetworkPool(t *testing.T) {
poolType: types.NetworkPoolVlanType,
networkProviderId: vCenter.VSphereVCenter.VcId,
backingType: "distributed_switches",
backingName: ds.BackingRef.Name,
backingNames: []string{ds.BackingRef.Name},
})
}
if len(distributedSwitches) > 0 {
Expand All @@ -97,17 +114,48 @@ func TestAccVcdResourceNetworkPool(t *testing.T) {
poolType: types.NetworkPoolVlanType,
networkProviderId: vCenter.VSphereVCenter.VcId,
backingType: "none",
backingName: "none",
backingNames: []string{"none"},
backingConstraint: types.BackingUseFirstAvailable,
})
}
var compatiblePgs []string
for _, pg := range portGroups {

compatible := false
for _, pg1 := range portGroups {
if pg.VcenterImportableDvpg.BackingRef.ID == pg1.VcenterImportableDvpg.BackingRef.ID {
continue
}
if pg.UsableWith(pg1) {
if !contains(compatiblePgs, pg.VcenterImportableDvpg.BackingRef.Name) {
compatiblePgs = append(compatiblePgs, pg.VcenterImportableDvpg.BackingRef.Name)
}
if !contains(compatiblePgs, pg1.VcenterImportableDvpg.BackingRef.Name) {
compatiblePgs = append(compatiblePgs, pg1.VcenterImportableDvpg.BackingRef.Name)
}
compatible = true
}
}
if compatible {
continue
}
runNetworkPoolTest(t, networkPoolData{
name: t.Name() + "-pg-name",
description: t.Name() + "-pg-name description",
poolType: types.NetworkPoolPortGroupType,
networkProviderId: vCenter.VSphereVCenter.VcId,
backingType: "port_groups",
backingName: pg.VcenterImportableDvpg.BackingRef.Name,
backingNames: []string{pg.VcenterImportableDvpg.BackingRef.Name},
})
}
if len(compatiblePgs) > 0 {
runNetworkPoolTest(t, networkPoolData{
name: t.Name() + "-pg-multi",
description: t.Name() + "-pg-multi description",
poolType: types.NetworkPoolPortGroupType,
networkProviderId: vCenter.VSphereVCenter.VcId,
backingType: "port_groups",
backingNames: compatiblePgs,
})
}
if len(portGroups) > 0 {
Expand All @@ -117,7 +165,8 @@ func TestAccVcdResourceNetworkPool(t *testing.T) {
poolType: types.NetworkPoolPortGroupType,
networkProviderId: vCenter.VSphereVCenter.VcId,
backingType: "none",
backingName: "none",
backingNames: []string{"none"},
backingConstraint: types.BackingUseFirstAvailable,
})
}

Expand All @@ -130,6 +179,20 @@ func runNetworkPoolTest(t *testing.T, npData networkPoolData) {
if npData.backingType == "none" {
tmpl = testAccNetworkPoolNoBacking
}
backingElements := " "
if len(npData.backingNames) > 1 {
tmpl = testAccNetworkPoolMulti
for _, name := range npData.backingNames {
backingElements = fmt.Sprintf("%s\n%s", backingElements, fmt.Sprintf(portGroupBacking, name))
}
}
testName := npData.poolType + "-" + npData.backingNames[0]
if len(npData.backingNames) > 1 {
testName = npData.poolType + "-multi"
}
if npData.backingNames[0] == "none" {
testName = npData.poolType + "-" + npData.name
}

var data = StringMap{
"SkipMessage": " ",
Expand All @@ -138,9 +201,11 @@ func runNetworkPoolTest(t *testing.T, npData networkPoolData) {
"NetworkProviderId": npData.networkProviderId,
"PoolType": npData.poolType,
"BackingType": npData.backingType,
"BackingName": npData.backingName,
"BackingName": npData.backingNames[0],
"BackingConstraint": npData.backingConstraint,
"BackingElements": backingElements,
"RangeIds": " ",
"FuncName": t.Name() + "-" + npData.poolType + "-" + npData.backingName,
"FuncName": t.Name() + "-" + testName,
}

if npData.poolType == types.NetworkPoolVlanType {
Expand All @@ -160,13 +225,11 @@ func runNetworkPoolTest(t *testing.T, npData networkPoolData) {
updatedText := templateFill(tmpl, data)
debugPrintf("#[DEBUG] Update: %s", updatedText)

if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
return
}

t.Run(npData.poolType+"-"+npData.backingName, func(t *testing.T) {

t.Run(testName, func(t *testing.T) {
if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
return
}
resourceDef := "vcd_network_pool.npool"
resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviders,
Expand All @@ -182,6 +245,9 @@ func runNetworkPoolTest(t *testing.T, npData networkPoolData) {
resource.TestCheckResourceAttr(resourceDef, "name", npData.name),
resource.TestCheckResourceAttr(resourceDef, "description", npData.description),
resource.TestCheckResourceAttr(resourceDef, "status", "REALIZED"),
checkWithCondition(npData.backingType != "none",
resource.TestCheckResourceAttr(resourceDef, "backing.0."+npData.backingType+".#",
fmt.Sprintf("%d", len(npData.backingNames)))),
),
},
// step 1 - update network pool
Expand All @@ -196,16 +262,27 @@ func runNetworkPoolTest(t *testing.T, npData networkPoolData) {
},
// step 2 - import
{
ResourceName: resourceDef,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: importStateIdTopHierarchy(updatedName),
ResourceName: resourceDef,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: importStateIdTopHierarchy(updatedName),
ImportStateVerifyIgnore: []string{"backing_components_use_constraint"},
},
},
})
})
}

// checkWithCondition runs a check only if the leading condition is true
func checkWithCondition(condition bool, f resource.TestCheckFunc) resource.TestCheckFunc {
if !condition {
return func(s *terraform.State) error {
return nil
}
}
return f
}

const testAccNetworkPoolWithBacking = `
{{.SkipMessage}}
resource "vcd_network_pool" "npool" {
Expand All @@ -223,13 +300,36 @@ resource "vcd_network_pool" "npool" {
}
`

const portGroupBacking = `
port_groups {
name = "%s"
}
`

const testAccNetworkPoolMulti = `
{{.SkipMessage}}
resource "vcd_network_pool" "npool" {
name = "{{.NetworkPoolName}}"
description = "{{.NetworkPoolDescription}}"
network_provider_id = "{{.NetworkProviderId}}"
type = "{{.PoolType}}"
backing {
{{.BackingElements}}
}
}
`

const testAccNetworkPoolNoBacking = `
{{.SkipMessage}}
resource "vcd_network_pool" "npool" {
name = "{{.NetworkPoolName}}"
description = "{{.NetworkPoolDescription}}"
network_provider_id = "{{.NetworkProviderId}}"
type = "{{.PoolType}}"
backing_components_use_constraint = "{{.BackingConstraint}}"
backing {
{{.RangeIds}}
}
Expand Down
3 changes: 3 additions & 0 deletions vcd/resource_vcd_provider_vdc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ resource "vcd_network_pool" "np1" {
name = "{{.NewNsxtNetworkPool}}"
network_provider_id = data.vcd_nsxt_manager.mgr1.id
type = "GENEVE" # provider VDC needs either a GENEVE (NSX-T) or a VXLAN (NSX-V) network pool
backing_components_use_constraint = "use-first-available"
backing {
}
}
Expand Down

0 comments on commit 673d85a

Please sign in to comment.