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

Implement DHCP Forwarding Resource and Data source #1056

Merged
merged 34 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f813d51
initial commit
May 3, 2023
f47a7b6
make old dhcp relay network test work
May 3, 2023
003e797
make fully functioning test for dhcp
May 5, 2023
0a4d82e
add datasource, documentation
May 8, 2023
92d4eb7
fix gosec complaint
May 8, 2023
c98d2b1
fix check-docs complaints
May 8, 2023
f056320
fix check-docs
May 8, 2023
73bde12
fix nil pointer dereference
May 8, 2023
514b8aa
fix nil pointer dereference
May 8, 2023
0dab791
fix typos
May 8, 2023
eb178b0
implement datasource test
May 8, 2023
066f515
merge upstream main
May 8, 2023
ba1dd13
add changelog entry
May 8, 2023
c51f862
typo
May 8, 2023
29606eb
fix .tf constant formatting
May 9, 2023
526449e
use owner_id and update docs
May 9, 2023
616b421
remove redundant configuration lines
May 9, 2023
27b4b98
refactor parent egw lock and update docs
May 9, 2023
ab1bc7e
update documentation
May 9, 2023
6be4e99
update docs
May 10, 2023
c5b668e
update datasource_not_found test
May 10, 2023
18cbc66
address comments
May 11, 2023
0ee3b65
remove unused param
May 11, 2023
381c803
address some of the comments
May 12, 2023
2685feb
split createupdate function
May 12, 2023
c813731
change enabled field corner case docs
May 15, 2023
55b6a27
address comments and requests
May 15, 2023
c45a2db
small fix
May 15, 2023
6a4dcf9
terraform fmt
May 15, 2023
8c4f045
fix hclcheck fails
May 15, 2023
8cc19c2
fix comment
May 16, 2023
3242c16
update note about disabled forwarder changes
May 16, 2023
16180d1
doc fix
May 16, 2023
a7b039f
go mod tidy to latest version of govcd
Jun 1, 2023
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/v3.10.0/1056-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* **New Resource:** `vcd_nsxt_edgegateway_dhcp_forwarding` to manage NSX-T Edge Gateway DHCP Forwarding configuration [GH-1056]
* **New Data Source:** `vcd_nsxt_edgegateway_dhcp_forwarding` to read NSX-T Edge Gateway DHCP Forwarding configuration [GH-1056]
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ require (
google.golang.org/grpc v1.51.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
)

replace github.com/vmware/go-vcloud-director/v2 => github.com/adezxc/go-vcloud-director/v2 v2.20.0-alpha.15.0.20230503092536-680538e15fdc
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C6
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/adezxc/go-vcloud-director/v2 v2.20.0-alpha.15.0.20230503092536-680538e15fdc h1:nkYTb+2LD+Fu4NN2044N/eLHCQYNxFjih7eHqSY14gk=
github.com/adezxc/go-vcloud-director/v2 v2.20.0-alpha.15.0.20230503092536-680538e15fdc/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
Expand Down Expand Up @@ -194,8 +196,6 @@ github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvC
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmware/go-vcloud-director/v2 v2.20.0 h1:vT1vmh6uxJPE5a4d2nSj8KmF3C0kb/1UF2hn6hp7vr0=
github.com/vmware/go-vcloud-director/v2 v2.20.0/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
28 changes: 28 additions & 0 deletions vcd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,34 @@ func (cli *VCDClient) unLockParentEdgeGtw(d *schema.ResourceData) {
vcdMutexKV.kvUnlock(edgeGtwIdValue)
}

// lockParentVdcGroupOrEdgeGateway handles lock of parent Edge Gateway or parent VDC group, depending
// if the parent Edge Gateway is in a VDC or a VDC group. Returns a function that contains the needed
// unlock function, so that it can be deferred and called after the work with the resource has been
// done.
func (cli *VCDClient) lockParentVdcGroupOrEdgeGateway(d *schema.ResourceData) (func(), error) {
Didainius marked this conversation as resolved.
Show resolved Hide resolved
parentEdgeGatewayOwnerId, _, err := getParentEdgeGatewayOwnerId(cli, d)
Didainius marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("error finding parent Edge Gateway: %s", err)
}

// Handling locks is conditional. There are two scenarios:
// * When the parent Edge Gateway is in a VDC - a lock on parent Edge Gateway must be acquired
// * When the parent Edge Gateway is in a VDC Group - a lock on parent VDC Group must be acquired
// To find out parent lock object, Edge Gateway must be looked up and its OwnerRef must be checked
// Note. It is not safe to do multiple locks in the same resource as it can result in a deadlock
if govcd.OwnerIsVdcGroup(parentEdgeGatewayOwnerId) {
cli.lockById(parentEdgeGatewayOwnerId)
return func() {
cli.unlockById(parentEdgeGatewayOwnerId)
}, nil
} else {
cli.lockParentEdgeGtw(d)
return func() {
cli.unLockParentEdgeGtw(d)
}, nil
}
}

func (cli *VCDClient) lockParentOrgNetwork(d *schema.ResourceData) {
orgNetworkId := d.Get("org_network_id").(string)
vcdMutexKV.kvLock(orgNetworkId)
Expand Down
3 changes: 1 addition & 2 deletions vcd/datasource_not_found_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ func addMandatoryParams(dataSourceName string, mandatoryFields []string, t *test
}

if (dataSourceName == "vcd_nsxt_edgegateway_bgp_configuration" || dataSourceName == "vcd_nsxt_alb_settings" ||
dataSourceName == "vcd_nsxt_firewall" || dataSourceName == "vcd_nsxt_route_advertisement" ||
dataSourceName == "vcd_nsxt_edgegateway_rate_limiting") &&
dataSourceName == "vcd_nsxt_edgegateway_rate_limiting" || dataSourceName == "vcd_nsxt_edgegateway_dhcp_forwarding") &&
mandatoryFields[fieldIndex] == "edge_gateway_id" {
// injecting fake Edge Gateway ID
templateFields = templateFields + `edge_gateway_id = "urn:vcloud:gateway:784feb3d-87e4-4905-202a-bfe9faa5476f"` + "\n"
Expand Down
44 changes: 44 additions & 0 deletions vcd/datasource_vcd_nsxt_edgegateway_dhcp_forwarding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package vcd

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func datasourceVcdNsxtEdgegatewayDhcpForwarding() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcdNsxtEdgegatewayDhcpForwardingRead,
Schema: map[string]*schema.Schema{
"org": {
Type: schema.TypeString,
Required: true,
Description: "The name of organization to use, optional if defined at provider " +
"level. Useful when connected as sysadmin working across different organizations",
},
"edge_gateway_id": {
Type: schema.TypeString,
Required: true,
Description: "Edge gateway ID for DHCP forwarding configuration",
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Status of DHCP Forwarding for the Edge Gateway",
},
"dhcp_servers": {
Type: schema.TypeSet,
Computed: true,
Description: "IP addresses of the DHCP servers",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func datasourceVcdNsxtEdgegatewayDhcpForwardingRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return genericVcdNsxtEdgegatewayDhcpForwardingRead(ctx, d, meta, "datasource")
}
96 changes: 96 additions & 0 deletions vcd/datasource_vcd_nsxt_edgegateway_dhcp_forwarding_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//go:build gateway || network || nsxt || ALL || functional

package vcd

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

// TestAccVcdDataSourceNsxtEdgeRateLimiting is a test for datasource
// vcd_nsxt_edgegateway_rate_limiting It only check if ingress and egress profile IDs are empty
// ("unlimited" rate). Other values are tested in resource test.
Didainius marked this conversation as resolved.
Show resolved Hide resolved
func TestAccVcdDataSourceNsxtEdgeDhcpForwarding(t *testing.T) {
preTestChecks(t)
skipIfNotSysAdmin(t)

vcdClient := createTemporaryVCDConnection(true)
if vcdClient == nil {
t.Skip(acceptanceTestsSkipped)
}
if vcdClient.Client.APIVCDMaxVersionIs("< 36.1") {
t.Skipf("This test tests VCD 10.3.1+ (API V36.1+) features. Skipping.")
}

// String map to fill the template
var params = StringMap{
"Org": testConfig.VCD.Org,
"NsxtVdc": testConfig.Nsxt.Vdc,
"NsxtVdcGroup": testConfig.Nsxt.VdcGroup,
"NsxtEdgeGwInVdcGroup": testConfig.Nsxt.VdcGroupEdgeGateway,
"NsxtEdgeGw": testConfig.Nsxt.EdgeGateway,
"TestName": t.Name(),
}
testParamsNotEmpty(t, params)

configText1 := templateFill(testAccVcdDataSourceNsxtEdgeDhcpForwarding, params)
debugPrintf("#[DEBUG] CONFIGURATION for step 1: %s", configText1)
dataclouder marked this conversation as resolved.
Show resolved Hide resolved

if vcdShortTest {
t.Skip(acceptanceTestsSkipped)
return
}

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviders,
Steps: []resource.TestStep{
{
Config: configText1,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.vcd_nsxt_edgegateway_dhcp_forwarding.testing-in-vdc", "id"),
resource.TestCheckResourceAttr("data.vcd_nsxt_edgegateway_dhcp_forwarding.testing-in-vdc", "enabled", "false"),

resource.TestCheckResourceAttrSet("data.vcd_nsxt_edgegateway_dhcp_forwarding.testing-in-vdc-group", "id"),
resource.TestCheckResourceAttr("data.vcd_nsxt_edgegateway_dhcp_forwarding.testing-in-vdc-group", "enabled", "false"),
),
},
},
})
}

const testAccVcdDataSourceNsxtEdgeDhcpForwarding = `
data "vcd_vdc_group" "g1" {
org = "{{.Org}}"
name = "{{.NsxtVdcGroup}}"
}

data "vcd_nsxt_edgegateway" "testing-in-vdc-group" {
org = "{{.Org}}"
owner_id = data.vcd_vdc_group.g1.id

name = "{{.NsxtEdgeGwInVdcGroup}}"
}

data "vcd_org_vdc" "v1" {
org = "{{.Org}}"
name = "{{.NsxtVdc}}"
}

data "vcd_nsxt_edgegateway" "testing-in-vdc" {
org = "{{.Org}}"
owner_id = data.vcd_org_vdc.v1.id

name = "{{.NsxtEdgeGw}}"
}

data "vcd_nsxt_edgegateway_dhcp_forwarding" "testing-in-vdc" {
org = "{{.Org}}"
edge_gateway_id = data.vcd_nsxt_edgegateway.testing-in-vdc.id
}

data "vcd_nsxt_edgegateway_dhcp_forwarding" "testing-in-vdc-group" {
org = "{{.Org}}"
edge_gateway_id = data.vcd_nsxt_edgegateway.testing-in-vdc-group.id
}
`
3 changes: 2 additions & 1 deletion vcd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ var globalDataSourceMap = map[string]*schema.Resource{
"vcd_nsxt_edgegateway_qos_profile": datasourceVcdNsxtEdgeGatewayQosProfile(), // 3.9
"vcd_nsxt_edgegateway_rate_limiting": datasourceVcdNsxtEdgegatewayRateLimiting(), // 3.9
"vcd_nsxt_network_dhcp_binding": datasourceVcdNsxtDhcpBinding(), // 3.9
"vcd_nsxt_edgegateway_dhcp_forwarding": datasourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
}

var globalResourceMap = map[string]*schema.Resource{
Expand Down Expand Up @@ -204,6 +205,7 @@ var globalResourceMap = map[string]*schema.Resource{
"vcd_rde": resourceVcdRde(), // 3.9
"vcd_nsxt_edgegateway_rate_limiting": resourceVcdNsxtEdgegatewayRateLimiting(), // 3.9
"vcd_nsxt_network_dhcp_binding": resourceVcdNsxtDhcpBinding(), // 3.9
"vcd_nsxt_edgegateway_dhcp_forwarding": resourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
}

// Provider returns a terraform.ResourceProvider.
Expand All @@ -216,7 +218,6 @@ func Provider() *schema.Provider {
DefaultFunc: schema.EnvDefaultFunc("VCD_USER", nil),
Description: "The user name for VCD API operations.",
},

"password": {
Type: schema.TypeString,
Optional: true,
Expand Down
2 changes: 1 addition & 1 deletion vcd/resource_vcd_network_routed_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ func getOpenApiOrgVdcRoutedNetworkType(d *schema.ResourceData, vcdClient *VCDCli
func getParentEdgeGatewayOwnerId(vcdClient *VCDClient, d *schema.ResourceData) (string, *govcd.Org, error) {
org, err := vcdClient.GetOrgFromResource(d)
if err != nil {
return "", nil, fmt.Errorf("[routed network create v2] error retrieving Org: %s", err)
return "", nil, fmt.Errorf("error retrieving Org: %s", err)
}

anyEdgeGateway, err := org.GetAnyTypeEdgeGatewayById(d.Get("edge_gateway_id").(string))
Expand Down
Loading