Skip to content

Commit

Permalink
NSX-T Segment Profile Template support (vmware#1120)
Browse files Browse the repository at this point in the history
  • Loading branch information
Didainius authored Nov 7, 2023
1 parent b5b1a70 commit dff899e
Show file tree
Hide file tree
Showing 43 changed files with 4,064 additions and 281 deletions.
3 changes: 3 additions & 0 deletions .changes/v3.11.0/1120-deprecations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* Resource `vcd_org_vdc` deprecates `edge_cluster_id` in favor of new resource
`vcd_org_vdc_nsxt_network_profile` that can configure NSX-T Edge Clusters and default Segment
Profile Templates for NSX-T VDCs [GH-1120]
13 changes: 13 additions & 0 deletions .changes/v3.11.0/1120-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
* **New Data Source:** `vcd_nsxt_segment_ip_discovery_profile` to read NSX-T IP Discovery Segment Profiles [GH-1120]
* **New Data Source:** `vcd_nsxt_segment_mac_discovery_profile` to read NSX-T MAC Discovery Segment Profiles [GH-1120]
* **New Data Source:** `vcd_nsxt_segment_spoof_guard_profile` to read NSX-T Spoof Guard Profiles [GH-1120]
* **New Data Source:** `vcd_nsxt_segment_qos_profile` to read NSX-T QoS Profiles [GH-1120]
* **New Data Source:** `vcd_nsxt_segment_security_profile` to read NSX-T Segment Security Profiles [GH-1120]
* **New Resource:** `vcd_nsxt_segment_profile_template` to manage NSX-T Segment Profile Templates [GH-1120]
* **New Data Source:** `vcd_nsxt_segment_profile_template` to read NSX-T Segment Profile Templates [GH-1120]
* **New Resource:** `vcd_nsxt_global_default_segment_profile_template` to manage NSX-T Global Default Segment Profile Templates [GH-1120]
* **New Data Source:** `vcd_nsxt_global_default_segment_profile_template` to read NSX-T Global Default Segment Profile Templates [GH-1120]
* **New Resource:** `vcd_org_vdc_nsxt_network_profile` to manage default Segment Profile Templates for NSX-T VDCs [GH-1120]
* **New Data Source:** `vcd_org_vdc_nsxt_network_profile` to read default Segment Profile Templates for NSX-T VDCs [GH-1120]
* **New Resource:** `vcd_nsxt_network_segment_profile` to manage individual Segment Profiles or Segment Profile Templates for NSX-T Org VDC Networks [GH-1120]
* **New Data Source:** `vcd_nsxt_network_segment_profile` to read individual Segment Profiles or Segment Profile Templates for NSX-T Org VDC Networks [GH-1120]
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
github.com/kr/pretty v0.2.1
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.9
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.10
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.9 h1:3cY/rmJVPgdz83+SHZynmNJUP4IqsxxFvHDF6BxkI6s=
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.9/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.10 h1:QboVfzGd9x2ZY52YYBhPBbrL+RWn60Z3hIfNml5NkYU=
github.com/vmware/go-vcloud-director/v2 v2.22.0-alpha.10/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc=
Expand Down
1 change: 1 addition & 0 deletions scripts/skip-upgrade-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ vcd.TestAccVcdVmPlacementPolicyWithoutDescription.tf v3.9.0 "Changed 'descriptio
vcd.TestAccVcdVmPlacementPolicy.tf v3.9.0 "Changed 'description' to Computed in 'vcd_vm_placement_policy'"
vcd.ResourceSchema-vcd_vdc_group.tf v3.10.0 "Added new field 'force_delete'"
vcd.ResourceSchema-vcd_nsxt_alb_pool.tf v3.10.0 "added field 'ssl_enabled'"
vcd.ResourceSchema-vcd_org_vdc.tf v3.10.0 "field 'edge_cluster_id' becomes computed"
vcd.ResourceSchema-vcd_nsxt_edgegateway.tf v3.10.0 "Added support for Segment backed external networks"
vcd.ResourceSchema-vcd_vapp_vm.tf v3.11.0 "added fields 'firmware' and 'boot_options'"
vcd.ResourceSchema-vcd_vm.tf v3.11.0 "added fields 'firmware' and 'boot_options'"
Expand Down
5 changes: 5 additions & 0 deletions vcd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ type TestConfig struct {
RoutedNetwork string `json:"routedNetwork"`
IsolatedNetwork string `json:"isolatedNetwork"`
DirectNetwork string `json:"directNetwork"`
IpDiscoveryProfile string `json:"ipDiscoveryProfile"`
MacDiscoveryProfile string `json:"macDiscoveryProfile"`
SpoofGuardProfile string `json:"spoofGuardProfile"`
QosProfile string `json:"qosProfile"`
SegmentSecurityProfile string `json:"segmentSecurityProfile"`
} `json:"nsxt"`
VSphere struct {
ResourcePoolForVcd1 string `json:"resourcePoolForVcd1,omitempty"`
Expand Down
35 changes: 35 additions & 0 deletions vcd/datasource_not_found_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ func TestAccDataSourceNotFound(t *testing.T) {

func testSpecificDataSourceNotFound(dataSourceName string, vcdClient *VCDClient) func(*testing.T) {
return func(t *testing.T) {

type skipAlways struct {
dataSourceName string
reason string
}

skipAlwaysSlice := []skipAlways{
{
dataSourceName: "vcd_nsxt_global_default_segment_profile_template",
reason: "Global Default Segment Profile Template configuration is always available",
},
}
for _, skip := range skipAlwaysSlice {
if dataSourceName == skip.dataSourceName {
t.Skipf("Skipping: %s", skip.reason)
}
}

// Skip subtest based on versions
type skipOnVersion struct {
skipVersionConstraint string
Expand Down Expand Up @@ -96,6 +114,16 @@ func testSpecificDataSourceNotFound(dataSourceName string, vcdClient *VCDClient)
"vcd_resource_pool",
"vcd_network_pool",
"vcd_nsxt_edgegateway_qos_profile",
"vcd_nsxt_segment_ip_discovery_profile",
"vcd_nsxt_segment_mac_discovery_profile",
"vcd_nsxt_segment_spoof_guard_profile",
"vcd_nsxt_segment_qos_profile",
"vcd_nsxt_segment_security_profile",
"vcd_org_vdc_nsxt_network_profile",
"vcd_nsxt_global_default_segment_profile_template",
"vcd_nsxt_network_segment_profile",
"vcd_nsxt_segment_profile_template",
"vcd_nsxt_network_context_profile",
}
dataSourcesRequiringAlbConfig := []string{
"vcd_nsxt_alb_cloud",
Expand Down Expand Up @@ -142,10 +170,17 @@ func testSpecificDataSourceNotFound(dataSourceName string, vcdClient *VCDClient)
"DataSourceName": dataSourceName,
"MandatoryFields": addedParams,
}

if dataSourceName == "vcd_nsxv_distributed_firewall" {
params["MandatoryFields"] = `vdc_id = "deadbeef-dead-beef-dead-beefdeadbeef"`
}

if dataSourceName == "vcd_org_vdc_nsxt_network_profile" {
config := `org = "` + testConfig.VCD.Org + `"` + "\n"
config += `vdc = "non-existing"` + "\n"
params["MandatoryFields"] = config
}

params["FuncName"] = "NotFoundDataSource-" + dataSourceName
// Adding skip directive as running these tests in binary test mode add no value
binaryTestSkipText := "# skip-binary-test: data source not found test only works in acceptance tests\n"
Expand Down
23 changes: 23 additions & 0 deletions vcd/datasource_vcd_nsxt_global_default_segment_profile_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package vcd

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

func datasourceVcdGlobalDefaultSegmentProfileTemplate() *schema.Resource {
return &schema.Resource{
ReadContext: resourceDataSourceVcdGlobalDefaultSegmentProfileTemplateRead,
Schema: map[string]*schema.Schema{
"vdc_networks_default_segment_profile_template_id": {
Type: schema.TypeString,
Computed: true,
Description: "Global default NSX-T Segment Profile for Org VDC networks",
},
"vapp_networks_default_segment_profile_template_id": {
Type: schema.TypeString,
Computed: true,
Description: "Global default NSX-T Segment Profile for vApp networks",
},
},
}
}
69 changes: 69 additions & 0 deletions vcd/datasource_vcd_nsxt_network_segment_profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package vcd

import (
"context"

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

func datasourceVcdNsxtOrgVdcNetworkSegmentProfileTemplate() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceVcdNsxtOrgVdcNetworkSegmentProfileRead,

Schema: map[string]*schema.Schema{
"org": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: "The name of organization to use, optional if defined at provider " +
"level. Useful when connected as sysadmin working across different organizations",
},
"org_network_id": {
Type: schema.TypeString,
Required: true,
Description: "ID of the Organization Network that uses the Segment Profile Template",
},
"segment_profile_template_id": {
Type: schema.TypeString,
Computed: true,
Description: "Segment Profile Template ID",
},
"segment_profile_template_name": {
Type: schema.TypeString,
Computed: true,
Description: "Segment Profile Template Name",
},
// Individual Segment Profiles
"ip_discovery_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "NSX-T IP Discovery Profile",
},
"mac_discovery_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "NSX-T Mac Discovery Profile",
},
"spoof_guard_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "NSX-T Spoof Guard Profile",
},
"qos_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "NSX-T QoS Profile",
},
"segment_security_profile_id": {
Type: schema.TypeString,
Computed: true,
Description: "NSX-T Segment Security Profile",
},
},
}
}

func dataSourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return resourceDataSourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx, d, meta, "datasource")
}
152 changes: 152 additions & 0 deletions vcd/datasource_vcd_nsxt_segment_ip_discovery_profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package vcd

import (
"context"
"fmt"
"net/url"

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

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

func datasourceVcdNsxtSegmentIpDiscoveryProfile() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceNsxtSegmentIpDiscoveryProfileRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of Segment IP Discovery Profile",
},
"nsxt_manager_id": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"nsxt_manager_id", "vdc_id", "vdc_group_id"},
Description: "ID of NSX-T Manager",
},
"vdc_id": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"nsxt_manager_id", "vdc_id", "vdc_group_id"},
Description: "ID of VDC",
},
"vdc_group_id": {
Type: schema.TypeString,
Optional: true,
ExactlyOneOf: []string{"nsxt_manager_id", "vdc_id", "vdc_group_id"},
Description: "ID of VDC Group",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "Description of Segment IP Discovery Profile",
},
"arp_binding_limit": {
Type: schema.TypeInt,
Computed: true,
Description: "Indicates the number of ARP snooped IP addresses to be remembered per logical port",
},
"arp_binding_timeout": {
Type: schema.TypeInt,
Computed: true,
Description: "Indicates ARP and ND cache timeout (in minutes)",
},
"is_arp_snooping_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Defines whether ARP snooping is enabled",
},
"is_dhcp_snooping_v4_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Defines whether DHCP snooping for IPv4 is enabled",
},
"is_dhcp_snooping_v6_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Defines whether DHCP snooping for IPv6 is enabled",
},
"is_duplicate_ip_detection_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether duplicate IP detection is enabled",
},
"is_nd_snooping_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether neighbor discovery (ND) snooping is enabled",
},
"is_tofu_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Defines whether 'Trust on First Use (TOFU)' paradigm is enabled",
},
"is_vmtools_v4_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether fetching IPv4 address using vm-tools is enabled",
},
"is_vmtools_v6_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether fetching IPv6 address using vm-tools is enabled",
},
"nd_snooping_limit": {
Type: schema.TypeInt,
Computed: true,
Description: "Maximum number of Neighbor Discovery (ND) snooped IPv6 addresses",
},
},
}
}

func datasourceNsxtSegmentIpDiscoveryProfileRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcdClient := meta.(*VCDClient)
profileName := d.Get("name").(string)

contextFilterField, contextUrn, err := getContextFilterField(d)
if err != nil {
return diag.FromErr(err)
}

queryFilter := url.Values{}
queryFilter.Add("filter", fmt.Sprintf("%s==%s", contextFilterField, contextUrn))

ipDiscoveryProfile, err := vcdClient.GetIpDiscoveryProfileByName(profileName, queryFilter)
if err != nil {
return diag.Errorf("could not find IP Discovery Profile by name '%s': %s", profileName, err)
}

dSet(d, "description", ipDiscoveryProfile.Description)
dSet(d, "arp_binding_limit", ipDiscoveryProfile.ArpBindingLimit)
dSet(d, "arp_binding_timeout", ipDiscoveryProfile.ArpNdBindingTimeout)
dSet(d, "is_arp_snooping_enabled", ipDiscoveryProfile.IsArpSnoopingEnabled)
dSet(d, "is_dhcp_snooping_v4_enabled", ipDiscoveryProfile.IsDhcpSnoopingV4Enabled)
dSet(d, "is_dhcp_snooping_v6_enabled", ipDiscoveryProfile.IsDhcpSnoopingV6Enabled)
dSet(d, "is_duplicate_ip_detection_enabled", ipDiscoveryProfile.IsDuplicateIPDetectionEnabled)
dSet(d, "is_nd_snooping_enabled", ipDiscoveryProfile.IsNdSnoopingEnabled)
dSet(d, "is_tofu_enabled", ipDiscoveryProfile.IsTofuEnabled)
dSet(d, "is_vmtools_v4_enabled", ipDiscoveryProfile.IsVMToolsV4Enabled)
dSet(d, "is_vmtools_v6_enabled", ipDiscoveryProfile.IsVMToolsV6Enabled)
dSet(d, "nd_snooping_limit", ipDiscoveryProfile.NdSnoopingLimit)

d.SetId(ipDiscoveryProfile.ID)

return nil
}

// getContextFilterField determines which field should be used for filtering
func getContextFilterField(d *schema.ResourceData) (string, string, error) {
switch {
case d.Get("nsxt_manager_id").(string) != "":
return "nsxTManagerRef.id", d.Get("nsxt_manager_id").(string), nil
case d.Get("vdc_id").(string) != "":
return "orgVdcId", d.Get("vdc_id").(string), nil
case d.Get("vdc_group_id").(string) != "":
return "vdcGroupId", d.Get("vdc_group_id").(string), nil

}

return "", "", fmt.Errorf("unknown filtering field")
}
Loading

0 comments on commit dff899e

Please sign in to comment.