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 vcd_ip_space resource and data source #1061

Merged
merged 19 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 17 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/v3.10.0/1061-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* **New Resource:** `vcd_ip_space` to manage IP Spaces in VCD 10.4.1+ [GH-1061]
* **New Data Source:** `vcd_ip_space` to read IP Spaces in VCD 10.4.1+ [GH-1061]
2 changes: 1 addition & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ vet:

# formats all .go files
fmt:
gofmt -w $(GOFMT_FILES)
gofmt -s -w $(GOFMT_FILES)

# runs a Go format check
fmtcheck:
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@ 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/Didainius/go-vcloud-director/v2 v2.17.0-alpha.2.0.20230620062417-dd5677ec97d6

//replace github.com/vmware/go-vcloud-director/v2 => ../go-vcloud-director
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Didainius/go-vcloud-director/v2 v2.17.0-alpha.2.0.20230620062417-dd5677ec97d6 h1:lguEYjqL1kiN+js3lubgZjxL1FvQsbii/8ThdNnOq7g=
github.com/Didainius/go-vcloud-director/v2 v2.17.0-alpha.2.0.20230620062417-dd5677ec97d6/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
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.21.0-alpha.2 h1:EXhOldqcLDR72Q4hXsknxZPKpsBw5mslK8GdcmxOy3c=
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.2/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
3 changes: 2 additions & 1 deletion vcd/datasource_not_found_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ func addMandatoryParams(dataSourceName string, mandatoryFields []string, t *test
}

if (dataSourceName == "vcd_nsxt_edgegateway_bgp_configuration" || dataSourceName == "vcd_nsxt_alb_settings" ||
dataSourceName == "vcd_nsxt_edgegateway_rate_limiting" || dataSourceName == "vcd_nsxt_edgegateway_dhcp_forwarding") &&
dataSourceName == "vcd_nsxt_edgegateway_rate_limiting" || dataSourceName == "vcd_nsxt_edgegateway_dhcp_forwarding" ||
dataSourceName == "vcd_nsxt_firewall" || dataSourceName == "vcd_nsxt_route_advertisement") &&
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
151 changes: 151 additions & 0 deletions vcd/datasource_vcd_ip_space.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package vcd

import (
"context"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/go-vcloud-director/v2/govcd"
)

func datasourceVcdIpSpace() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcdIpSpaceRead,

Schema: map[string]*schema.Schema{
"org_id": {
Type: schema.TypeString,
Optional: true,
Description: "Org ID for 'SHARED' IP spaces",
},
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of IP space",
},
"type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of IP space",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "Description of IP space",
},
"internal_scope": {
Type: schema.TypeSet,
Computed: true,
Description: "A set of up internal scope IPs in CIDR format",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ip_range_quota": {
Type: schema.TypeString,
Computed: true,
Description: "IP range quota",
},
"ip_range": {
Type: schema.TypeSet,
Computed: true,
Description: "IP ranges",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"start_address": {
Type: schema.TypeString,
Computed: true,
Description: "Start address of the IP range",
},
"end_address": {
Type: schema.TypeString,
Computed: true,
Description: "End address of the IP range",
},
},
},
},
"ip_prefix": {
Type: schema.TypeSet,
Computed: true,
Description: "IP prefixes",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"prefix": {
Type: schema.TypeSet,
Computed: true,
Description: "IP Prefix",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"first_ip": {
Type: schema.TypeString,
Computed: true,
Description: "First IP",
},
"prefix_length": {
Type: schema.TypeString,
Computed: true,
Description: "Prefix length",
},
"prefix_count": {
Type: schema.TypeString,
Computed: true,
Description: "Prefix count",
},
},
},
},
"default_quota": {
Type: schema.TypeString,
Computed: true,
Description: "Floating IP quota",
},
},
},
},
"external_scope": {
Type: schema.TypeString,
Computed: true,
Description: "External scope in CIDR format",
},
"route_advertisement_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Flag exposing if route advertisement is enabled",
},
},
}
}

func datasourceVcdIpSpaceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)
log.Printf("[TRACE] IP Space datasource read initiated")

orgId := d.Get("org_id").(string)
ipSpaceName := d.Get("name").(string)

var ipSpace *govcd.IpSpace
var err error

if orgId != "" { // in case org_id is provided (PRIVATE IP Space)
ipSpace, err = vcdClient.GetIpSpaceByNameAndOrgId(ipSpaceName, orgId)
adambarreiro marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return diag.Errorf("error retrieving IP Space '%s' in Org ID '%s': %s", ipSpaceName, orgId, err)
}
} else {
ipSpace, err = vcdClient.GetIpSpaceByName(ipSpaceName)
if err != nil {
return diag.Errorf("error retrieving IP Space '%s': %s", ipSpaceName, err)
}
}

err = setIpSpaceData(d, ipSpace.IpSpace)
if err != nil {
return diag.Errorf("error storing IP Space state: %s", err)
}

d.SetId(ipSpace.IpSpace.ID)

return nil
}
2 changes: 2 additions & 0 deletions 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_ip_space": datasourceVcdIpSpace(), // 3.10
"vcd_nsxt_edgegateway_dhcp_forwarding": datasourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
"vcd_org_saml": datasourceVcdOrgSaml(), // 3.10
"vcd_org_saml_metadata": datasourceVcdOrgSamlMetadata(), // 3.10
Expand Down Expand Up @@ -207,6 +208,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_ip_space": resourceVcdIpSpace(), // 3.10
"vcd_nsxt_edgegateway_dhcp_forwarding": resourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
"vcd_org_saml": resourceVcdOrgSaml(), // 3.10
}
Expand Down
28 changes: 28 additions & 0 deletions vcd/remove_leftovers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ func removeLeftovers(govcdClient *govcd.VCDClient, verbose bool) error {
}
}
}

// --------------------------------------------------------------
// IP Spaces
// --------------------------------------------------------------
err = removeLeftoversIpSpaces(govcdClient, true)
if err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -493,6 +501,26 @@ func removeLeftoversNsxtAlbTenant(govcdClient *govcd.VCDClient, verbose bool) er
return nil
}

func removeLeftoversIpSpaces(govcdClient *govcd.VCDClient, verbose bool) error {
allIpSpaces, err := govcdClient.GetAllIpSpaceSummaries(nil)
if err != nil {
return fmt.Errorf("error retrieving IP spaces")
}

for _, ipSpace := range allIpSpaces {
toBeDeleted := shouldDeleteEntity(alsoDelete, doNotDelete, ipSpace.IpSpace.Name, "vcd_ip_space", 0, verbose)
if toBeDeleted {
fmt.Printf("REMOVING IP Space %s\n", ipSpace.IpSpace.Name)
err = ipSpace.Delete()
if err != nil {
return fmt.Errorf("error deleting IP Space '%s': %s", ipSpace.IpSpace.Name, err)
}
}
}

return nil
}

// shouldDeleteEntity checks whether a given entity is to be deleted, either by its name
// or by its inclusion in one of the entity lists
func shouldDeleteEntity(alsoDelete, doNotDelete entityList, name, entityType string, level int, verbose bool) bool {
Expand Down
Loading