diff --git a/.changes/v3.11.0/1120-deprecations.md b/.changes/v3.11.0/1120-deprecations.md new file mode 100644 index 000000000..c899671aa --- /dev/null +++ b/.changes/v3.11.0/1120-deprecations.md @@ -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] diff --git a/.changes/v3.11.0/1120-features.md b/.changes/v3.11.0/1120-features.md new file mode 100644 index 000000000..203ec51c8 --- /dev/null +++ b/.changes/v3.11.0/1120-features.md @@ -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] diff --git a/go.mod b/go.mod index cb7bcfa7f..3c7d5f4bd 100644 --- a/go.mod +++ b/go.mod @@ -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 ( diff --git a/go.sum b/go.sum index 24a2750d5..20f6704c9 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/scripts/skip-upgrade-tests.txt b/scripts/skip-upgrade-tests.txt index 50a9eeca4..ed081dc95 100644 --- a/scripts/skip-upgrade-tests.txt +++ b/scripts/skip-upgrade-tests.txt @@ -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'" diff --git a/vcd/config_test.go b/vcd/config_test.go index 4863f6919..89a24663a 100644 --- a/vcd/config_test.go +++ b/vcd/config_test.go @@ -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"` diff --git a/vcd/datasource_not_found_test.go b/vcd/datasource_not_found_test.go index 14e4363db..758ade6e7 100644 --- a/vcd/datasource_not_found_test.go +++ b/vcd/datasource_not_found_test.go @@ -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 @@ -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", @@ -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" diff --git a/vcd/datasource_vcd_nsxt_global_default_segment_profile_template.go b/vcd/datasource_vcd_nsxt_global_default_segment_profile_template.go new file mode 100644 index 000000000..57084aff4 --- /dev/null +++ b/vcd/datasource_vcd_nsxt_global_default_segment_profile_template.go @@ -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", + }, + }, + } +} diff --git a/vcd/datasource_vcd_nsxt_network_segment_profile.go b/vcd/datasource_vcd_nsxt_network_segment_profile.go new file mode 100644 index 000000000..94aa08c5a --- /dev/null +++ b/vcd/datasource_vcd_nsxt_network_segment_profile.go @@ -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") +} diff --git a/vcd/datasource_vcd_nsxt_segment_ip_discovery_profile.go b/vcd/datasource_vcd_nsxt_segment_ip_discovery_profile.go new file mode 100644 index 000000000..fb6712609 --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_ip_discovery_profile.go @@ -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") +} diff --git a/vcd/datasource_vcd_nsxt_segment_mac_discovery_profile.go b/vcd/datasource_vcd_nsxt_segment_mac_discovery_profile.go new file mode 100644 index 000000000..4ea0ef61c --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_mac_discovery_profile.go @@ -0,0 +1,107 @@ +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 datasourceVcdNsxtSegmentMacDiscoveryProfile() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceNsxtSegmentMacDiscoveryProfileRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment MAC 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 MAC Discovery Profile", + }, + "is_mac_change_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indcates whether source MAC address change is enabled", + }, + "is_mac_learning_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether source MAC address learning is enabled", + }, + "is_unknown_unicast_flooding_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether unknown unicast flooding rule is enabled", + }, + "mac_learning_aging_time": { + Type: schema.TypeInt, + Computed: true, + Description: "Indicates aging time in seconds for learned MAC address", + }, + "mac_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "Indicates the maximum number of MAC addresses that can be learned on this port", + }, + "mac_policy": { + Type: schema.TypeString, + Computed: true, + Description: "Defines the policy after MAC Limit is exceeded. It can be either 'ALLOW' or 'DROP'", + }, + }, + } +} + +func datasourceNsxtSegmentMacDiscoveryProfileRead(_ 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)) + + macDiscoveryProfile, err := vcdClient.GetMacDiscoveryProfileByName(profileName, queryFilter) + if err != nil { + return diag.Errorf("could not find MAC Discovery Profile by name '%s': %s", profileName, err) + } + + dSet(d, "description", macDiscoveryProfile.Description) + dSet(d, "is_mac_change_enabled", macDiscoveryProfile.IsMacChangeEnabled) + dSet(d, "is_mac_learning_enabled", macDiscoveryProfile.IsMacLearningEnabled) + dSet(d, "is_unknown_unicast_flooding_enabled", macDiscoveryProfile.IsUnknownUnicastFloodingEnabled) + dSet(d, "mac_learning_aging_time", macDiscoveryProfile.MacLearningAgingTime) + dSet(d, "mac_limit", macDiscoveryProfile.MacLimit) + dSet(d, "mac_policy", macDiscoveryProfile.MacPolicy) + + d.SetId(macDiscoveryProfile.ID) + + return nil +} diff --git a/vcd/datasource_vcd_nsxt_segment_profile_template.go b/vcd/datasource_vcd_nsxt_segment_profile_template.go new file mode 100644 index 000000000..f4d6af32f --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_profile_template.go @@ -0,0 +1,71 @@ +package vcd + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func datasourceVcdSegmentProfileTemplate() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceVcdSegmentProfileTemplateRead, + + Schema: map[string]*schema.Schema{ + + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment Profile Template", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of Segment Profile Template", + }, + "nsxt_manager_id": { + Type: schema.TypeString, + Computed: true, + Description: "NSX-T Manager ID", + }, + "ip_discovery_profile_id": { + Type: schema.TypeString, + Computed: true, + Description: "Segment IP Discovery Profile ID", + }, + "mac_discovery_profile_id": { + Type: schema.TypeString, + Computed: true, + Description: "Segment MAC Discovery Profile ID", + }, + "spoof_guard_profile_id": { + Type: schema.TypeString, + Computed: true, + Description: "Segment Spoof Guard Profile ID", + }, + "qos_profile_id": { + Type: schema.TypeString, + Computed: true, + Description: "Segment QoS Profile ID", + }, + "segment_security_profile_id": { + Type: schema.TypeString, + Computed: true, + Description: "Segment Security Profile ID", + }, + }, + } +} + +func datasourceVcdSegmentProfileTemplateRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + segmentProfileTemplate, err := vcdClient.GetSegmentProfileTemplateByName(d.Get("name").(string)) + if err != nil { + return diag.FromErr(err) + } + + setNsxtSegmentProfileTemplateData(d, segmentProfileTemplate.NsxtSegmentProfileTemplate) + d.SetId(segmentProfileTemplate.NsxtSegmentProfileTemplate.ID) + + return nil +} diff --git a/vcd/datasource_vcd_nsxt_segment_profiles_test.go b/vcd/datasource_vcd_nsxt_segment_profiles_test.go new file mode 100644 index 000000000..750f540ef --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_profiles_test.go @@ -0,0 +1,332 @@ +//go:build network || nsxt || ALL || functional + +package vcd + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccVcdDataSourceNsxtSegmentProfiles(t *testing.T) { + preTestChecks(t) + skipIfNotSysAdmin(t) + + // String map to fill the template + var params = StringMap{ + "TestName": t.Name(), + "OrgName": testConfig.VCD.Org, + "VdcName": testConfig.Nsxt.Vdc, + "VdcGroupName": testConfig.Nsxt.VdcGroup, + "NsxtManager": testConfig.Nsxt.Manager, + + "IpDiscoveryProfileName": testConfig.Nsxt.IpDiscoveryProfile, + "MacDiscoveryProfileName": testConfig.Nsxt.MacDiscoveryProfile, + "QosProfileName": testConfig.Nsxt.QosProfile, + "SpoofGuardProfileName": testConfig.Nsxt.SpoofGuardProfile, + "SegmentSecurityProfileName": testConfig.Nsxt.SegmentSecurityProfile, + + "Tags": "nsxt", + } + testParamsNotEmpty(t, params) + + configText1 := templateFill(testAccVcdDataSourceNsxtSegmentProfilesByNsxtManager, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 1: %s", configText1) + + params["FuncName"] = t.Name() + "step2" + configText2 := templateFill(testAccVcdDataSourceNsxtSegmentProfilesByVdcId, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 2: %s", configText2) + + params["FuncName"] = t.Name() + "step3" + configText3 := templateFill(testAccVcdDataSourceNsxtSegmentProfilesByVdcGroupId, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 3: %s", configText3) + + 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_segment_ip_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_timeout"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_arp_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v6_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_duplicate_ip_detection_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_nd_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_tofu_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v6_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_change_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_learning_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_unknown_unicast_flooding_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_learning_aging_time"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_policy"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "is_address_binding_whitelist_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "class_of_service"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_priority"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_trust_mode"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_peak_bandwidth"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "bpdu_filter_allow_list.#"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_bpdu_filter_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_non_ip_traffic_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_ra_guard_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_rate_limitting_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_multicast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_multicast_limit"), + ), + }, + { + Config: configText2, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_timeout"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_arp_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v6_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_duplicate_ip_detection_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_nd_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_tofu_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v6_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_change_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_learning_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_unknown_unicast_flooding_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_learning_aging_time"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_policy"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "is_address_binding_whitelist_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "class_of_service"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_priority"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_trust_mode"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_peak_bandwidth"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "bpdu_filter_allow_list.#"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_bpdu_filter_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_non_ip_traffic_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_ra_guard_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_rate_limitting_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_multicast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_multicast_limit"), + ), + }, + { + Config: configText3, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "arp_binding_timeout"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_arp_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_dhcp_snooping_v6_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_duplicate_ip_detection_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_nd_snooping_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_tofu_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v4_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_ip_discovery_profile.first", "is_vmtools_v6_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_change_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_mac_learning_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "is_unknown_unicast_flooding_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_learning_aging_time"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_mac_discovery_profile.first", "mac_policy"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_spoof_guard_profile.first", "is_address_binding_whitelist_enabled"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "class_of_service"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_priority"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "dscp_trust_mode"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "egress_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_broadcast_rate_limiter_peak_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_avg_bandwidth"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_burst_size"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_qos_profile.first", "ingress_rate_limiter_peak_bandwidth"), + + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "id"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "description"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "bpdu_filter_allow_list.#"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_bpdu_filter_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_client_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v4_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_dhcp_v6_server_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_non_ip_traffic_block_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_ra_guard_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "is_rate_limitting_enabled"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "rx_multicast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_broadcast_limit"), + resource.TestCheckResourceAttrSet("data.vcd_nsxt_segment_security_profile.first", "tx_multicast_limit"), + ), + }, + }, + }) +} + +const testAccVcdDataSourceNsxtSegmentProfilesByNsxtManager = ` +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +` + +const testAccVcdDataSourceNsxtSegmentProfilesByVdcId = ` +data "vcd_org_vdc" "nsxt" { + org = "{{.OrgName}}" + name = "{{.VdcName}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + vdc_id = data.vcd_org_vdc.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + vdc_id = data.vcd_org_vdc.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + vdc_id = data.vcd_org_vdc.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + vdc_id = data.vcd_org_vdc.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + vdc_id = data.vcd_org_vdc.nsxt.id +} +` + +const testAccVcdDataSourceNsxtSegmentProfilesByVdcGroupId = ` +data "vcd_vdc_group" "nsxt" { + org = "{{.OrgName}}" + name = "{{.VdcGroupName}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + vdc_group_id = data.vcd_vdc_group.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + vdc_group_id = data.vcd_vdc_group.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + vdc_group_id = data.vcd_vdc_group.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + vdc_group_id = data.vcd_vdc_group.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + vdc_group_id = data.vcd_vdc_group.nsxt.id +} +` diff --git a/vcd/datasource_vcd_nsxt_segment_qos_profile.go b/vcd/datasource_vcd_nsxt_segment_qos_profile.go new file mode 100644 index 000000000..fdf24bba7 --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_qos_profile.go @@ -0,0 +1,143 @@ +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 datasourceVcdNsxtSegmentQosProfile() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceNsxtSegmentQosProfileRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment QoS 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 QoS Profile", + }, + "class_of_service": { + Type: schema.TypeInt, + Computed: true, + Description: "Groups similar types of traffic in the network and each type of traffic is treated as a class with its own level of service priority", + }, + "dscp_priority": { + Type: schema.TypeInt, + Computed: true, + Description: "Differentiated Services Code Point priority", + }, + "dscp_trust_mode": { + Type: schema.TypeString, + Computed: true, + Description: "Differentiated Services Code Point trust mode", + }, + "egress_rate_limiter_avg_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Average bandwidth in Mb/s", + }, + "egress_rate_limiter_burst_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Burst size in bytes", + }, + "egress_rate_limiter_peak_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Peak bandwidth in Mb/s", + }, + "ingress_broadcast_rate_limiter_avg_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Average bandwidth in Mb/s", + }, + "ingress_broadcast_rate_limiter_burst_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Burst size in bytes", + }, + "ingress_broadcast_rate_limiter_peak_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Peak bandwidth in Mb/s", + }, + "ingress_rate_limiter_avg_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Average bandwidth in Mb/s", + }, + "ingress_rate_limiter_burst_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Burst size in bytes", + }, + "ingress_rate_limiter_peak_bandwidth": { + Type: schema.TypeInt, + Computed: true, + Description: "Peak bandwidth in Mb/s", + }, + }, + } +} + +func datasourceNsxtSegmentQosProfileRead(_ 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)) + + qosProfile, err := vcdClient.GetQoSProfileByName(profileName, queryFilter) + if err != nil { + return diag.Errorf("could not find QoS Profile by name '%s': %s", profileName, err) + } + + dSet(d, "description", qosProfile.Description) + dSet(d, "class_of_service", qosProfile.ClassOfService) + dSet(d, "dscp_priority", qosProfile.DscpConfig.Priority) + dSet(d, "dscp_trust_mode", qosProfile.DscpConfig.TrustMode) + dSet(d, "egress_rate_limiter_avg_bandwidth", qosProfile.EgressRateLimiter.AvgBandwidth) + dSet(d, "egress_rate_limiter_burst_size", qosProfile.EgressRateLimiter.BurstSize) + dSet(d, "egress_rate_limiter_peak_bandwidth", qosProfile.EgressRateLimiter.PeakBandwidth) + dSet(d, "ingress_broadcast_rate_limiter_avg_bandwidth", qosProfile.IngressBroadcastRateLimiter.AvgBandwidth) + dSet(d, "ingress_broadcast_rate_limiter_burst_size", qosProfile.IngressBroadcastRateLimiter.BurstSize) + dSet(d, "ingress_broadcast_rate_limiter_peak_bandwidth", qosProfile.IngressBroadcastRateLimiter.PeakBandwidth) + dSet(d, "ingress_rate_limiter_avg_bandwidth", qosProfile.IngressRateLimiter.AvgBandwidth) + dSet(d, "ingress_rate_limiter_burst_size", qosProfile.IngressRateLimiter.BurstSize) + dSet(d, "ingress_rate_limiter_peak_bandwidth", qosProfile.IngressRateLimiter.PeakBandwidth) + + d.SetId(qosProfile.ID) + + return nil +} diff --git a/vcd/datasource_vcd_nsxt_segment_security_profile.go b/vcd/datasource_vcd_nsxt_segment_security_profile.go new file mode 100644 index 000000000..e37b3b439 --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_security_profile.go @@ -0,0 +1,158 @@ +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 datasourceVcdNsxtSegmentSecurityProfile() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceNsxtSegmentSecurityProfileRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment Security 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 Security Profile", + }, + "bpdu_filter_allow_list": { + Type: schema.TypeSet, + Optional: true, + Description: "Indicates pre-defined list of allowed MAC addresses to be excluded from BPDU filtering", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "is_bpdu_filter_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether BPDU filter is enabled", + }, + "is_dhcp_v4_client_block_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether DHCP Client block IPv4 is enabled", + }, + "is_dhcp_v6_client_block_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether DHCP Client block IPv6 is enabled", + }, + "is_dhcp_v4_server_block_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether DHCP Server block IPv4 is enabled", + }, + "is_dhcp_v6_server_block_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether DHCP Server block IPv6 is enabled", + }, + "is_non_ip_traffic_block_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether non IP traffic block is enabled", + }, + "is_ra_guard_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether Router Advertisement Guard is enabled", + }, + "is_rate_limitting_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether Rate Limiting is enabled", + }, + "rx_broadcast_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "Incoming broadcast traffic limit in packets per second", + }, + "rx_multicast_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "Incoming multicast traffic limit in packets per second", + }, + "tx_broadcast_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "Outgoing broadcast traffic limit in packets per second", + }, + "tx_multicast_limit": { + Type: schema.TypeInt, + Computed: true, + Description: "Outgoing multicast traffic limit in packets per second", + }, + }, + } +} + +func datasourceNsxtSegmentSecurityProfileRead(_ 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)) + + segmentSecurityProfile, err := vcdClient.GetSegmentSecurityProfileByName(profileName, queryFilter) + if err != nil { + return diag.Errorf("could not find Segment Security Profile by name '%s': %s", profileName, err) + } + + dSet(d, "description", segmentSecurityProfile.Description) + + bpduAllowList := convertStringsToTypeSet(segmentSecurityProfile.BpduFilterAllowList) + err = d.Set("bpdu_filter_allow_list", bpduAllowList) + if err != nil { + return diag.Errorf("error storing 'bpdu_filter_allow_list': %s", err) + } + + dSet(d, "is_bpdu_filter_enabled", segmentSecurityProfile.IsBpduFilterEnabled) + dSet(d, "is_dhcp_v4_client_block_enabled", segmentSecurityProfile.IsDhcpClientBlockV4Enabled) + dSet(d, "is_dhcp_v6_client_block_enabled", segmentSecurityProfile.IsDhcpClientBlockV6Enabled) + dSet(d, "is_dhcp_v4_server_block_enabled", segmentSecurityProfile.IsDhcpServerBlockV4Enabled) + dSet(d, "is_dhcp_v6_server_block_enabled", segmentSecurityProfile.IsDhcpServerBlockV6Enabled) + dSet(d, "is_non_ip_traffic_block_enabled", segmentSecurityProfile.IsNonIPTrafficBlockEnabled) + dSet(d, "is_ra_guard_enabled", segmentSecurityProfile.IsRaGuardEnabled) + dSet(d, "is_rate_limitting_enabled", segmentSecurityProfile.IsRateLimitingEnabled) + dSet(d, "rx_broadcast_limit", segmentSecurityProfile.RateLimits.RxBroadcast) + dSet(d, "rx_multicast_limit", segmentSecurityProfile.RateLimits.RxMulticast) + dSet(d, "tx_broadcast_limit", segmentSecurityProfile.RateLimits.TxBroadcast) + dSet(d, "tx_multicast_limit", segmentSecurityProfile.RateLimits.TxMulticast) + + d.SetId(segmentSecurityProfile.ID) + + return nil +} diff --git a/vcd/datasource_vcd_nsxt_segment_spoof_guard_profile.go b/vcd/datasource_vcd_nsxt_segment_spoof_guard_profile.go new file mode 100644 index 000000000..d93b47d7b --- /dev/null +++ b/vcd/datasource_vcd_nsxt_segment_spoof_guard_profile.go @@ -0,0 +1,77 @@ +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 datasourceVcdNsxtSegmentSpoofGuardProfile() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceNsxtSegmentSpoofGuardProfileRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment Spoof Guard 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 Spoof Guard Profile", + }, + "is_address_binding_whitelist_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether Spoof Guard is enabled", + }, + }, + } +} + +func datasourceNsxtSegmentSpoofGuardProfileRead(_ 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)) + + spoofGuardProfile, err := vcdClient.GetSpoofGuardProfileByName(profileName, queryFilter) + if err != nil { + return diag.Errorf("could not find Spoof Guard Profile by name '%s': %s", profileName, err) + } + + dSet(d, "description", spoofGuardProfile.Description) + dSet(d, "is_address_binding_whitelist_enabled", spoofGuardProfile.IsAddressBindingWhitelistEnabled) + + d.SetId(spoofGuardProfile.ID) + + return nil +} diff --git a/vcd/datasource_vcd_org_vdc_network_profile.go b/vcd/datasource_vcd_org_vdc_network_profile.go new file mode 100644 index 000000000..fd2535d1e --- /dev/null +++ b/vcd/datasource_vcd_org_vdc_network_profile.go @@ -0,0 +1,49 @@ +package vcd + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func datasourceVcdNsxtOrgVdcNetworkProfile() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceVcdNsxtOrgVdcNetworkProfileRead, + + 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", + }, + "vdc": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "The name of VDC to use, optional if defined at provider level", + }, + "edge_cluster_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of NSX-T Edge Cluster (provider vApp networking services and DHCP capability for Isolated networks)", + }, + "vdc_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Computed: true, + Description: "Default NSX-T Segment Profile for Org VDC networks", + }, + "vapp_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Computed: true, + Description: "Default NSX-T Segment Profile for vApp networks", + }, + }, + } +} + +func dataSourceVcdNsxtOrgVdcNetworkProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return resourceDataSourceVcdNsxtOrgVdcNetworkProfileRead(ctx, d, meta, "datasource") +} diff --git a/vcd/provider.go b/vcd/provider.go index 87bdd9dc7..8ebcd5104 100644 --- a/vcd/provider.go +++ b/vcd/provider.go @@ -3,10 +3,11 @@ package vcd import ( "context" "fmt" - "github.com/vmware/go-vcloud-director/v2/govcd" "os" "regexp" + "github.com/vmware/go-vcloud-director/v2/govcd" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -33,215 +34,228 @@ func Resources(nameRegexp string, includeDeprecated bool) (map[string]*schema.Re } var globalDataSourceMap = map[string]*schema.Resource{ - "vcd_org": datasourceVcdOrg(), // 2.5 - "vcd_org_group": datasourceVcdOrgGroup(), // 3.6 - "vcd_org_user": datasourceVcdOrgUser(), // 3.0 - "vcd_org_vdc": datasourceVcdOrgVdc(), // 2.5 - "vcd_catalog": datasourceVcdCatalog(), // 2.5 - "vcd_catalog_media": datasourceVcdCatalogMedia(), // 2.5 - "vcd_catalog_item": datasourceVcdCatalogItem(), // 2.5 - "vcd_edgegateway": datasourceVcdEdgeGateway(), // 2.5 - "vcd_external_network": datasourceVcdExternalNetwork(), // 2.5 - "vcd_external_network_v2": datasourceVcdExternalNetworkV2(), // 3.0 - "vcd_independent_disk": datasourceVcIndependentDisk(), // 2.5 - "vcd_network_routed": datasourceVcdNetworkRouted(), // 2.5 - "vcd_network_direct": datasourceVcdNetworkDirect(), // 2.5 - "vcd_network_isolated": datasourceVcdNetworkIsolated(), // 2.5 - "vcd_vapp": datasourceVcdVApp(), // 2.5 - "vcd_vapp_vm": datasourceVcdVAppVm(), // 2.6 - "vcd_lb_service_monitor": datasourceVcdLbServiceMonitor(), // 2.4 - "vcd_lb_server_pool": datasourceVcdLbServerPool(), // 2.4 - "vcd_lb_app_profile": datasourceVcdLBAppProfile(), // 2.4 - "vcd_lb_app_rule": datasourceVcdLBAppRule(), // 2.4 - "vcd_lb_virtual_server": datasourceVcdLbVirtualServer(), // 2.4 - "vcd_nsxv_dnat": datasourceVcdNsxvDnat(), // 2.5 - "vcd_nsxv_snat": datasourceVcdNsxvSnat(), // 2.5 - "vcd_nsxv_firewall_rule": datasourceVcdNsxvFirewallRule(), // 2.5 - "vcd_nsxv_dhcp_relay": datasourceVcdNsxvDhcpRelay(), // 2.6 - "vcd_nsxv_ip_set": datasourceVcdIpSet(), // 2.6 - "vcd_vapp_network": datasourceVcdVappNetwork(), // 2.7 - "vcd_vapp_org_network": datasourceVcdVappOrgNetwork(), // 2.7 - "vcd_vm_affinity_rule": datasourceVcdVmAffinityRule(), // 2.9 - "vcd_vm_sizing_policy": datasourceVcdVmSizingPolicy(), // 3.0 - "vcd_nsxt_manager": datasourceVcdNsxtManager(), // 3.0 - "vcd_nsxt_tier0_router": datasourceVcdNsxtTier0Router(), // 3.0 - "vcd_portgroup": datasourceVcdPortgroup(), // 3.0 - "vcd_vcenter": datasourceVcdVcenter(), // 3.0 - "vcd_resource_list": datasourceVcdResourceList(), // 3.1 - "vcd_resource_schema": datasourceVcdResourceSchema(), // 3.1 - "vcd_nsxt_edge_cluster": datasourceVcdNsxtEdgeCluster(), // 3.1 - "vcd_nsxt_edgegateway": datasourceVcdNsxtEdgeGateway(), // 3.1 - "vcd_storage_profile": datasourceVcdStorageProfile(), // 3.1 - "vcd_vm": datasourceVcdStandaloneVm(), // 3.2 - "vcd_network_routed_v2": datasourceVcdNetworkRoutedV2(), // 3.2 - "vcd_network_isolated_v2": datasourceVcdNetworkIsolatedV2(), // 3.2 - "vcd_nsxt_network_imported": datasourceVcdNsxtNetworkImported(), // 3.2 - "vcd_nsxt_network_dhcp": datasourceVcdOpenApiDhcp(), // 3.2 - "vcd_right": datasourceVcdRight(), // 3.3 - "vcd_role": datasourceVcdRole(), // 3.3 - "vcd_global_role": datasourceVcdGlobalRole(), // 3.3 - "vcd_rights_bundle": datasourceVcdRightsBundle(), // 3.3 - "vcd_nsxt_ip_set": datasourceVcdNsxtIpSet(), // 3.3 - "vcd_nsxt_security_group": datasourceVcdNsxtSecurityGroup(), // 3.3 - "vcd_nsxt_app_port_profile": datasourceVcdNsxtAppPortProfile(), // 3.3 - "vcd_nsxt_nat_rule": datasourceVcdNsxtNatRule(), // 3.3 - "vcd_nsxt_firewall": datasourceVcdNsxtFirewall(), // 3.3 - "vcd_nsxt_ipsec_vpn_tunnel": datasourceVcdNsxtIpSecVpnTunnel(), // 3.3 - "vcd_nsxt_alb_importable_cloud": datasourceVcdAlbImportableCloud(), // 3.4 - "vcd_nsxt_alb_controller": datasourceVcdAlbController(), // 3.4 - "vcd_nsxt_alb_cloud": datasourceVcdAlbCloud(), // 3.4 - "vcd_nsxt_alb_service_engine_group": datasourceVcdAlbServiceEngineGroup(), // 3.4 - "vcd_nsxt_alb_settings": datasourceVcdAlbSettings(), // 3.5 - "vcd_nsxt_alb_edgegateway_service_engine_group": datasourceVcdAlbEdgeGatewayServiceEngineGroup(), // 3.5 - "vcd_library_certificate": datasourceLibraryCertificate(), // 3.5 - "vcd_nsxt_alb_pool": datasourceVcdAlbPool(), // 3.5 - "vcd_nsxt_alb_virtual_service": datasourceVcdAlbVirtualService(), // 3.5 - "vcd_vdc_group": datasourceVdcGroup(), // 3.5 - "vcd_nsxt_distributed_firewall": datasourceVcdNsxtDistributedFirewall(), // 3.6 - "vcd_nsxt_network_context_profile": datasourceVcdNsxtNetworkContextProfile(), // 3.6 - "vcd_nsxt_route_advertisement": datasourceVcdNsxtRouteAdvertisement(), // 3.7 - "vcd_nsxt_edgegateway_bgp_configuration": datasourceVcdEdgeBgpConfig(), // 3.7 - "vcd_nsxt_edgegateway_bgp_neighbor": datasourceVcdEdgeBgpNeighbor(), // 3.7 - "vcd_nsxt_edgegateway_bgp_ip_prefix_list": datasourceVcdEdgeBgpIpPrefixList(), // 3.7 - "vcd_nsxt_dynamic_security_group": datasourceVcdDynamicSecurityGroup(), // 3.7 - "vcd_org_ldap": datasourceVcdOrgLdap(), // 3.8 - "vcd_vm_placement_policy": datasourceVcdVmPlacementPolicy(), // 3.8 - "vcd_provider_vdc": datasourceVcdProviderVdc(), // 3.8 - "vcd_vm_group": datasourceVcdVmGroup(), // 3.8 - "vcd_catalog_vapp_template": datasourceVcdCatalogVappTemplate(), // 3.8 - "vcd_subscribed_catalog": datasourceVcdSubscribedCatalog(), // 3.8 - "vcd_task": datasourceVcdTask(), // 3.8 - "vcd_nsxv_distributed_firewall": datasourceVcdNsxvDistributedFirewall(), // 3.9 - "vcd_nsxv_application_finder": datasourceVcdNsxvApplicationFinder(), // 3.9 - "vcd_nsxv_application": datasourceVcdNsxvApplication(), // 3.9 - "vcd_nsxv_application_group": datasourceVcdNsxvApplicationGroup(), // 3.9 - "vcd_rde_interface": datasourceVcdRdeInterface(), // 3.9 - "vcd_rde_type": datasourceVcdRdeType(), // 3.9 - "vcd_rde": datasourceVcdRde(), // 3.9 - "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_ip_space_uplink": datasourceVcdIpSpaceUplink(), // 3.10 - "vcd_ip_space_ip_allocation": datasourceVcdIpAllocation(), // 3.10 - "vcd_ip_space_custom_quota": datasourceVcdIpSpaceCustomQuota(), // 3.10 - "vcd_nsxt_edgegateway_dhcp_forwarding": datasourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10 - "vcd_nsxt_edgegateway_dhcpv6": datasourceVcdNsxtEdgegatewayDhcpV6(), // 3.10 - "vcd_org_saml": datasourceVcdOrgSaml(), // 3.10 - "vcd_org_saml_metadata": datasourceVcdOrgSamlMetadata(), // 3.10 - "vcd_nsxt_distributed_firewall_rule": datasourceVcdNsxtDistributedFirewallRule(), // 3.10 - "vcd_nsxt_edgegateway_static_route": datasourceVcdNsxtEdgeGatewayStaticRoute(), // 3.10 - "vcd_resource_pool": datasourceVcdResourcePool(), // 3.10 - "vcd_network_pool": datasourceVcdNetworkPool(), // 3.10 - "vcd_ui_plugin": datasourceVcdUIPlugin(), // 3.10 - "vcd_service_account": datasourceVcdServiceAccount(), // 3.10 - "vcd_rde_interface_behavior": datasourceVcdRdeInterfaceBehavior(), // 3.10 - "vcd_rde_type_behavior": datasourceVcdRdeTypeBehavior(), // 3.10 - "vcd_rde_type_behavior_acl": datasourceVcdRdeTypeBehaviorAccessLevel(), // 3.10 - "vcd_nsxt_edgegateway_l2_vpn_tunnel": datasourceVcdNsxtEdgegatewayL2VpnTunnel(), // 3.11 - "vcd_rde_behavior_invocation": datasourceVcdRdeBehaviorInvocation(), // 3.11 + "vcd_org": datasourceVcdOrg(), // 2.5 + "vcd_org_group": datasourceVcdOrgGroup(), // 3.6 + "vcd_org_user": datasourceVcdOrgUser(), // 3.0 + "vcd_org_vdc": datasourceVcdOrgVdc(), // 2.5 + "vcd_catalog": datasourceVcdCatalog(), // 2.5 + "vcd_catalog_media": datasourceVcdCatalogMedia(), // 2.5 + "vcd_catalog_item": datasourceVcdCatalogItem(), // 2.5 + "vcd_edgegateway": datasourceVcdEdgeGateway(), // 2.5 + "vcd_external_network": datasourceVcdExternalNetwork(), // 2.5 + "vcd_external_network_v2": datasourceVcdExternalNetworkV2(), // 3.0 + "vcd_independent_disk": datasourceVcIndependentDisk(), // 2.5 + "vcd_network_routed": datasourceVcdNetworkRouted(), // 2.5 + "vcd_network_direct": datasourceVcdNetworkDirect(), // 2.5 + "vcd_network_isolated": datasourceVcdNetworkIsolated(), // 2.5 + "vcd_vapp": datasourceVcdVApp(), // 2.5 + "vcd_vapp_vm": datasourceVcdVAppVm(), // 2.6 + "vcd_lb_service_monitor": datasourceVcdLbServiceMonitor(), // 2.4 + "vcd_lb_server_pool": datasourceVcdLbServerPool(), // 2.4 + "vcd_lb_app_profile": datasourceVcdLBAppProfile(), // 2.4 + "vcd_lb_app_rule": datasourceVcdLBAppRule(), // 2.4 + "vcd_lb_virtual_server": datasourceVcdLbVirtualServer(), // 2.4 + "vcd_nsxv_dnat": datasourceVcdNsxvDnat(), // 2.5 + "vcd_nsxv_snat": datasourceVcdNsxvSnat(), // 2.5 + "vcd_nsxv_firewall_rule": datasourceVcdNsxvFirewallRule(), // 2.5 + "vcd_nsxv_dhcp_relay": datasourceVcdNsxvDhcpRelay(), // 2.6 + "vcd_nsxv_ip_set": datasourceVcdIpSet(), // 2.6 + "vcd_vapp_network": datasourceVcdVappNetwork(), // 2.7 + "vcd_vapp_org_network": datasourceVcdVappOrgNetwork(), // 2.7 + "vcd_vm_affinity_rule": datasourceVcdVmAffinityRule(), // 2.9 + "vcd_vm_sizing_policy": datasourceVcdVmSizingPolicy(), // 3.0 + "vcd_nsxt_manager": datasourceVcdNsxtManager(), // 3.0 + "vcd_nsxt_tier0_router": datasourceVcdNsxtTier0Router(), // 3.0 + "vcd_portgroup": datasourceVcdPortgroup(), // 3.0 + "vcd_vcenter": datasourceVcdVcenter(), // 3.0 + "vcd_resource_list": datasourceVcdResourceList(), // 3.1 + "vcd_resource_schema": datasourceVcdResourceSchema(), // 3.1 + "vcd_nsxt_edge_cluster": datasourceVcdNsxtEdgeCluster(), // 3.1 + "vcd_nsxt_edgegateway": datasourceVcdNsxtEdgeGateway(), // 3.1 + "vcd_storage_profile": datasourceVcdStorageProfile(), // 3.1 + "vcd_vm": datasourceVcdStandaloneVm(), // 3.2 + "vcd_network_routed_v2": datasourceVcdNetworkRoutedV2(), // 3.2 + "vcd_network_isolated_v2": datasourceVcdNetworkIsolatedV2(), // 3.2 + "vcd_nsxt_network_imported": datasourceVcdNsxtNetworkImported(), // 3.2 + "vcd_nsxt_network_dhcp": datasourceVcdOpenApiDhcp(), // 3.2 + "vcd_right": datasourceVcdRight(), // 3.3 + "vcd_role": datasourceVcdRole(), // 3.3 + "vcd_global_role": datasourceVcdGlobalRole(), // 3.3 + "vcd_rights_bundle": datasourceVcdRightsBundle(), // 3.3 + "vcd_nsxt_ip_set": datasourceVcdNsxtIpSet(), // 3.3 + "vcd_nsxt_security_group": datasourceVcdNsxtSecurityGroup(), // 3.3 + "vcd_nsxt_app_port_profile": datasourceVcdNsxtAppPortProfile(), // 3.3 + "vcd_nsxt_nat_rule": datasourceVcdNsxtNatRule(), // 3.3 + "vcd_nsxt_firewall": datasourceVcdNsxtFirewall(), // 3.3 + "vcd_nsxt_ipsec_vpn_tunnel": datasourceVcdNsxtIpSecVpnTunnel(), // 3.3 + "vcd_nsxt_alb_importable_cloud": datasourceVcdAlbImportableCloud(), // 3.4 + "vcd_nsxt_alb_controller": datasourceVcdAlbController(), // 3.4 + "vcd_nsxt_alb_cloud": datasourceVcdAlbCloud(), // 3.4 + "vcd_nsxt_alb_service_engine_group": datasourceVcdAlbServiceEngineGroup(), // 3.4 + "vcd_nsxt_alb_settings": datasourceVcdAlbSettings(), // 3.5 + "vcd_nsxt_alb_edgegateway_service_engine_group": datasourceVcdAlbEdgeGatewayServiceEngineGroup(), // 3.5 + "vcd_library_certificate": datasourceLibraryCertificate(), // 3.5 + "vcd_nsxt_alb_pool": datasourceVcdAlbPool(), // 3.5 + "vcd_nsxt_alb_virtual_service": datasourceVcdAlbVirtualService(), // 3.5 + "vcd_vdc_group": datasourceVdcGroup(), // 3.5 + "vcd_nsxt_distributed_firewall": datasourceVcdNsxtDistributedFirewall(), // 3.6 + "vcd_nsxt_network_context_profile": datasourceVcdNsxtNetworkContextProfile(), // 3.6 + "vcd_nsxt_route_advertisement": datasourceVcdNsxtRouteAdvertisement(), // 3.7 + "vcd_nsxt_edgegateway_bgp_configuration": datasourceVcdEdgeBgpConfig(), // 3.7 + "vcd_nsxt_edgegateway_bgp_neighbor": datasourceVcdEdgeBgpNeighbor(), // 3.7 + "vcd_nsxt_edgegateway_bgp_ip_prefix_list": datasourceVcdEdgeBgpIpPrefixList(), // 3.7 + "vcd_nsxt_dynamic_security_group": datasourceVcdDynamicSecurityGroup(), // 3.7 + "vcd_org_ldap": datasourceVcdOrgLdap(), // 3.8 + "vcd_vm_placement_policy": datasourceVcdVmPlacementPolicy(), // 3.8 + "vcd_provider_vdc": datasourceVcdProviderVdc(), // 3.8 + "vcd_vm_group": datasourceVcdVmGroup(), // 3.8 + "vcd_catalog_vapp_template": datasourceVcdCatalogVappTemplate(), // 3.8 + "vcd_subscribed_catalog": datasourceVcdSubscribedCatalog(), // 3.8 + "vcd_task": datasourceVcdTask(), // 3.8 + "vcd_nsxv_distributed_firewall": datasourceVcdNsxvDistributedFirewall(), // 3.9 + "vcd_nsxv_application_finder": datasourceVcdNsxvApplicationFinder(), // 3.9 + "vcd_nsxv_application": datasourceVcdNsxvApplication(), // 3.9 + "vcd_nsxv_application_group": datasourceVcdNsxvApplicationGroup(), // 3.9 + "vcd_rde_interface": datasourceVcdRdeInterface(), // 3.9 + "vcd_rde_type": datasourceVcdRdeType(), // 3.9 + "vcd_rde": datasourceVcdRde(), // 3.9 + "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_ip_space_uplink": datasourceVcdIpSpaceUplink(), // 3.10 + "vcd_ip_space_ip_allocation": datasourceVcdIpAllocation(), // 3.10 + "vcd_ip_space_custom_quota": datasourceVcdIpSpaceCustomQuota(), // 3.10 + "vcd_nsxt_edgegateway_dhcp_forwarding": datasourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10 + "vcd_nsxt_edgegateway_dhcpv6": datasourceVcdNsxtEdgegatewayDhcpV6(), // 3.10 + "vcd_org_saml": datasourceVcdOrgSaml(), // 3.10 + "vcd_org_saml_metadata": datasourceVcdOrgSamlMetadata(), // 3.10 + "vcd_nsxt_distributed_firewall_rule": datasourceVcdNsxtDistributedFirewallRule(), // 3.10 + "vcd_nsxt_edgegateway_static_route": datasourceVcdNsxtEdgeGatewayStaticRoute(), // 3.10 + "vcd_resource_pool": datasourceVcdResourcePool(), // 3.10 + "vcd_network_pool": datasourceVcdNetworkPool(), // 3.10 + "vcd_ui_plugin": datasourceVcdUIPlugin(), // 3.10 + "vcd_service_account": datasourceVcdServiceAccount(), // 3.10 + "vcd_rde_interface_behavior": datasourceVcdRdeInterfaceBehavior(), // 3.10 + "vcd_rde_type_behavior": datasourceVcdRdeTypeBehavior(), // 3.10 + "vcd_rde_type_behavior_acl": datasourceVcdRdeTypeBehaviorAccessLevel(), // 3.10 + "vcd_nsxt_edgegateway_l2_vpn_tunnel": datasourceVcdNsxtEdgegatewayL2VpnTunnel(), // 3.11 + "vcd_rde_behavior_invocation": datasourceVcdRdeBehaviorInvocation(), // 3.11 + "vcd_nsxt_segment_ip_discovery_profile": datasourceVcdNsxtSegmentIpDiscoveryProfile(), // 3.11 + "vcd_nsxt_segment_mac_discovery_profile": datasourceVcdNsxtSegmentMacDiscoveryProfile(), // 3.11 + "vcd_nsxt_segment_spoof_guard_profile": datasourceVcdNsxtSegmentSpoofGuardProfile(), // 3.11 + "vcd_nsxt_segment_qos_profile": datasourceVcdNsxtSegmentQosProfile(), // 3.11 + "vcd_nsxt_segment_security_profile": datasourceVcdNsxtSegmentSecurityProfile(), // 3.11 + "vcd_nsxt_segment_profile_template": datasourceVcdSegmentProfileTemplate(), // 3.11 + "vcd_nsxt_global_default_segment_profile_template": datasourceVcdGlobalDefaultSegmentProfileTemplate(), // 3.11 + "vcd_org_vdc_nsxt_network_profile": datasourceVcdNsxtOrgVdcNetworkProfile(), // 3.11 + "vcd_nsxt_network_segment_profile": datasourceVcdNsxtOrgVdcNetworkSegmentProfileTemplate(), // 3.11 } var globalResourceMap = map[string]*schema.Resource{ - "vcd_network_routed": resourceVcdNetworkRouted(), // 2.0 - "vcd_network_direct": resourceVcdNetworkDirect(), // 2.0 - "vcd_network_isolated": resourceVcdNetworkIsolated(), // 2.0 - "vcd_vapp_network": resourceVcdVappNetwork(), // 2.1 - "vcd_vapp": resourceVcdVApp(), // 1.0 - "vcd_edgegateway": resourceVcdEdgeGateway(), // 2.4 - "vcd_edgegateway_vpn": resourceVcdEdgeGatewayVpn(), // 1.0 - "vcd_edgegateway_settings": resourceVcdEdgeGatewaySettings(), // 3.0 - "vcd_vapp_vm": resourceVcdVAppVm(), // 1.0 - "vcd_org": resourceOrg(), // 2.0 - "vcd_org_vdc": resourceVcdOrgVdc(), // 2.2 - "vcd_org_user": resourceVcdOrgUser(), // 2.4 - "vcd_catalog": resourceVcdCatalog(), // 2.0 - "vcd_catalog_item": resourceVcdCatalogItem(), // 2.0 - "vcd_catalog_media": resourceVcdCatalogMedia(), // 2.0 - "vcd_inserted_media": resourceVcdInsertedMedia(), // 2.1 - "vcd_independent_disk": resourceVcdIndependentDisk(), // 2.1 - "vcd_external_network": resourceVcdExternalNetwork(), // 2.2 - "vcd_lb_service_monitor": resourceVcdLbServiceMonitor(), // 2.4 - "vcd_lb_server_pool": resourceVcdLBServerPool(), // 2.4 - "vcd_lb_app_profile": resourceVcdLBAppProfile(), // 2.4 - "vcd_lb_app_rule": resourceVcdLBAppRule(), // 2.4 - "vcd_lb_virtual_server": resourceVcdLBVirtualServer(), // 2.4 - "vcd_nsxv_dnat": resourceVcdNsxvDnat(), // 2.5 - "vcd_nsxv_snat": resourceVcdNsxvSnat(), // 2.5 - "vcd_nsxv_firewall_rule": resourceVcdNsxvFirewallRule(), // 2.5 - "vcd_nsxv_dhcp_relay": resourceVcdNsxvDhcpRelay(), // 2.6 - "vcd_nsxv_ip_set": resourceVcdIpSet(), // 2.6 - "vcd_vm_internal_disk": resourceVmInternalDisk(), // 2.7 - "vcd_vapp_org_network": resourceVcdVappOrgNetwork(), // 2.7 - "vcd_org_group": resourceVcdOrgGroup(), // 2.9 - "vcd_vapp_firewall_rules": resourceVcdVappFirewallRules(), // 2.9 - "vcd_vapp_nat_rules": resourceVcdVappNetworkNatRules(), // 2.9 - "vcd_vapp_static_routing": resourceVcdVappNetworkStaticRouting(), // 2.9 - "vcd_vm_affinity_rule": resourceVcdVmAffinityRule(), // 2.9 - "vcd_vapp_access_control": resourceVcdAccessControlVapp(), // 3.0 - "vcd_external_network_v2": resourceVcdExternalNetworkV2(), // 3.0 - "vcd_vm_sizing_policy": resourceVcdVmSizingPolicy(), // 3.0 - "vcd_nsxt_edgegateway": resourceVcdNsxtEdgeGateway(), // 3.1 - "vcd_vm": resourceVcdStandaloneVm(), // 3.2 - "vcd_network_routed_v2": resourceVcdNetworkRoutedV2(), // 3.2 - "vcd_network_isolated_v2": resourceVcdNetworkIsolatedV2(), // 3.2 - "vcd_nsxt_network_imported": resourceVcdNsxtNetworkImported(), // 3.2 - "vcd_nsxt_network_dhcp": resourceVcdOpenApiDhcp(), // 3.2 - "vcd_role": resourceVcdRole(), // 3.3 - "vcd_global_role": resourceVcdGlobalRole(), // 3.3 - "vcd_rights_bundle": resourceVcdRightsBundle(), // 3.3 - "vcd_nsxt_ip_set": resourceVcdNsxtIpSet(), // 3.3 - "vcd_nsxt_security_group": resourceVcdSecurityGroup(), // 3.3 - "vcd_nsxt_firewall": resourceVcdNsxtFirewall(), // 3.3 - "vcd_nsxt_app_port_profile": resourceVcdNsxtAppPortProfile(), // 3.3 - "vcd_nsxt_nat_rule": resourceVcdNsxtNatRule(), // 3.3 - "vcd_nsxt_ipsec_vpn_tunnel": resourceVcdNsxtIpSecVpnTunnel(), // 3.3 - "vcd_nsxt_alb_cloud": resourceVcdAlbCloud(), // 3.4 - "vcd_nsxt_alb_controller": resourceVcdAlbController(), // 3.4 - "vcd_nsxt_alb_service_engine_group": resourceVcdAlbServiceEngineGroup(), // 3.4 - "vcd_nsxt_alb_settings": resourceVcdAlbSettings(), // 3.5 - "vcd_nsxt_alb_edgegateway_service_engine_group": resourceVcdAlbEdgeGatewayServiceEngineGroup(), // 3.5 - "vcd_library_certificate": resourceLibraryCertificate(), // 3.5 - "vcd_nsxt_alb_pool": resourceVcdAlbPool(), // 3.5 - "vcd_nsxt_alb_virtual_service": resourceVcdAlbVirtualService(), // 3.5 - "vcd_vdc_group": resourceVdcGroup(), // 3.5 - "vcd_nsxt_distributed_firewall": resourceVcdNsxtDistributedFirewall(), // 3.6 - "vcd_security_tag": resourceVcdSecurityTag(), // 3.7 - "vcd_nsxt_route_advertisement": resourceVcdNsxtRouteAdvertisement(), // 3.7 - "vcd_org_vdc_access_control": resourceVcdOrgVdcAccessControl(), // 3.7 - "vcd_nsxt_dynamic_security_group": resourceVcdDynamicSecurityGroup(), // 3.7 - "vcd_nsxt_edgegateway_bgp_neighbor": resourceVcdEdgeBgpNeighbor(), // 3.7 - "vcd_nsxt_edgegateway_bgp_ip_prefix_list": resourceVcdEdgeBgpIpPrefixList(), // 3.7 - "vcd_nsxt_edgegateway_bgp_configuration": resourceVcdEdgeBgpConfig(), // 3.7 - "vcd_org_ldap": resourceVcdOrgLdap(), // 3.8 - "vcd_vm_placement_policy": resourceVcdVmPlacementPolicy(), // 3.8 - "vcd_catalog_vapp_template": resourceVcdCatalogVappTemplate(), // 3.8 - "vcd_catalog_access_control": resourceVcdCatalogAccessControl(), // 3.8 - "vcd_subscribed_catalog": resourceVcdSubscribedCatalog(), // 3.8 - "vcd_nsxv_distributed_firewall": resourceVcdNsxvDistributedFirewall(), // 3.9 - "vcd_rde_interface": resourceVcdRdeInterface(), // 3.9 - "vcd_rde_type": resourceVcdRdeType(), // 3.9 - "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_ip_space_uplink": resourceVcdIpSpaceUplink(), // 3.10 - "vcd_ip_space_ip_allocation": resourceVcdIpAllocation(), // 3.10 - "vcd_ip_space_custom_quota": resourceVcdIpSpaceCustomQuota(), // 3.10 - "vcd_nsxt_edgegateway_dhcp_forwarding": resourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10 - "vcd_nsxt_edgegateway_dhcpv6": resourceVcdNsxtEdgegatewayDhcpV6(), // 3.10 - "vcd_org_saml": resourceVcdOrgSaml(), // 3.10 - "vcd_nsxt_distributed_firewall_rule": resourceVcdNsxtDistributedFirewallRule(), // 3.10 - "vcd_nsxt_edgegateway_static_route": resourceVcdNsxtEdgeGatewayStaticRoute(), // 3.10 - "vcd_provider_vdc": resourceVcdProviderVdc(), // 3.10 - "vcd_cloned_vapp": resourceVcdClonedVApp(), // 3.10 - "vcd_ui_plugin": resourceVcdUIPlugin(), // 3.10 - "vcd_api_token": resourceVcdApiToken(), // 3.10 - "vcd_service_account": resourceVcdServiceAccount(), // 3.10 - "vcd_rde_interface_behavior": resourceVcdRdeInterfaceBehavior(), // 3.10 - "vcd_rde_type_behavior": resourceVcdRdeTypeBehavior(), // 3.10 - "vcd_rde_type_behavior_acl": resourceVcdRdeTypeBehaviorAccessLevel(), // 3.10 - "vcd_nsxt_edgegateway_l2_vpn_tunnel": resourceVcdNsxtEdgegatewayL2VpnTunnel(), // 3.11 + "vcd_network_routed": resourceVcdNetworkRouted(), // 2.0 + "vcd_network_direct": resourceVcdNetworkDirect(), // 2.0 + "vcd_network_isolated": resourceVcdNetworkIsolated(), // 2.0 + "vcd_vapp_network": resourceVcdVappNetwork(), // 2.1 + "vcd_vapp": resourceVcdVApp(), // 1.0 + "vcd_edgegateway": resourceVcdEdgeGateway(), // 2.4 + "vcd_edgegateway_vpn": resourceVcdEdgeGatewayVpn(), // 1.0 + "vcd_edgegateway_settings": resourceVcdEdgeGatewaySettings(), // 3.0 + "vcd_vapp_vm": resourceVcdVAppVm(), // 1.0 + "vcd_org": resourceOrg(), // 2.0 + "vcd_org_vdc": resourceVcdOrgVdc(), // 2.2 + "vcd_org_user": resourceVcdOrgUser(), // 2.4 + "vcd_catalog": resourceVcdCatalog(), // 2.0 + "vcd_catalog_item": resourceVcdCatalogItem(), // 2.0 + "vcd_catalog_media": resourceVcdCatalogMedia(), // 2.0 + "vcd_inserted_media": resourceVcdInsertedMedia(), // 2.1 + "vcd_independent_disk": resourceVcdIndependentDisk(), // 2.1 + "vcd_external_network": resourceVcdExternalNetwork(), // 2.2 + "vcd_lb_service_monitor": resourceVcdLbServiceMonitor(), // 2.4 + "vcd_lb_server_pool": resourceVcdLBServerPool(), // 2.4 + "vcd_lb_app_profile": resourceVcdLBAppProfile(), // 2.4 + "vcd_lb_app_rule": resourceVcdLBAppRule(), // 2.4 + "vcd_lb_virtual_server": resourceVcdLBVirtualServer(), // 2.4 + "vcd_nsxv_dnat": resourceVcdNsxvDnat(), // 2.5 + "vcd_nsxv_snat": resourceVcdNsxvSnat(), // 2.5 + "vcd_nsxv_firewall_rule": resourceVcdNsxvFirewallRule(), // 2.5 + "vcd_nsxv_dhcp_relay": resourceVcdNsxvDhcpRelay(), // 2.6 + "vcd_nsxv_ip_set": resourceVcdIpSet(), // 2.6 + "vcd_vm_internal_disk": resourceVmInternalDisk(), // 2.7 + "vcd_vapp_org_network": resourceVcdVappOrgNetwork(), // 2.7 + "vcd_org_group": resourceVcdOrgGroup(), // 2.9 + "vcd_vapp_firewall_rules": resourceVcdVappFirewallRules(), // 2.9 + "vcd_vapp_nat_rules": resourceVcdVappNetworkNatRules(), // 2.9 + "vcd_vapp_static_routing": resourceVcdVappNetworkStaticRouting(), // 2.9 + "vcd_vm_affinity_rule": resourceVcdVmAffinityRule(), // 2.9 + "vcd_vapp_access_control": resourceVcdAccessControlVapp(), // 3.0 + "vcd_external_network_v2": resourceVcdExternalNetworkV2(), // 3.0 + "vcd_vm_sizing_policy": resourceVcdVmSizingPolicy(), // 3.0 + "vcd_nsxt_edgegateway": resourceVcdNsxtEdgeGateway(), // 3.1 + "vcd_vm": resourceVcdStandaloneVm(), // 3.2 + "vcd_network_routed_v2": resourceVcdNetworkRoutedV2(), // 3.2 + "vcd_network_isolated_v2": resourceVcdNetworkIsolatedV2(), // 3.2 + "vcd_nsxt_network_imported": resourceVcdNsxtNetworkImported(), // 3.2 + "vcd_nsxt_network_dhcp": resourceVcdOpenApiDhcp(), // 3.2 + "vcd_role": resourceVcdRole(), // 3.3 + "vcd_global_role": resourceVcdGlobalRole(), // 3.3 + "vcd_rights_bundle": resourceVcdRightsBundle(), // 3.3 + "vcd_nsxt_ip_set": resourceVcdNsxtIpSet(), // 3.3 + "vcd_nsxt_security_group": resourceVcdSecurityGroup(), // 3.3 + "vcd_nsxt_firewall": resourceVcdNsxtFirewall(), // 3.3 + "vcd_nsxt_app_port_profile": resourceVcdNsxtAppPortProfile(), // 3.3 + "vcd_nsxt_nat_rule": resourceVcdNsxtNatRule(), // 3.3 + "vcd_nsxt_ipsec_vpn_tunnel": resourceVcdNsxtIpSecVpnTunnel(), // 3.3 + "vcd_nsxt_alb_cloud": resourceVcdAlbCloud(), // 3.4 + "vcd_nsxt_alb_controller": resourceVcdAlbController(), // 3.4 + "vcd_nsxt_alb_service_engine_group": resourceVcdAlbServiceEngineGroup(), // 3.4 + "vcd_nsxt_alb_settings": resourceVcdAlbSettings(), // 3.5 + "vcd_nsxt_alb_edgegateway_service_engine_group": resourceVcdAlbEdgeGatewayServiceEngineGroup(), // 3.5 + "vcd_library_certificate": resourceLibraryCertificate(), // 3.5 + "vcd_nsxt_alb_pool": resourceVcdAlbPool(), // 3.5 + "vcd_nsxt_alb_virtual_service": resourceVcdAlbVirtualService(), // 3.5 + "vcd_vdc_group": resourceVdcGroup(), // 3.5 + "vcd_nsxt_distributed_firewall": resourceVcdNsxtDistributedFirewall(), // 3.6 + "vcd_security_tag": resourceVcdSecurityTag(), // 3.7 + "vcd_nsxt_route_advertisement": resourceVcdNsxtRouteAdvertisement(), // 3.7 + "vcd_org_vdc_access_control": resourceVcdOrgVdcAccessControl(), // 3.7 + "vcd_nsxt_dynamic_security_group": resourceVcdDynamicSecurityGroup(), // 3.7 + "vcd_nsxt_edgegateway_bgp_neighbor": resourceVcdEdgeBgpNeighbor(), // 3.7 + "vcd_nsxt_edgegateway_bgp_ip_prefix_list": resourceVcdEdgeBgpIpPrefixList(), // 3.7 + "vcd_nsxt_edgegateway_bgp_configuration": resourceVcdEdgeBgpConfig(), // 3.7 + "vcd_org_ldap": resourceVcdOrgLdap(), // 3.8 + "vcd_vm_placement_policy": resourceVcdVmPlacementPolicy(), // 3.8 + "vcd_catalog_vapp_template": resourceVcdCatalogVappTemplate(), // 3.8 + "vcd_catalog_access_control": resourceVcdCatalogAccessControl(), // 3.8 + "vcd_subscribed_catalog": resourceVcdSubscribedCatalog(), // 3.8 + "vcd_nsxv_distributed_firewall": resourceVcdNsxvDistributedFirewall(), // 3.9 + "vcd_rde_interface": resourceVcdRdeInterface(), // 3.9 + "vcd_rde_type": resourceVcdRdeType(), // 3.9 + "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_ip_space_uplink": resourceVcdIpSpaceUplink(), // 3.10 + "vcd_ip_space_ip_allocation": resourceVcdIpAllocation(), // 3.10 + "vcd_ip_space_custom_quota": resourceVcdIpSpaceCustomQuota(), // 3.10 + "vcd_nsxt_edgegateway_dhcp_forwarding": resourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10 + "vcd_nsxt_edgegateway_dhcpv6": resourceVcdNsxtEdgegatewayDhcpV6(), // 3.10 + "vcd_org_saml": resourceVcdOrgSaml(), // 3.10 + "vcd_nsxt_distributed_firewall_rule": resourceVcdNsxtDistributedFirewallRule(), // 3.10 + "vcd_nsxt_edgegateway_static_route": resourceVcdNsxtEdgeGatewayStaticRoute(), // 3.10 + "vcd_provider_vdc": resourceVcdProviderVdc(), // 3.10 + "vcd_cloned_vapp": resourceVcdClonedVApp(), // 3.10 + "vcd_ui_plugin": resourceVcdUIPlugin(), // 3.10 + "vcd_api_token": resourceVcdApiToken(), // 3.10 + "vcd_service_account": resourceVcdServiceAccount(), // 3.10 + "vcd_rde_interface_behavior": resourceVcdRdeInterfaceBehavior(), // 3.10 + "vcd_rde_type_behavior": resourceVcdRdeTypeBehavior(), // 3.10 + "vcd_rde_type_behavior_acl": resourceVcdRdeTypeBehaviorAccessLevel(), // 3.10 + "vcd_nsxt_edgegateway_l2_vpn_tunnel": resourceVcdNsxtEdgegatewayL2VpnTunnel(), // 3.11 + "vcd_nsxt_segment_profile_template": resourceVcdSegmentProfileTemplate(), // 3.11 + "vcd_nsxt_global_default_segment_profile_template": resourceVcdGlobalDefaultSegmentProfileTemplate(), // 3.11 + "vcd_org_vdc_nsxt_network_profile": resourceVcdNsxtOrgVdcNetworkProfile(), // 3.11 + "vcd_nsxt_network_segment_profile": resourceVcdNsxtOrgVdcNetworkSegmentProfileTemplate(), // 3.11 } // Provider returns a terraform.ResourceProvider. diff --git a/vcd/remove_leftovers_test.go b/vcd/remove_leftovers_test.go index d517a134d..0da43ab81 100644 --- a/vcd/remove_leftovers_test.go +++ b/vcd/remove_leftovers_test.go @@ -90,7 +90,7 @@ var alsoDelete = entityList{ var isTest = regexp.MustCompile(`^[Tt]est`) // alwaysShow lists the resources that will always be shown -var alwaysShow = []string{"vcd_provider_vdc", "vcd_org", "vcd_catalog", "vcd_org_vdc", "vcd_nsxt_alb_controller"} +var alwaysShow = []string{"vcd_provider_vdc", "vcd_org", "vcd_catalog", "vcd_org_vdc", "vcd_nsxt_alb_controller", "vcd_nsxt_segment_profile_template"} func removeLeftovers(govcdClient *govcd.VCDClient, verbose bool) error { if verbose { @@ -452,6 +452,31 @@ func removeLeftovers(govcdClient *govcd.VCDClient, verbose bool) error { } } + // -------------------------------------------------------------- + // Segment Profile Templates can be used in: + // * Global Default Segment Profiles (Infrastructure resources -> Segment Profile Templates -> Global Defaults) + // * VDC defaults (Cloud Resources -> Organization VDCs -> _any NSX-T vdc_ -> Segment Profile Templates) + // * Org VDC Networks (Org VDC networks do not show ) + // It is best to attempt cleanup at the end, when all the other artifacts that can consume them + // are already removed + // -------------------------------------------------------------- + if govcdClient.Client.IsSysAdmin { + allSpts, err := govcdClient.GetAllSegmentProfileTemplates(nil) + if err != nil { + return fmt.Errorf("error retrieving all Segment Profile Templates: %s", err) + } + for _, spt := range allSpts { + // This will delete all Segment Profile Templates that match the `isTest` regex. + toBeDeleted := shouldDeleteEntity(alsoDelete, doNotDelete, spt.NsxtSegmentProfileTemplate.Name, "vcd_nsxt_segment_profile_template", 0, verbose) + if toBeDeleted { + err = spt.Delete() + if err != nil { + return fmt.Errorf("error deleting Segment Profile Template '%s': %s", spt.NsxtSegmentProfileTemplate.Name, err) + } + } + } + } + return nil } diff --git a/vcd/resource_vcd_nsxt_global_default_segment_profile_template.go b/vcd/resource_vcd_nsxt_global_default_segment_profile_template.go new file mode 100644 index 000000000..93334675f --- /dev/null +++ b/vcd/resource_vcd_nsxt_global_default_segment_profile_template.go @@ -0,0 +1,109 @@ +package vcd + +import ( + "context" + "fmt" + + "github.com/vmware/go-vcloud-director/v2/types/v56" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + globalDefaultSegmentProfileId = "global-default-segment-profile" +) + +func resourceVcdGlobalDefaultSegmentProfileTemplate() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceVcdGlobalDefaultSegmentProfileTemplateCreateUpdate, + ReadContext: resourceDataSourceVcdGlobalDefaultSegmentProfileTemplateRead, + UpdateContext: resourceVcdGlobalDefaultSegmentProfileTemplateCreateUpdate, + DeleteContext: resourceVcdGlobalDefaultSegmentProfileTemplateDelete, + Importer: &schema.ResourceImporter{ + StateContext: resourceVcdGlobalDefaultSegmentProfileTemplateImport, + }, + + Schema: map[string]*schema.Schema{ + "vdc_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Optional: true, + Description: "Global default NSX-T Segment Profile for Org VDC networks", + }, + "vapp_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Optional: true, + Description: "Global default NSX-T Segment Profile for vApp networks", + }, + }, + } +} + +func resourceVcdGlobalDefaultSegmentProfileTemplateCreateUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + globalDefaultSegmentProfileConfig := &types.NsxtGlobalDefaultSegmentProfileTemplate{} + + if d.Get("vapp_networks_default_segment_profile_template_id").(string) != "" { + globalDefaultSegmentProfileConfig.VappNetworkSegmentProfileTemplateRef = &types.OpenApiReference{ID: d.Get("vapp_networks_default_segment_profile_template_id").(string)} + } + + if d.Get("vdc_networks_default_segment_profile_template_id").(string) != "" { + globalDefaultSegmentProfileConfig.VdcNetworkSegmentProfileTemplateRef = &types.OpenApiReference{ID: d.Get("vdc_networks_default_segment_profile_template_id").(string)} + } + + _, err := vcdClient.UpdateGlobalDefaultSegmentProfileTemplates(globalDefaultSegmentProfileConfig) + if err != nil { + return diag.Errorf("error updating Global Default Segment Profile Template configuration: %s", err) + } + + d.SetId(globalDefaultSegmentProfileId) + + return resourceDataSourceVcdGlobalDefaultSegmentProfileTemplateRead(ctx, d, meta) +} + +func resourceDataSourceVcdGlobalDefaultSegmentProfileTemplateRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + defaults, err := vcdClient.GetGlobalDefaultSegmentProfileTemplates() + if err != nil { + return diag.Errorf("error reading Global Default Segment Profile Template configuration: %s", err) + } + + dSet(d, "vdc_networks_default_segment_profile_template_id", "") + if defaults.VdcNetworkSegmentProfileTemplateRef != nil { + dSet(d, "vdc_networks_default_segment_profile_template_id", defaults.VdcNetworkSegmentProfileTemplateRef.ID) + } + + dSet(d, "vapp_networks_default_segment_profile_template_id", "") + if defaults.VappNetworkSegmentProfileTemplateRef != nil { + dSet(d, "vapp_networks_default_segment_profile_template_id", defaults.VappNetworkSegmentProfileTemplateRef.ID) + } + + d.SetId(globalDefaultSegmentProfileId) + + return nil +} + +func resourceVcdGlobalDefaultSegmentProfileTemplateDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + _, err := vcdClient.UpdateGlobalDefaultSegmentProfileTemplates(&types.NsxtGlobalDefaultSegmentProfileTemplate{}) + if err != nil { + return diag.Errorf("error deleting Global Default Segment Profile Template configuration: %s", err) + } + + return nil +} + +func resourceVcdGlobalDefaultSegmentProfileTemplateImport(_ context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + vcdClient := meta.(*VCDClient) + + _, err := vcdClient.GetGlobalDefaultSegmentProfileTemplates() + if err != nil { + return nil, fmt.Errorf("error finding Global Segment Profile Template: %s", err) + } + + d.SetId(globalDefaultSegmentProfileId) + return []*schema.ResourceData{d}, nil +} diff --git a/vcd/resource_vcd_nsxt_network_segment_profile.go b/vcd/resource_vcd_nsxt_network_segment_profile.go new file mode 100644 index 000000000..e2b2f4ca3 --- /dev/null +++ b/vcd/resource_vcd_nsxt_network_segment_profile.go @@ -0,0 +1,273 @@ +package vcd + +import ( + "context" + "fmt" + "strings" + + "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" + "github.com/vmware/go-vcloud-director/v2/types/v56" +) + +func resourceVcdNsxtOrgVdcNetworkSegmentProfileTemplate() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceVcdNsxtOrgVdcNetworkSegmentProfileCreateUpdate, + ReadContext: resourceVcdNsxtOrgVdcNetworkSegmentProfileRead, + UpdateContext: resourceVcdNsxtOrgVdcNetworkSegmentProfileCreateUpdate, + DeleteContext: resourceVcdNsxtOrgVdcNetworkSegmentProfileDelete, + Importer: &schema.ResourceImporter{ + StateContext: resourceVcdNsxtOrgVdcNetworkSegmentProfileImport, + }, + + 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 will have the segment profile", + }, + // One can set either Segment Profile Template (which is composed of multiple Segment Profiles), or individual Segment Profiles + "segment_profile_template_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment Profile Template ID", + ConflictsWith: []string{"ip_discovery_profile_id", "mac_discovery_profile_id", "spoof_guard_profile_id", "qos_profile_id", "segment_security_profile_id"}, + }, + "segment_profile_template_name": { + Type: schema.TypeString, + Computed: true, + Description: "Segment Profile Template Name", + }, + "ip_discovery_profile_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "NSX-T IP Discovery Profile", + ConflictsWith: []string{"segment_profile_template_id"}, + }, + "mac_discovery_profile_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "NSX-T Mac Discovery Profile", + ConflictsWith: []string{"segment_profile_template_id"}, + }, + "spoof_guard_profile_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "NSX-T Spoof Guard Profile", + ConflictsWith: []string{"segment_profile_template_id"}, + }, + "qos_profile_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "NSX-T QoS Profile", + ConflictsWith: []string{"segment_profile_template_id"}, + }, + "segment_security_profile_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "NSX-T Segment Security Profile", + ConflictsWith: []string{"segment_profile_template_id"}, + }, + }, + } +} + +func resourceVcdNsxtOrgVdcNetworkSegmentProfileCreateUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + vcdClient.lockParentOrgNetwork(d) + defer vcdClient.unLockParentOrgNetwork(d) + + org, err := vcdClient.GetOrgFromResource(d) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration] error retrieving Org: %s", err) + } + + orgNetworkId := d.Get("org_network_id").(string) + orgVdcNet, err := org.GetOpenApiOrgVdcNetworkById(orgNetworkId) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration] error retrieving Org VDC network with ID '%s': %s", orgNetworkId, err) + } + + if !orgVdcNet.IsNsxt() { + return diag.Errorf("[Org VDC Network Segment Profile configuration] only NSX-T Org VDC networks support Segment Profiles") + } + + ipDiscoveryProfileId := d.Get("ip_discovery_profile_id").(string) + macDiscoveryProfileId := d.Get("mac_discovery_profile_id").(string) + spoofGuardProfileId := d.Get("spoof_guard_profile_id").(string) + qosProfileId := d.Get("qos_profile_id").(string) + segmentSecurityProfileId := d.Get("segment_security_profile_id").(string) + + segmentProfileTemplateId := d.Get("segment_profile_template_id").(string) + + switch { + // Setting `segment_profile_template_id` requires modifying Org VDC Network structure. + // It can only be set (PUT/POST) using Org VDC network structure, but cannot be read (GET). + // To read its value one must use orgVdcNet.GetSegmentProfile() function. + case segmentProfileTemplateId != "": + orgVdcNet.OpenApiOrgVdcNetwork.SegmentProfileTemplate = &types.OpenApiReference{ID: segmentProfileTemplateId} + _, err = orgVdcNet.Update(orgVdcNet.OpenApiOrgVdcNetwork) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration] error setting Segment Profile Template for Org VDC Network: %s", err) + } + case ipDiscoveryProfileId != "" || macDiscoveryProfileId != "" || spoofGuardProfileId != "" || qosProfileId != "" || segmentSecurityProfileId != "": + // Individual segment profiles should be applied using a dedicated Segment Profile orgVdcNet.UpdateSegmentProfile + segmentProfileConfig := &types.OrgVdcNetworkSegmentProfiles{ + IPDiscoveryProfile: &types.Reference{ID: ipDiscoveryProfileId}, + MacDiscoveryProfile: &types.Reference{ID: macDiscoveryProfileId}, + SpoofGuardProfile: &types.Reference{ID: spoofGuardProfileId}, + QosProfile: &types.Reference{ID: qosProfileId}, + SegmentSecurityProfile: &types.Reference{ID: segmentSecurityProfileId}, + } + _, err = orgVdcNet.UpdateSegmentProfile(segmentProfileConfig) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration] error configuring Segment Profile for Org VDC Network: %s", err) + } + default: + return diag.Errorf("[Org VDC Network Segment Profile configuration] invalid configuration provided") + } + + d.SetId(orgVdcNet.OpenApiOrgVdcNetwork.ID) + + return resourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx, d, meta) +} + +func resourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return resourceDataSourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx, d, meta, "resource") +} + +func resourceDataSourceVcdNsxtOrgVdcNetworkSegmentProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}, origin string) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + org, err := vcdClient.GetOrgFromResource(d) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration read] error retrieving Org: %s", err) + } + + orgNetworkId := d.Get("org_network_id").(string) + orgVdcNet, err := org.GetOpenApiOrgVdcNetworkById(orgNetworkId) + if err != nil { + if origin == "resource" && govcd.ContainsNotFound(err) { + d.SetId("") + return nil + } + return diag.Errorf("[Org VDC Network Segment Profile configuration read] error retrieving Org VDC network with ID '%s': %s", orgNetworkId, err) + } + + segmentProfileConfig, err := orgVdcNet.GetSegmentProfile() + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration read] error retrieving Segment Profile configuration for Org VDC Network: %s", err) + } + + dSet(d, "segment_profile_template_name", "") + dSet(d, "segment_profile_template_id", "") + if segmentProfileConfig.SegmentProfileTemplate != nil && segmentProfileConfig.SegmentProfileTemplate.TemplateRef != nil { + dSet(d, "segment_profile_template_id", segmentProfileConfig.SegmentProfileTemplate.TemplateRef.ID) + dSet(d, "segment_profile_template_name", segmentProfileConfig.SegmentProfileTemplate.TemplateRef.Name) + } + + dSet(d, "ip_discovery_profile_id", "") + if segmentProfileConfig.IPDiscoveryProfile != nil { + dSet(d, "ip_discovery_profile_id", segmentProfileConfig.IPDiscoveryProfile.ID) + } + + dSet(d, "mac_discovery_profile_id", "") + if segmentProfileConfig.MacDiscoveryProfile != nil { + dSet(d, "mac_discovery_profile_id", segmentProfileConfig.MacDiscoveryProfile.ID) + } + + dSet(d, "spoof_guard_profile_id", "") + if segmentProfileConfig.SpoofGuardProfile != nil { + dSet(d, "spoof_guard_profile_id", segmentProfileConfig.SpoofGuardProfile.ID) + } + + dSet(d, "qos_profile_id", "") + if segmentProfileConfig.QosProfile != nil { + dSet(d, "qos_profile_id", segmentProfileConfig.QosProfile.ID) + } + + dSet(d, "segment_security_profile_id", "") + if segmentProfileConfig.SegmentSecurityProfile != nil { + dSet(d, "segment_security_profile_id", segmentProfileConfig.SegmentSecurityProfile.ID) + } + + d.SetId(orgVdcNet.OpenApiOrgVdcNetwork.ID) + + return nil +} + +func resourceVcdNsxtOrgVdcNetworkSegmentProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + vcdClient.lockParentOrgNetwork(d) + defer vcdClient.unLockParentOrgNetwork(d) + + org, err := vcdClient.GetOrgFromResource(d) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration delete] error retrieving Org: %s", err) + } + + orgNetworkId := d.Get("org_network_id").(string) + + orgVdcNet, err := org.GetOpenApiOrgVdcNetworkById(orgNetworkId) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration delete] error retrieving Org VDC network with ID '%s': %s", orgNetworkId, err) + } + + // Attempt to remove Segment Profile Template using main network structure (it is the only way, if it is set) + if orgVdcNet.OpenApiOrgVdcNetwork != nil && orgVdcNet.OpenApiOrgVdcNetwork.SegmentProfileTemplate != nil { + orgVdcNet.OpenApiOrgVdcNetwork.SegmentProfileTemplate = &types.OpenApiReference{} + _, err := orgVdcNet.Update(orgVdcNet.OpenApiOrgVdcNetwork) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration delete] error reseting Segment Profile Template ID for Org VDC Network: %s", err) + } + } + + // Attempt to cleanup any custom segment profiles + _, err = orgVdcNet.UpdateSegmentProfile(&types.OrgVdcNetworkSegmentProfiles{}) + if err != nil { + return diag.Errorf("[Org VDC Network Segment Profile configuration delete] error reseting Segment Profile: %s", err) + } + + return nil +} + +func resourceVcdNsxtOrgVdcNetworkSegmentProfileImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + resourceURI := strings.Split(d.Id(), ImportSeparator) + if len(resourceURI) != 3 { + return nil, fmt.Errorf("resource name must be specified as org-name.vdc-org-vdc-group-name.org_network_name") + } + orgName, vdcOrVdcGroupName, orgVdcNetworkName := resourceURI[0], resourceURI[1], resourceURI[2] + + vcdClient := meta.(*VCDClient) + vdcOrVdcGroup, err := lookupVdcOrVdcGroup(vcdClient, orgName, vdcOrVdcGroupName) + if err != nil { + return nil, err + } + + if !vdcOrVdcGroup.IsNsxt() { + return nil, fmt.Errorf("[Org VDC Network Segment Profile configuration import] Segment Profile configuration is only supported for NSX-T networks: %s", err) + } + + orgVdcNet, err := vdcOrVdcGroup.GetOpenApiOrgVdcNetworkByName(orgVdcNetworkName) + if err != nil { + return nil, fmt.Errorf("[Org VDC Network Segment Profile configuration import] error retrieving Org VDC network with name '%s': %s", orgVdcNetworkName, err) + } + + dSet(d, "org", orgName) + dSet(d, "org_network_id", orgVdcNet.OpenApiOrgVdcNetwork.ID) + d.SetId(orgVdcNet.OpenApiOrgVdcNetwork.ID) + + return []*schema.ResourceData{d}, nil +} diff --git a/vcd/resource_vcd_nsxt_network_segment_profile_test.go b/vcd/resource_vcd_nsxt_network_segment_profile_test.go new file mode 100644 index 000000000..c5483c83e --- /dev/null +++ b/vcd/resource_vcd_nsxt_network_segment_profile_test.go @@ -0,0 +1,561 @@ +//go:build nsxt || ALL || functional + +package vcd + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccVcdNsxtNetworkSegmentProfileCustom(t *testing.T) { + preTestChecks(t) + skipIfNotSysAdmin(t) + + // String map to fill the template + var params = StringMap{ + "TestName": t.Name(), + "Org": testConfig.VCD.Org, + "NsxtVdc": testConfig.Nsxt.Vdc, + "EdgeGw": testConfig.Nsxt.EdgeGateway, + "NsxtManager": testConfig.Nsxt.Manager, + "IpDiscoveryProfileName": testConfig.Nsxt.IpDiscoveryProfile, + "MacDiscoveryProfileName": testConfig.Nsxt.MacDiscoveryProfile, + "QosProfileName": testConfig.Nsxt.QosProfile, + "SpoofGuardProfileName": testConfig.Nsxt.SpoofGuardProfile, + "SegmentSecurityProfileName": testConfig.Nsxt.SegmentSecurityProfile, + + "Tags": "nsxt ", + } + + configText1 := templateFill(testAccVcdNsxtNetworkSegmentProfileCustom, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 1: %s", configText1) + + params["FuncName"] = t.Name() + "step2" + configText2DS := templateFill(testAccVcdNsxtNetworkSegmentProfileCustomDS, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 2: %s", configText2DS) + + params["FuncName"] = t.Name() + "step4" + configText4 := templateFill(testAccVcdNsxtNetworkSegmentProfileCustomUpdate, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 4: %s", configText4) + + if vcdShortTest { + t.Skip(acceptanceTestsSkipped) + return + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: configText1, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof", "id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_ip_discovery_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "ip_discovery_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_mac_discovery_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "mac_discovery_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_spoof_guard_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "spoof_guard_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_qos_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "qos_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_security_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "segment_security_profile_id"), + ), + }, + { + ResourceName: "vcd_nsxt_network_segment_profile.custom-prof", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: importStateIdOrgNsxtVdcObject(t.Name() + "-routed"), + }, + { + Config: configText2DS, + Check: resource.ComposeAggregateTestCheckFunc( + resourceFieldsEqual("data.vcd_nsxt_network_segment_profile.custom-prof", "vcd_nsxt_network_segment_profile.custom-prof", nil), + ), + }, + { + Config: configText4, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof", "id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_ip_discovery_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "ip_discovery_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_mac_discovery_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "mac_discovery_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_spoof_guard_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "spoof_guard_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_qos_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "qos_profile_id"), + resource.TestCheckResourceAttrPair("data.vcd_nsxt_segment_security_profile.first", "id", "vcd_nsxt_network_segment_profile.custom-prof", "segment_security_profile_id"), + ), + }, + }, + }) + postTestChecks(t) +} + +const testAccVcdNsxtNetworkSegmentProfileCustom = ` +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "{{.Org}}" + name = "{{.EdgeGw}}" +} + +resource "vcd_network_routed_v2" "net1" { + org = "{{.Org}}" + name = "{{.TestName}}-routed" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} +` + +const testAccVcdNsxtNetworkSegmentProfileCustomDS = testAccVcdNsxtNetworkSegmentProfileCustom + ` +data "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + depends_on = [vcd_nsxt_network_segment_profile.custom-prof] +} +` + +const testAccVcdNsxtNetworkSegmentProfileCustomUpdate = ` +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "{{.Org}}" + name = "{{.EdgeGw}}" +} + +resource "vcd_network_routed_v2" "net1" { + org = "{{.Org}}" + name = "{{.TestName}}-routed" + description = "{{.TestName}}-description" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} +` + +func TestAccVcdNsxtNetworkSegmentProfileTemplate(t *testing.T) { + preTestChecks(t) + skipIfNotSysAdmin(t) + + // String map to fill the template + var params = StringMap{ + "TestName": t.Name(), + "Org": testConfig.VCD.Org, + "NsxtVdc": testConfig.Nsxt.Vdc, + "EdgeGw": testConfig.Nsxt.EdgeGateway, + "NsxtImportSegment": testConfig.Nsxt.NsxtImportSegment, + "NsxtManager": testConfig.Nsxt.Manager, + "IpDiscoveryProfileName": testConfig.Nsxt.IpDiscoveryProfile, + "MacDiscoveryProfileName": testConfig.Nsxt.MacDiscoveryProfile, + "QosProfileName": testConfig.Nsxt.QosProfile, + "SpoofGuardProfileName": testConfig.Nsxt.SpoofGuardProfile, + "SegmentSecurityProfileName": testConfig.Nsxt.SegmentSecurityProfile, + + "Tags": "nsxt ", + } + + configText1 := templateFill(testAccVcdNsxtNetworkSegmentProfileTemplateStep1, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 1: %s", configText1) + + params["FuncName"] = t.Name() + "step2" + configText2DS := templateFill(testAccVcdNsxtNetworkSegmentProfileTemplateDS, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 2: %s", configText2DS) + + params["FuncName"] = t.Name() + "step4" + configText4 := templateFill(testAccVcdNsxtNetworkSegmentProfileTemplateStep2, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 4: %s", configText4) + + if vcdShortTest { + t.Skip(acceptanceTestsSkipped) + return + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: configText1, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("vcd_nsxt_segment_profile_template.complete", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-routed", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-isolated", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-imported", "id"), + ), + }, + { + ResourceName: "vcd_nsxt_network_segment_profile.custom-prof-routed", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: importStateIdOrgNsxtVdcObject(t.Name() + "-routed"), + }, + { + Config: configText2DS, + Check: resource.ComposeAggregateTestCheckFunc( + resourceFieldsEqual("data.vcd_nsxt_network_segment_profile.custom-prof-routed", "vcd_nsxt_network_segment_profile.custom-prof-routed", nil), + ), + }, + { + // This step checks that updating Org VDC network does not compromise its Segment Profile configuration + // after updating Org VDC networks + Config: configText4, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("vcd_nsxt_segment_profile_template.complete", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-routed", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-isolated", "id"), + resource.TestCheckResourceAttrSet("vcd_nsxt_network_segment_profile.custom-prof-imported", "id"), + ), + }, + }, + }) + postTestChecks(t) +} + +const testAccVcdNsxtNetworkSegmentProfileTemplateStep1 = ` +data "vcd_org_vdc" "nsxt" { + org = "{{.Org}}" + name = "{{.NsxtVdc}}" +} + +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +resource "vcd_nsxt_segment_profile_template" "complete" { + name = "{{.TestName}}-complete" + description = "description" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "{{.Org}}" + name = "{{.EdgeGw}}" +} + +resource "vcd_network_routed_v2" "net1" { + org = "{{.Org}}" + name = "{{.TestName}}-routed" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-routed" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} + +resource "vcd_network_isolated_v2" "nsxt-backed" { + org = "{{.Org}}" + owner_id = data.vcd_org_vdc.nsxt.id + + name = "{{.TestName}}-isolated" + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } + + static_ip_pool { + start_address = "1.1.1.100" + end_address = "1.1.1.103" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-isolated" { + org = "{{.Org}}" + org_network_id = vcd_network_isolated_v2.nsxt-backed.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} + +resource "vcd_nsxt_network_imported" "net1" { + org = "{{.Org}}" + owner_id = data.vcd_org_vdc.nsxt.id + name = "{{.TestName}}-imported" + + nsxt_logical_switch_name = "{{.NsxtImportSegment}}" + + gateway = "8.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "8.1.1.10" + end_address = "8.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-imported" { + org = "{{.Org}}" + org_network_id = vcd_nsxt_network_imported.net1.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} +` + +const testAccVcdNsxtNetworkSegmentProfileTemplateDS = testAccVcdNsxtNetworkSegmentProfileTemplateStep1 + ` +data "vcd_nsxt_network_segment_profile" "custom-prof-routed" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + depends_on = [vcd_nsxt_network_segment_profile.custom-prof-routed] +} +` + +const testAccVcdNsxtNetworkSegmentProfileTemplateStep2 = ` +data "vcd_org_vdc" "nsxt" { + org = "{{.Org}}" + name = "{{.NsxtVdc}}" +} + +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +resource "vcd_nsxt_segment_profile_template" "complete" { + name = "{{.TestName}}-complete" + description = "description" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "{{.Org}}" + name = "{{.EdgeGw}}" +} + +resource "vcd_network_routed_v2" "net1" { + org = "{{.Org}}" + name = "{{.TestName}}-routed" + description = "{{.TestName}}-added-description" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } + + static_ip_pool { + start_address = "1.1.1.40" + end_address = "1.1.1.50" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-routed" { + org = "{{.Org}}" + org_network_id = vcd_network_routed_v2.net1.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} + +resource "vcd_network_isolated_v2" "nsxt-backed" { + org = "{{.Org}}" + owner_id = data.vcd_org_vdc.nsxt.id + + name = "{{.TestName}}-isolated" + description = "My isolated Org VDC network backed by NSX-T" + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } + +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-isolated" { + org = "{{.Org}}" + org_network_id = vcd_network_isolated_v2.nsxt-backed.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} + +resource "vcd_nsxt_network_imported" "net1" { + org = "{{.Org}}" + owner_id = data.vcd_org_vdc.nsxt.id + name = "{{.TestName}}-imported" + description = "{{.TestName}}-imported" + + nsxt_logical_switch_name = "{{.NsxtImportSegment}}" + + gateway = "8.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "8.1.1.10" + end_address = "8.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof-imported" { + org = "{{.Org}}" + org_network_id = vcd_nsxt_network_imported.net1.id + + segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} +` diff --git a/vcd/resource_vcd_nsxt_segment_profile_template.go b/vcd/resource_vcd_nsxt_segment_profile_template.go new file mode 100644 index 000000000..8667a4e47 --- /dev/null +++ b/vcd/resource_vcd_nsxt_segment_profile_template.go @@ -0,0 +1,198 @@ +package vcd + +import ( + "context" + "fmt" + + "github.com/vmware/go-vcloud-director/v2/govcd" + + "github.com/vmware/go-vcloud-director/v2/types/v56" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceVcdSegmentProfileTemplate() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceVcdSegmentProfileTemplateCreate, + ReadContext: resourceVcdSegmentProfileTemplateRead, + UpdateContext: resourceVcdSegmentProfileTemplateUpdate, + DeleteContext: resourceVcdSegmentProfileTemplateDelete, + Importer: &schema.ResourceImporter{ + StateContext: resourceVcdSegmentProfileTemplateImport, + }, + + Schema: map[string]*schema.Schema{ + "nsxt_manager_id": { + Type: schema.TypeString, + Required: true, + Description: "NSX-T Manager ID", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of Segment Profile Template", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of Segment Profile Template", + }, + "ip_discovery_profile_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment IP Discovery Profile ID", + }, + "mac_discovery_profile_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment MAC Discovery Profile ID", + }, + "spoof_guard_profile_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment Spoof Guard Profile ID", + }, + "qos_profile_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment QoS Profile ID", + }, + "segment_security_profile_id": { + Type: schema.TypeString, + Optional: true, + Description: "Segment Security Profile ID", + }, + }, + } +} + +func resourceVcdSegmentProfileTemplateCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + segmentProfileTemplateCfg := getNsxtSegmentProfileTemplateType(d) + createdSegmentProfileTemplate, err := vcdClient.CreateSegmentProfileTemplate(segmentProfileTemplateCfg) + if err != nil { + return diag.Errorf("error creating NSX-T Segment Profile Template '%s': %s", segmentProfileTemplateCfg.Name, err) + } + + d.SetId(createdSegmentProfileTemplate.NsxtSegmentProfileTemplate.ID) + + return resourceVcdSegmentProfileTemplateRead(ctx, d, meta) +} + +func resourceVcdSegmentProfileTemplateUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + spt, err := vcdClient.GetSegmentProfileTemplateById(d.Id()) + if err != nil { + return diag.Errorf("unable to find NSX-T Segment Profile Template: %s", err) + } + + updateSegmentProfileTemplateConfig := getNsxtSegmentProfileTemplateType(d) + updateSegmentProfileTemplateConfig.ID = d.Id() + _, err = spt.Update(updateSegmentProfileTemplateConfig) + if err != nil { + return diag.Errorf("error updating NSX-T Segment Profile Template: %s", err) + } + + return resourceVcdSegmentProfileTemplateRead(ctx, d, meta) +} + +func resourceVcdSegmentProfileTemplateRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + spt, err := vcdClient.GetSegmentProfileTemplateById(d.Id()) + if err != nil { + if govcd.ContainsNotFound(err) { + d.SetId("") + return nil + } + return diag.Errorf("unable to find NSX-T Segment Profile Template: %s", err) + } + + setNsxtSegmentProfileTemplateData(d, spt.NsxtSegmentProfileTemplate) + + return nil +} + +func resourceVcdSegmentProfileTemplateDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + spt, err := vcdClient.GetSegmentProfileTemplateById(d.Id()) + if err != nil { + return diag.Errorf("unable to find NSX-T Segment Profile Template: %s", err) + } + + err = spt.Delete() + if err != nil { + return diag.Errorf("error deleting NSX-T Segment Profile Template: %s", err) + } + + return nil +} + +func resourceVcdSegmentProfileTemplateImport(_ context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + vcdClient := meta.(*VCDClient) + + resourceURI := d.Id() + spt, err := vcdClient.GetSegmentProfileTemplateByName(resourceURI) + if err != nil { + return nil, fmt.Errorf("error finding NSX-T Segment Profile Template with Name '%s': %s", d.Id(), err) + } + + d.SetId(spt.NsxtSegmentProfileTemplate.ID) + return []*schema.ResourceData{d}, nil +} + +func getNsxtSegmentProfileTemplateType(d *schema.ResourceData) *types.NsxtSegmentProfileTemplate { + + config := &types.NsxtSegmentProfileTemplate{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + IPDiscoveryProfile: &types.Reference{ID: d.Get("ip_discovery_profile_id").(string)}, + MacDiscoveryProfile: &types.Reference{ID: d.Get("mac_discovery_profile_id").(string)}, + QosProfile: &types.Reference{ID: d.Get("qos_profile_id").(string)}, + SegmentSecurityProfile: &types.Reference{ID: d.Get("segment_security_profile_id").(string)}, + SpoofGuardProfile: &types.Reference{ID: d.Get("spoof_guard_profile_id").(string)}, + SourceNsxTManagerRef: &types.OpenApiReference{ID: d.Get("nsxt_manager_id").(string)}, + } + + return config +} + +func setNsxtSegmentProfileTemplateData(d *schema.ResourceData, config *types.NsxtSegmentProfileTemplate) { + dSet(d, "name", config.Name) + dSet(d, "description", config.Description) + + dSet(d, "nsxt_manager_id", "") + if config.SourceNsxTManagerRef != nil { + dSet(d, "nsxt_manager_id", config.SourceNsxTManagerRef.ID) + } + + dSet(d, "ip_discovery_profile_id", "") + if config.IPDiscoveryProfile != nil { + dSet(d, "ip_discovery_profile_id", config.IPDiscoveryProfile.ID) + } + + dSet(d, "mac_discovery_profile_id", "") + if config.MacDiscoveryProfile != nil { + dSet(d, "mac_discovery_profile_id", config.MacDiscoveryProfile.ID) + } + + dSet(d, "qos_profile_id", "") + if config.QosProfile != nil { + dSet(d, "qos_profile_id", config.QosProfile.ID) + } + + dSet(d, "segment_security_profile_id", "") + if config.SegmentSecurityProfile != nil { + dSet(d, "segment_security_profile_id", config.SegmentSecurityProfile.ID) + } + + dSet(d, "spoof_guard_profile_id", "") + if config.SpoofGuardProfile != nil { + dSet(d, "spoof_guard_profile_id", config.SpoofGuardProfile.ID) + } + +} diff --git a/vcd/resource_vcd_nsxt_segment_profile_template_test.go b/vcd/resource_vcd_nsxt_segment_profile_template_test.go new file mode 100644 index 000000000..40c313737 --- /dev/null +++ b/vcd/resource_vcd_nsxt_segment_profile_template_test.go @@ -0,0 +1,260 @@ +//go:build nsxt || ALL || functional + +package vcd + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/vmware/go-vcloud-director/v2/govcd" +) + +func TestAccVcdNsxtSegmentProfileTemplate(t *testing.T) { + preTestChecks(t) + skipIfNotSysAdmin(t) + + // String map to fill the template + var params = StringMap{ + "TestName": t.Name(), + "NsxtManager": testConfig.Nsxt.Manager, + "IpDiscoveryProfileName": testConfig.Nsxt.IpDiscoveryProfile, + "MacDiscoveryProfileName": testConfig.Nsxt.MacDiscoveryProfile, + "QosProfileName": testConfig.Nsxt.QosProfile, + "SpoofGuardProfileName": testConfig.Nsxt.SpoofGuardProfile, + "SegmentSecurityProfileName": testConfig.Nsxt.SegmentSecurityProfile, + + "Tags": "nsxt ", + } + + configText1 := templateFill(testAccVcdNsxtSegmentProfileTemplate, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 1: %s", configText1) + + params["FuncName"] = t.Name() + "step2" + configText2DS := templateFill(testAccVcdNsxtSegmentProfileTemplateDS, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 2: %s", configText2DS) + + params["FuncName"] = t.Name() + "step3" + configText3 := templateFill(testAccVcdNsxtSegmentProfileTemplateGlobalDefault, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 3: %s", configText3) + + params["FuncName"] = t.Name() + "step4" + configText4DS := templateFill(testAccVcdNsxtSegmentProfileTemplateGlobalDefaultDS, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 4: %s", configText4DS) + + params["FuncName"] = t.Name() + "step7" + configText7 := templateFill(testAccVcdNsxtSegmentProfileTemplateGlobalDefaultNoValues, params) + debugPrintf("#[DEBUG] CONFIGURATION for step 7: %s", configText7) + + if vcdShortTest { + t.Skip(acceptanceTestsSkipped) + return + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: testAccProviders, + CheckDestroy: resource.ComposeAggregateTestCheckFunc( + testAccCheckVcdSegmentProfileTemplateDestroy("vcd_nsxt_segment_profile_template.empty"), + testAccCheckVcdSegmentProfileTemplateDestroy("vcd_nsxt_segment_profile_template.complete"), + testAccCheckVcdSegmentProfileTemplateDestroy("vcd_nsxt_segment_profile_template.half-complete"), + ), + Steps: []resource.TestStep{ + { + Config: configText1, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "name", t.Name()+"-empty"), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "description", "description"), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "ip_discovery_profile_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "mac_discovery_profile_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "spoof_guard_profile_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "qos_profile_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.empty", "segment_security_profile_id", ""), + + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.complete", "name", t.Name()+"-complete"), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.complete", "ip_discovery_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.complete", "mac_discovery_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.complete", "spoof_guard_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.complete", "qos_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.complete", "segment_security_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "name", t.Name()+"-half-complete"), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "description", ""), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "ip_discovery_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "mac_discovery_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestMatchResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "spoof_guard_profile_id", regexp.MustCompile(`[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$`)), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "qos_profile_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_segment_profile_template.half-complete", "segment_security_profile_id", ""), + ), + }, + { + ResourceName: "vcd_nsxt_segment_profile_template.complete", + ImportState: true, + ImportStateVerify: true, + ImportStateId: t.Name() + "-complete", + }, + { + Config: configText2DS, + Check: resource.ComposeAggregateTestCheckFunc( + resourceFieldsEqual("data.vcd_nsxt_segment_profile_template.empty", "vcd_nsxt_segment_profile_template.empty", nil), + resourceFieldsEqual("data.vcd_nsxt_segment_profile_template.half-complete", "vcd_nsxt_segment_profile_template.half-complete", nil), + resourceFieldsEqual("data.vcd_nsxt_segment_profile_template.complete", "vcd_nsxt_segment_profile_template.complete", nil), + ), + }, + { + Config: configText3, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("vcd_nsxt_global_default_segment_profile_template.singleton", "id", globalDefaultSegmentProfileId), + ), + }, + { + Config: configText4DS, + Check: resource.ComposeAggregateTestCheckFunc( + resourceFieldsEqual("data.vcd_nsxt_global_default_segment_profile_template.singleton", "vcd_nsxt_global_default_segment_profile_template.singleton", nil), + ), + }, + { + ResourceName: "vcd_nsxt_global_default_segment_profile_template.singleton", + ImportState: true, + ImportStateVerify: true, + ImportStateId: "", // It does not need a value for ID as it is global VCD configuration + }, + { + ResourceName: "vcd_nsxt_global_default_segment_profile_template.singleton", + ImportState: true, + ImportStateVerify: true, + ImportStateId: "dummy", // Attempt to perform import with a dummy ID + }, + { + Config: configText7, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("vcd_nsxt_global_default_segment_profile_template.singleton", "vdc_networks_default_segment_profile_template_id", ""), + resource.TestCheckResourceAttr("vcd_nsxt_global_default_segment_profile_template.singleton", "vapp_networks_default_segment_profile_template_id", ""), + ), + }, + }, + }) + postTestChecks(t) +} + +const testAccVcdNsxtSegmentProfileTemplate = ` +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +resource "vcd_nsxt_segment_profile_template" "empty" { + name = "{{.TestName}}-empty" + description = "description" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +resource "vcd_nsxt_segment_profile_template" "complete" { + name = "{{.TestName}}-complete" + description = "description" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} + +resource "vcd_nsxt_segment_profile_template" "half-complete" { + name = "{{.TestName}}-half-complete" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +` + +const testAccVcdNsxtSegmentProfileTemplateDS = testAccVcdNsxtSegmentProfileTemplate + ` +data "vcd_nsxt_segment_profile_template" "empty" { + name = vcd_nsxt_segment_profile_template.empty.name + + depends_on = [vcd_nsxt_segment_profile_template.empty] +} + +data "vcd_nsxt_segment_profile_template" "half-complete" { + name = vcd_nsxt_segment_profile_template.half-complete.name + + depends_on = [vcd_nsxt_segment_profile_template.half-complete] +} + +data "vcd_nsxt_segment_profile_template" "complete" { + name = vcd_nsxt_segment_profile_template.complete.name + + depends_on = [vcd_nsxt_segment_profile_template.complete] +} +` + +const testAccVcdNsxtSegmentProfileTemplateGlobalDefault = testAccVcdNsxtSegmentProfileTemplate + ` +resource "vcd_nsxt_global_default_segment_profile_template" "singleton" { + vdc_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id + vapp_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.empty.id +} +` + +const testAccVcdNsxtSegmentProfileTemplateGlobalDefaultDS = testAccVcdNsxtSegmentProfileTemplateGlobalDefault + ` +data "vcd_nsxt_global_default_segment_profile_template" "singleton" { + + depends_on = [vcd_nsxt_global_default_segment_profile_template.singleton] +} +` + +const testAccVcdNsxtSegmentProfileTemplateGlobalDefaultNoValues = testAccVcdNsxtSegmentProfileTemplate + ` +resource "vcd_nsxt_global_default_segment_profile_template" "singleton" { +} +` + +func testAccCheckVcdSegmentProfileTemplateDestroy(identifier string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[identifier] + if !ok { + return fmt.Errorf("not found: %s", identifier) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("no Segment Profile Template ID is set") + } + + conn := testAccProvider.Meta().(*VCDClient) + + _, err := conn.GetSegmentProfileTemplateById(rs.Primary.ID) + + if err == nil || !govcd.ContainsNotFound(err) { + return fmt.Errorf("%s not deleted yet", identifier) + } + return nil + + } +} diff --git a/vcd/resource_vcd_org_vdc.go b/vcd/resource_vcd_org_vdc.go index 5fa02146e..951b71b61 100644 --- a/vcd/resource_vcd_org_vdc.go +++ b/vcd/resource_vcd_org_vdc.go @@ -275,7 +275,9 @@ func resourceVcdOrgVdc() *schema.Resource { "edge_cluster_id": { Type: schema.TypeString, Optional: true, + Computed: true, Description: "ID of NSX-T Edge Cluster (provider vApp networking services and DHCP capability for Isolated networks)", + Deprecated: "Please use 'vcd_org_vdc_nsxt_network_profile' resource to manage Edge Cluster and Segment Profile Templates", }, "enable_nsxv_distributed_firewall": { Type: schema.TypeBool, diff --git a/vcd/resource_vcd_org_vdc_network_profile.go b/vcd/resource_vcd_org_vdc_network_profile.go new file mode 100644 index 000000000..1fad109b3 --- /dev/null +++ b/vcd/resource_vcd_org_vdc_network_profile.go @@ -0,0 +1,144 @@ +package vcd + +import ( + "context" + + "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" + "github.com/vmware/go-vcloud-director/v2/types/v56" +) + +func resourceVcdNsxtOrgVdcNetworkProfile() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceVcdNsxtOrgVdcNetworkProfileCreateUpdate, + ReadContext: resourceVcdNsxtOrgVdcNetworkProfileRead, + UpdateContext: resourceVcdNsxtOrgVdcNetworkProfileCreateUpdate, + DeleteContext: resourceVcdNsxtOrgVdcNetworkProfileDelete, + Importer: &schema.ResourceImporter{ + StateContext: resourceVcdVdcAccessControlImport, + }, + + 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", + }, + "vdc": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "The name of VDC to use, optional if defined at provider level", + }, + "edge_cluster_id": { + Type: schema.TypeString, + Optional: true, + Description: "ID of NSX-T Edge Cluster (provider vApp networking services and DHCP capability for Isolated networks)", + }, + "vdc_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Optional: true, + Description: "Default NSX-T Segment Profile for Org VDC networks", + }, + "vapp_networks_default_segment_profile_template_id": { + Type: schema.TypeString, + Optional: true, + Description: "Default NSX-T Segment Profile for vApp networks", + }, + }, + } +} + +func resourceVcdNsxtOrgVdcNetworkProfileCreateUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + _, vdc, err := vcdClient.GetOrgAndVdcFromResource(d) + if err != nil { + return diag.Errorf("error when retrieving VDC: %s", err) + } + + if !vdc.IsNsxt() { + return diag.Errorf("network profile configuration is only supported on NSX-T VDCs") + } + + vdcNetworkProfileConfig := &types.VdcNetworkProfile{} + + if d.Get("edge_cluster_id").(string) != "" { + vdcNetworkProfileConfig.ServicesEdgeCluster = &types.VdcNetworkProfileServicesEdgeCluster{BackingID: d.Get("edge_cluster_id").(string)} + } + + if d.Get("vdc_networks_default_segment_profile_template_id").(string) != "" { + vdcNetworkProfileConfig.VdcNetworkSegmentProfileTemplateRef = &types.OpenApiReference{ID: d.Get("vdc_networks_default_segment_profile_template_id").(string)} + } + + if d.Get("vapp_networks_default_segment_profile_template_id").(string) != "" { + vdcNetworkProfileConfig.VappNetworkSegmentProfileTemplateRef = &types.OpenApiReference{ID: d.Get("vapp_networks_default_segment_profile_template_id").(string)} + } + + _, err = vdc.UpdateVdcNetworkProfile(vdcNetworkProfileConfig) + if err != nil { + return diag.Errorf("error updating VDC network profile configuration: %s", err) + } + + d.SetId(vdc.Vdc.ID) + return resourceVcdNsxtOrgVdcNetworkProfileRead(ctx, d, meta) +} + +func resourceVcdNsxtOrgVdcNetworkProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + return resourceDataSourceVcdNsxtOrgVdcNetworkProfileRead(ctx, d, meta, "resource") +} + +func resourceDataSourceVcdNsxtOrgVdcNetworkProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}, origin string) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + _, vdc, err := vcdClient.GetOrgAndVdcFromResource(d) + if err != nil { + if origin == "resource" && govcd.ContainsNotFound(err) { + d.SetId("") + return nil + } + return diag.Errorf("error when retrieving VDC: %s", err) + } + + netProfile, err := vdc.GetVdcNetworkProfile() + if err != nil { + return diag.Errorf("error getting VDC Network Profile: %s", err) + } + + dSet(d, "edge_cluster_id", "") + if netProfile.ServicesEdgeCluster != nil && netProfile.ServicesEdgeCluster.BackingID != "" { + dSet(d, "edge_cluster_id", netProfile.ServicesEdgeCluster.BackingID) + } + + dSet(d, "vapp_networks_default_segment_profile_template_id", "") + if netProfile.VappNetworkSegmentProfileTemplateRef != nil { + dSet(d, "vapp_networks_default_segment_profile_template_id", netProfile.VappNetworkSegmentProfileTemplateRef.ID) + } + + dSet(d, "vdc_networks_default_segment_profile_template_id", "") + if netProfile.VdcNetworkSegmentProfileTemplateRef != nil { + dSet(d, "vdc_networks_default_segment_profile_template_id", netProfile.VdcNetworkSegmentProfileTemplateRef.ID) + } + + d.SetId(vdc.Vdc.ID) + return nil +} + +func resourceVcdNsxtOrgVdcNetworkProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + _, vdc, err := vcdClient.GetOrgAndVdcFromResource(d) + if err != nil { + return diag.Errorf("error when retrieving VDC: %s", err) + } + + _, err = vdc.UpdateVdcNetworkProfile(&types.VdcNetworkProfile{}) + if err != nil { + return diag.Errorf("error deleting VDC network profile configuration: %s", err) + } + + return nil +} diff --git a/vcd/resource_vcd_org_vdc_network_profile_test.go b/vcd/resource_vcd_org_vdc_network_profile_test.go new file mode 100644 index 000000000..54e37593c --- /dev/null +++ b/vcd/resource_vcd_org_vdc_network_profile_test.go @@ -0,0 +1,193 @@ +//go:build vdc || nsxt || ALL || functional + +package vcd + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccVcdOrgVdcNsxtNetworkProfile(t *testing.T) { + preTestChecks(t) + skipIfNotSysAdmin(t) + + var params = StringMap{ + "VdcName": testConfig.Nsxt.Vdc, + "OrgName": testConfig.VCD.Org, + + "EdgeCluster": testConfig.Nsxt.NsxtEdgeCluster, + + "TestName": t.Name(), + "NsxtManager": testConfig.Nsxt.Manager, + "IpDiscoveryProfileName": testConfig.Nsxt.IpDiscoveryProfile, + "MacDiscoveryProfileName": testConfig.Nsxt.MacDiscoveryProfile, + "QosProfileName": testConfig.Nsxt.QosProfile, + "SpoofGuardProfileName": testConfig.Nsxt.SpoofGuardProfile, + "SegmentSecurityProfileName": testConfig.Nsxt.SegmentSecurityProfile, + + "Tags": "vdc", + } + testParamsNotEmpty(t, params) + + configText1 := templateFill(testAccVcdOrgVdcNsxtNetworkProfile, params) + params["FuncName"] = t.Name() + "-step2DS" + configText2 := templateFill(testAccVcdOrgVdcNsxtNetworkProfileDS, params) + + params["FuncName"] = t.Name() + "-step4" + configText4 := templateFill(testAccVcdOrgVdcNsxtNetworkProfileRemove, params) + + debugPrintf("#[DEBUG] CONFIGURATION - Step1: %s", configText1) + debugPrintf("#[DEBUG] CONFIGURATION - Step2: %s", configText2) + debugPrintf("#[DEBUG] CONFIGURATION - Step4: %s", configText4) + + if vcdShortTest { + t.Skip(acceptanceTestsSkipped) + return + } + + resource.Test(t, resource.TestCase{ + ProviderFactories: testAccProviders, + CheckDestroy: resource.ComposeAggregateTestCheckFunc( + testAccCheckVdcDestroy, + ), + Steps: []resource.TestStep{ + { + Config: configText1, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("vcd_org_vdc_nsxt_network_profile.nsxt", "vdc_networks_default_segment_profile_template_id"), + resource.TestCheckResourceAttrSet("vcd_org_vdc_nsxt_network_profile.nsxt", "vapp_networks_default_segment_profile_template_id"), + resource.TestCheckResourceAttrSet("vcd_org_vdc_nsxt_network_profile.nsxt", "edge_cluster_id"), + resource.TestCheckResourceAttrPair("vcd_org_vdc_nsxt_network_profile.nsxt", "edge_cluster_id", "data.vcd_org_vdc.nsxt2", "edge_cluster_id"), + ), + }, + { + Config: configText2, + Check: resource.ComposeTestCheckFunc( + resourceFieldsEqual("vcd_org_vdc_nsxt_network_profile.nsxt", "vcd_org_vdc_nsxt_network_profile.nsxt", nil), + ), + }, + { + ResourceName: "vcd_org_vdc_nsxt_network_profile.nsxt", + ImportState: true, + ImportStateVerify: true, + ImportStateId: testConfig.VCD.Org + "." + testConfig.Nsxt.Vdc, + }, + { + Config: configText4, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("vcd_org_vdc_nsxt_network_profile.nsxt", "vdc_networks_default_segment_profile_template_id", ""), + resource.TestCheckResourceAttr("vcd_org_vdc_nsxt_network_profile.nsxt", "vapp_networks_default_segment_profile_template_id", ""), + resource.TestCheckResourceAttr("vcd_org_vdc_nsxt_network_profile.nsxt", "edge_cluster_id", ""), + resource.TestCheckResourceAttrPair("vcd_org_vdc_nsxt_network_profile.nsxt", "edge_cluster_id", "data.vcd_org_vdc.nsxt2", "edge_cluster_id"), + ), + }, + }, + }) + postTestChecks(t) +} + +const testAccVcdOrgVdcNsxtNetworkProfileCommon = ` +data "vcd_nsxt_manager" "nsxt" { + name = "{{.NsxtManager}}" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "{{.IpDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "{{.MacDiscoveryProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "{{.SpoofGuardProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "{{.QosProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "{{.SegmentSecurityProfileName}}" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +resource "vcd_nsxt_segment_profile_template" "complete" { + name = "{{.TestName}}-complete" + description = "description" + + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} + +` + +const testAccVcdOrgVdcNsxtNetworkProfile = testAccVcdOrgVdcNsxtNetworkProfileCommon + ` +data "vcd_org_vdc" "nsxt" { + org = "{{.OrgName}}" + name = "{{.VdcName}}" +} + +data "vcd_nsxt_edge_cluster" "first" { + org = "{{.OrgName}}" + vdc_id = data.vcd_org_vdc.nsxt.id + name = "{{.EdgeCluster}}" +} + +resource "vcd_org_vdc_nsxt_network_profile" "nsxt" { + org = "{{.OrgName}}" + vdc = "{{.VdcName}}" + + edge_cluster_id = data.vcd_nsxt_edge_cluster.first.id + vdc_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id + vapp_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} + +data "vcd_org_vdc" "nsxt2" { + org = "{{.OrgName}}" + name = "{{.VdcName}}" + + depends_on = [vcd_org_vdc_nsxt_network_profile.nsxt] +} +` + +const testAccVcdOrgVdcNsxtNetworkProfileDS = testAccVcdOrgVdcNsxtNetworkProfile + ` +data "vcd_org_vdc_nsxt_network_profile" "nsxt" { + org = vcd_org_vdc_nsxt_network_profile.nsxt.org + vdc = vcd_org_vdc_nsxt_network_profile.nsxt.vdc +} +` + +const testAccVcdOrgVdcNsxtNetworkProfileRemove = testAccVcdOrgVdcNsxtNetworkProfileCommon + ` +data "vcd_org_vdc" "nsxt" { + org = "{{.OrgName}}" + name = "{{.VdcName}}" +} + +data "vcd_nsxt_edge_cluster" "first" { + org = "{{.OrgName}}" + vdc_id = data.vcd_org_vdc.nsxt.id + name = "{{.EdgeCluster}}" +} + +resource "vcd_org_vdc_nsxt_network_profile" "nsxt" { + org = "{{.OrgName}}" + vdc = "{{.VdcName}}" +} + +data "vcd_org_vdc" "nsxt2" { + org = "{{.OrgName}}" + name = "{{.VdcName}}" + + depends_on = [vcd_org_vdc_nsxt_network_profile.nsxt] +} +` diff --git a/vcd/resource_vcd_org_vdc_nsxt_edge_cluster_test.go b/vcd/resource_vcd_org_vdc_nsxt_edge_cluster_test.go index 1da9cc169..0a1412506 100644 --- a/vcd/resource_vcd_org_vdc_nsxt_edge_cluster_test.go +++ b/vcd/resource_vcd_org_vdc_nsxt_edge_cluster_test.go @@ -27,16 +27,8 @@ func TestAccVcdOrgVdcNsxtEdgeCluster(t *testing.T) { params["FuncName"] = t.Name() + "-step2DS" configText2 := templateFill(testAccVcdOrgVdcNsxtEdgeClusterDataSource, params) - params["FuncName"] = t.Name() + "-Update" - configText3 := templateFill(testAccVcdOrgVdcNsxtEdgeCluster_update, params) - - params["FuncName"] = t.Name() + "-UpdateDS" - configText4 := templateFill(testAccVcdOrgVdcNsxtEdgeClusterDataSource_update, params) - debugPrintf("#[DEBUG] CONFIGURATION - Step1: %s", configText1) debugPrintf("#[DEBUG] CONFIGURATION - Step2: %s", configText2) - debugPrintf("#[DEBUG] CONFIGURATION - Step3: %s", configText3) - debugPrintf("#[DEBUG] CONFIGURATION - Step4: %s", configText4) if vcdShortTest { t.Skip(acceptanceTestsSkipped) @@ -67,18 +59,6 @@ func TestAccVcdOrgVdcNsxtEdgeCluster(t *testing.T) { resourceFieldsEqual("vcd_org_vdc.with-edge-cluster", "data.vcd_org_vdc.ds", []string{"delete_recursive", "delete_force", "%"}), ), }, - { - Config: configText3, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("vcd_org_vdc.with-edge-cluster", "edge_cluster_id", ""), - ), - }, - { - Config: configText4, - Check: resource.ComposeTestCheckFunc( - resourceFieldsEqual("vcd_org_vdc.with-edge-cluster", "data.vcd_org_vdc.ds", []string{"delete_recursive", "delete_force", "%"}), - ), - }, }, }) postTestChecks(t) @@ -140,50 +120,3 @@ resource "vcd_org_vdc" "with-edge-cluster" { ` const testAccVcdOrgVdcNsxtEdgeClusterDataSource = testAccVcdOrgVdcNsxtEdgeCluster + testAccVcdOrgVdcNsxtEdgeClusterDS - -const testAccVcdOrgVdcNsxtEdgeCluster_update = ` -data "vcd_provider_vdc" "pvdc" { - name = "{{.ProviderVdc}}" -} - -data "vcd_nsxt_edge_cluster" "ec" { - provider_vdc_id = data.vcd_provider_vdc.pvdc.id - name = "{{.EdgeCluster}}" -} - -resource "vcd_org_vdc" "with-edge-cluster" { - name = "{{.VdcName}}" - org = "{{.OrgName}}" - - allocation_model = "ReservationPool" - network_pool_name = "{{.NetworkPool}}" - provider_vdc_name = data.vcd_provider_vdc.pvdc.name - - compute_capacity { - cpu { - allocated = 1024 - limit = 1024 - } - - memory { - allocated = 1024 - limit = 1024 - } - } - - storage_profile { - name = "{{.ProviderVdcStorageProfile}}" - enabled = true - limit = 10240 - default = true - } - - enabled = true - enable_thin_provisioning = true - enable_fast_provisioning = true - delete_force = true - delete_recursive = true -} -` - -const testAccVcdOrgVdcNsxtEdgeClusterDataSource_update = testAccVcdOrgVdcNsxtEdgeCluster_update + testAccVcdOrgVdcNsxtEdgeClusterDS diff --git a/website/docs/d/nsxt_global_default_segment_profile_template.html.markdown b/website/docs/d/nsxt_global_default_segment_profile_template.html.markdown new file mode 100644 index 000000000..8444b671a --- /dev/null +++ b/website/docs/d/nsxt_global_default_segment_profile_template.html.markdown @@ -0,0 +1,34 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_global_default_segment_profile_template" +sidebar_current: "docs-vcd-data-source-nsxt-segment-profile-template" +description: |- + Provides a data source to read Global Default NSX-T Segment Profile Templates. +--- + +# vcd\_nsxt\_global\_default\_segment\_profile\_template + +Provides a resource to manage Global Default NSX-T Segment Profile Templates. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. Requires System Administrator privileges. + +## Example Usage + +```hcl +resource "vcd_nsxt_global_default_segment_profile_template" "singleton" { +} +``` +## Argument Reference + +No arguments are required because this is a global VCD configuration + +## Attribute Reference + +The following attributes are supported: + +* `vdc_networks_default_segment_profile_template_id` - Global Default Segment Profile + Template ID for all VDC Networks +* `vapp_networks_default_segment_profile_template_id` - Global Default Segment Profile + Template ID for all vApp Networks + + diff --git a/website/docs/d/nsxt_network_segment_profile.html.markdown b/website/docs/d/nsxt_network_segment_profile.html.markdown new file mode 100644 index 000000000..74ddab2e4 --- /dev/null +++ b/website/docs/d/nsxt_network_segment_profile.html.markdown @@ -0,0 +1,35 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_org_vdc_nsxt_network_profile" +sidebar_current: "docs-vcd-datasource-nsxt-network-segment-profile" +description: |- + Provides a data source to read Segment Profile configuration for NSX-T Org VDC networks. +--- + +# vcd\_nsxt\_network\_segment\_profile + +Provides a data source to read Segment Profile configuration for NSX-T Org VDC networks. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. + +## Example Usage + +```hcl +data "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "my-org" + org_network_id = vcd_network_routed_v2.net1.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `org` - (Optional) The name of organization to use, optional if defined at provider level +* `org_network_id` - (Required) Org VDC Network ID + +## Attribute Reference + +All the arguments and attributes defined in +[`vcd_nsxt_network_segment_profile`](/providers/vmware/vcd/latest/docs/resources/nsxt_network_segment_profile) +resource are available. diff --git a/website/docs/d/nsxt_segment_ip_discovery_profile.html.markdown b/website/docs/d/nsxt_segment_ip_discovery_profile.html.markdown new file mode 100644 index 000000000..10a9016b2 --- /dev/null +++ b/website/docs/d/nsxt_segment_ip_discovery_profile.html.markdown @@ -0,0 +1,66 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_ip_discovery_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-ip-discovery-profile" +description: |- + Provides a VMware Cloud Director NSX-T IP Discovery Profile data source. This can be used to read NSX-T Segment Profile definitions. +--- + +# vcd\_nsxt\_segment\_ip\_discovery\_profile + +Provides a VMware Cloud Director NSX-T IP Discovery Profile data source. This can be used to read NSX-T Segment Profile definitions. + +Supported in provider *v3.11+*. + +## Example Usage (IP Discovery Profile) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "ip-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of Segment Profile +* `nsxt_manager_id` - (Optional) Segment Profile search context. Use when searching by NSX-T manager +* `vdc_id` - (Optional) Segment Profile search context. Use when searching by VDC +* `vdc_group_id` - (Optional) Segment Profile search context. Use when searching by VDC group + +-> Note: only one of `nsxt_manager_id`, `vdc_id`, `vdc_group_id` can be used + + +## Attribute reference + +* `description` - Description of IP Discovery Profile +* `arp_binding_limit` - Indicates the number of ARP snooped IP addresses to be remembered per + logical port +* `arp_binding_timeout` - ARP and ND (Neighbor Discovery) cache timeout (in minutes) +* `is_arp_snooping_enabled` - Defines whether ARP snooping is enabled +* `is_dhcp_snooping_v4_enabled` - Defines whether DHCP snooping for IPv4 is enabled +* `is_dhcp_snooping_v6_enabled` - Defines whether DHCP snooping for IPv6 is enabled +* `is_duplicate_ip_detection_enabled` - Defines whether duplicate IP detection is enabled. Duplicate + IP detection is used to determine if there is any IP conflict with any other port on the same + logical switch. If a conflict is detected, then the IP is marked as a duplicate on the port where + the IP was discovered last +* `is_nd_snooping_enabled` - Defines whether ND (Neighbor Discovery) snooping is enabled. If true, + this method will snoop the NS (Neighbor Solicitation) and NA (Neighbor Advertisement) messages in + the ND (Neighbor Discovery Protocol) family of messages which are transmitted by a VM. From the NS + messages, we will learn about the source which sent this NS message. From the NA message, we will + learn the resolved address in the message which the VM is a recipient of. Addresses snooped by + this method are subject to TOFU +* `is_tofu_enabled` - Defines whether `Trust on First Use(TOFU)` paradigm is enabled +* `is_vmtools_v4_enabled` - Defines whether fetching IPv4 address using vm-tools is enabled. This + option is only supported on ESX where vm-tools is installed +* `is_vmtools_v6_enabled` - Defines whether fetching IPv6 address using vm-tools is enabled. This + will learn the IPv6 addresses which are configured on interfaces of a VM with the help of the + VMTools software +* `nd_snooping_limit` - Maximum number of ND (Neighbor Discovery Protocol) snooped IPv6 addresses diff --git a/website/docs/d/nsxt_segment_mac_discovery_profile.html.markdown b/website/docs/d/nsxt_segment_mac_discovery_profile.html.markdown new file mode 100644 index 000000000..45665949d --- /dev/null +++ b/website/docs/d/nsxt_segment_mac_discovery_profile.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_mac_discovery_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-mac-discovery-profile" +description: |- + Provides a VMware Cloud Director NSX-T MAC Discovery Profile data source. This can be used to read NSX-T Segment Profile definitions. +--- + +# vcd\_nsxt\_segment\_mac\_discovery\_profile + +Provides a VMware Cloud Director NSX-T MAC Discovery Profile data source. This can be used to read NSX-T Segment Profile definitions. + +Supported in provider *v3.11+*. + +## Example Usage (MAC Discovery Profile) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "mac-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of Segment Profile +* `nsxt_manager_id` - (Optional) Segment Profile search context. Use when searching by NSX-T manager +* `vdc_id` - (Optional) Segment Profile search context. Use when searching by VDC +* `vdc_group_id` - (Optional) Segment Profile search context. Use when searching by VDC group + +-> Note: only one of `nsxt_manager_id`, `vdc_id`, `vdc_group_id` can be used + +## Attribute reference + +* `description` - Description of MAC Discovery Profile +* `is_mac_change_enabled` - Defines whether source MAC address change is enabled +* `is_mac_learning_enabled` - Defines whether source MAC address learning is enabled +* `is_unknown_unicast_flooding_enabled` - Defines whether unknown unicast flooding rule is enabled + This allows flooding for unlearned MAC for ingress traffic +* `mac_learning_aging_time` - Aging time in seconds for learned MAC address. Indicates how long + learned MAC address remain +* `mac_limit` - The maximum number of MAC addresses that can be learned on this port +* `mac_policy` - The policy after MAC Limit is exceeded. It can be either `ALLOW` or `DROP` \ No newline at end of file diff --git a/website/docs/d/nsxt_segment_profile_template.html.markdown b/website/docs/d/nsxt_segment_profile_template.html.markdown new file mode 100644 index 000000000..d1956ca14 --- /dev/null +++ b/website/docs/d/nsxt_segment_profile_template.html.markdown @@ -0,0 +1,32 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_profile_template" +sidebar_current: "docs-vcd-data-source-nsxt-segment-profile-template" +description: |- + Provides a data source to read NSX-T Segment Profile Templates. +--- + +# vcd\_nsxt\_segment\_profile\_template + +Provides a data source to read NSX-T Segment Profile Templates. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. Requires System Administrator privileges. + +## Example Usage (Complete example with all Segment Profiles) + +```hcl +data "vcd_nsxt_segment_profile_template" "complete" { + name = "my-segment-profile-template-name" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Name of existing Segment Profile Template + +## Attribute reference + +All properties defined in [vcd_nsxt_segment_profile_template](/providers/vmware/vcd/latest/docs/resources/nsxt_segment_profile_template) +resource are available. diff --git a/website/docs/d/nsxt_segment_qos_profile.html.markdown b/website/docs/d/nsxt_segment_qos_profile.html.markdown new file mode 100644 index 000000000..b12c16f87 --- /dev/null +++ b/website/docs/d/nsxt_segment_qos_profile.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_qos_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-qos-profile" +description: |- + Provides a VMware Cloud Director NSX-T QoS Profile data source. This can be used to read NSX-T Segment Profile definitions. +--- + +# vcd\_nsxt\_segment\_qos\_profile + +Provides a VMware Cloud Director NSX-T QoS Profile data source. This can be used to read NSX-T Segment Profile definitions. + +Supported in provider *v3.11+*. + +## Example Usage (QoS Profile) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "qos-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of Segment Profile +* `nsxt_manager_id` - (Optional) Segment Profile search context. Use when searching by NSX-T manager +* `vdc_id` - (Optional) Segment Profile search context. Use when searching by VDC +* `vdc_group_id` - (Optional) Segment Profile search context. Use when searching by VDC group + +-> Note: only one of `nsxt_manager_id`, `vdc_id`, `vdc_group_id` can be used + +## Attribute reference + +* `description` - Description of QoS Profile +* `class_of_service` - Class of service groups similar types of traffic in the network and each type + of traffic is treated as a class with its own level of service priority. The lower priority + traffic is slowed down or in some cases dropped to provide better throughput for higher priority + traffic. +* `dscp_priority` - A Differentiated Services Code Point (DSCP) priority + Profile. +* `dscp_trust_mode` - A Differentiated Services Code Point (DSCP) trust mode. Values are below: + * `TRUSTED` - With Trusted mode the inner header DSCP value is applied to the outer IP header for + IP/IPv6 traffic. For non IP/IPv6 traffic, the outer IP header takes the default value. + * `UNTRUSTED` - Untrusted mode is supported on overlay-based and VLAN-based logical port. +* `egress_rate_limiter_avg_bandwidth` - Average egress bandwidth in Mb/s. +* `egress_rate_limiter_burst_size` - Egress burst size in bytes. +* `egress_rate_limiter_peak_bandwidth` - Peak egress bandwidth in Mb/s. +* `ingress_broadcast_rate_limiter_avg_bandwidth` - Average ingress broadcast bandwidth in Mb/s. +* `ingress_broadcast_rate_limiter_burst_size` - Ingress broadcast burst size in bytes. +* `ingress_broadcast_rate_limiter_peak_bandwidth` - Peak ingress broadcast bandwidth in Mb/s. +* `ingress_rate_limiter_avg_bandwidth` - Average ingress bandwidth in Mb/s. +* `ingress_rate_limiter_burst_size` - Ingress burst size in bytes. +* `ingress_rate_limiter_peak_bandwidth` - Peak ingress broadcast bandwidth in Mb/s. diff --git a/website/docs/d/nsxt_segment_security_profile.html.markdown b/website/docs/d/nsxt_segment_security_profile.html.markdown new file mode 100644 index 000000000..fee30de6e --- /dev/null +++ b/website/docs/d/nsxt_segment_security_profile.html.markdown @@ -0,0 +1,56 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_security_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-security-profile" +description: |- + Provides a VMware Cloud Director NSX-T Segment Security Profile data source. This can be used to read NSX-T Segment Profile definitions. +--- + +# vcd\_nsxt\_segment\_security\_profile + +Provides a VMware Cloud Director NSX-T Segment Security Profile data source. This can be used to read NSX-T Segment Profile definitions. + +Supported in provider *v3.11+*. + +## Example Usage (Segment Security Profile) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "segment-security-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +``` + + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of Segment Profile +* `nsxt_manager_id` - (Optional) Segment Profile search context. Use when searching by NSX-T manager +* `vdc_id` - (Optional) Segment Profile search context. Use when searching by VDC +* `vdc_group_id` - (Optional) Segment Profile search context. Use when searching by VDC group + +-> Note: only one of `nsxt_manager_id`, `vdc_id`, `vdc_group_id` can be used + + +## Attribute reference + +* `description` - Description of Segment Security Profile +* `bpdu_filter_allow_list` - Pre-defined list of allowed MAC addresses to be excluded from BPDU filtering. +* `is_bpdu_filter_enabled` - Defines whether BPDU filter is enabled. +* `is_dhcp_v4_client_block_enabled` - Defines whether DHCP Client block IPv4 is enabled. This filters DHCP Client IPv4 traffic. +* `is_dhcp_v6_client_block_enabled` - Defines whether DHCP Client block IPv6 is enabled. This filters DHCP Client IPv6 traffic. +* `is_dhcp_v4_server_block_enabled` - Defines whether DHCP Server block IPv4 is enabled. This filters DHCP Server IPv4 traffic. +* `is_dhcp_v6_server_block_enabled` - Defines whether DHCP Server block IPv6 is enabled. This filters DHCP Server IPv6 traffic. +* `is_non_ip_traffic_block_enabled` - Defines whether non IP traffic block is enabled. If true, it blocks all traffic except IP/(G)ARP/BPDU. +* `is_ra_guard_enabled` - Defines whether Router Advertisement Guard is enabled. This filters DHCP Server IPv6 traffic. +* `is_rate_limitting_enabled` - Defines whether Rate Limiting is enabled. +* `rx_broadcast_limit` - Incoming broadcast traffic limit in packets per second. +* `rx_multicast_limit` - Incoming multicast traffic limit in packets per second. +* `tx_broadcast_limit` - Outgoing broadcast traffic limit in packets per second. +* `tx_multicast_limit` - Outgoing multicast traffic limit in packets per second. diff --git a/website/docs/d/nsxt_segment_spoof_guard_profile.html.markdown b/website/docs/d/nsxt_segment_spoof_guard_profile.html.markdown new file mode 100644 index 000000000..c1f3406aa --- /dev/null +++ b/website/docs/d/nsxt_segment_spoof_guard_profile.html.markdown @@ -0,0 +1,43 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_spoof_guard_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-spoof-guard-profile" +description: |- + Provides a VMware Cloud Director NSX-T Spoof Guard Profile data source. This can be used to read NSX-T Segment Profile definitions. +--- + +# vcd\_nsxt\_segment\_spoof\_guard\_profile + +Provides a VMware Cloud Director Spoof Guard Profile data source. This can be used to read NSX-T Segment Profile definitions. + +Supported in provider *v3.11+*. + +## Example Usage (IP Discovery Profile) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "spoof-guard-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of Segment Profile +* `nsxt_manager_id` - (Optional) Segment Profile search context. Use when searching by NSX-T manager +* `vdc_id` - (Optional) Segment Profile search context. Use when searching by VDC +* `vdc_group_id` - (Optional) Segment Profile search context. Use when searching by VDC group + +-> Note: only one of `nsxt_manager_id`, `vdc_id`, `vdc_group_id` can be used + +## Attribute reference + +* `description` - Description of Spoof Guard profile +* `is_address_binding_whitelist_enabled` - Whether Spoof Guard is enabled. If true, it only allows + VM sending traffic with the IPs in the whitelist diff --git a/website/docs/d/org_vdc_nsxt_network_profile.html.markdown b/website/docs/d/org_vdc_nsxt_network_profile.html.markdown new file mode 100644 index 000000000..c4d1adfdb --- /dev/null +++ b/website/docs/d/org_vdc_nsxt_network_profile.html.markdown @@ -0,0 +1,44 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_org_vdc_nsxt_network_profile" +sidebar_current: "docs-vcd-data-source-nsxt-segment-profile-template" +description: |- + Provides a data source to read Network Profile for NSX-T VDCs. +--- + +# vcd\_org\_vdc\_nsxt\_network\_profile + +Provides a data source to read Network Profile for NSX-T VDCs. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. + +## Example Usage + +```hcl +data "vcd_org_vdc_nsxt_network_profile" "nsxt" { + org = "my-org" + vdc = "my-vdc" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `org` - (Optional) The name of organization to use, optional if defined at provider level +* `vdc` - (Optional) The name of VDC to use, optional if defined at provider level + +## Attribute reference + +* `edge_cluster_id` - An ID of NSX-T Edge Cluster which should provide vApp + Networking Services or DHCP for Isolated Networks. This value **might be unavailable** in data + source if user has insufficient rights. +* `vdc_networks_default_segment_profile_template_id` - Default Segment Profile ID for all Org VDC + networks withing this VDC +* `vapp_networks_default_segment_profile_template_id`- Default Segment Profile ID for all vApp + networks withing this VDC + +All other attributes are defined in [organization VDC network profile +resource](/providers/vmware/vcd/latest/docs/resources/org_vdc_nsxt_network_profile.html#attribute-reference) +are supported. + diff --git a/website/docs/r/nsxt_global_default_segment_profile_template.html.markdown b/website/docs/r/nsxt_global_default_segment_profile_template.html.markdown new file mode 100644 index 000000000..c02600304 --- /dev/null +++ b/website/docs/r/nsxt_global_default_segment_profile_template.html.markdown @@ -0,0 +1,52 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_global_default_segment_profile_template" +sidebar_current: "docs-vcd-resource-nsxt-segment-profile-template" +description: |- + Provides a resource to manage Global Default NSX-T Segment Profile Templates. +--- + +# vcd\_nsxt\_global\_default\_segment\_profile\_template + +Provides a resource to manage Global Default NSX-T Segment Profile Templates. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. Requires System Administrator privileges. + +-> This resource is a singleton - only one configuration exists in entire VCD instance. Having +multiple resource definitions will override each other. + +## Example Usage + +```hcl +resource "vcd_nsxt_global_default_segment_profile_template" "singleton" { + vdc_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id + vapp_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.empty.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `vdc_networks_default_segment_profile_template_id` - (Optional) Global Default Segment Profile + Template ID for all VDC Networks +* `vapp_networks_default_segment_profile_template_id` - (Optional) Global Default Segment Profile + Template ID for all vApp Networks + + +## Importing + +~> The current implementation of Terraform import can only import resources into the state. +It does not generate configuration. [More information.](https://www.terraform.io/docs/import/) + +An existing global default Segment Profile Template configuration can be [imported][docs-import] into this +resource via supplying path for it. An example is below: + +[docs-import]: https://www.terraform.io/docs/import/ + +``` +terraform import vcd_nsxt_global_default_segment_profile_template.imported optional-dummy-id +``` + +The above would import the global default Segment Profile Template configuration. **Note**: the +`optional-dummy-id` is not mandatory but it may be useful for `import` definitions. diff --git a/website/docs/r/nsxt_network_segment_profile.html.markdown b/website/docs/r/nsxt_network_segment_profile.html.markdown new file mode 100644 index 000000000..23ebea874 --- /dev/null +++ b/website/docs/r/nsxt_network_segment_profile.html.markdown @@ -0,0 +1,152 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_org_vdc_nsxt_network_profile" +sidebar_current: "docs-vcd-resource-nsxt-network-segment-profile" +description: |- + Provides a resource to configure Segment Profiles for NSX-T Org VDC networks. +--- + +# vcd\_nsxt\_network\_segment\_profile + +Provides a resource to configure Segment Profiles for NSX-T Org VDC networks. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. + +## Example Usage (Segment Profile Template assignment to Org VDC Network) + +```hcl +data "vcd_nsxt_segment_profile_template" "complete" { + name = "complete-profile" +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "my-org" + name = "my-gw" +} + +resource "vcd_network_routed_v2" "net1" { + org = "my-org" + name = "routed-net" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "my-org" + org_network_id = vcd_network_routed_v2.net1.id + + segment_profile_template_id = data.vcd_nsxt_segment_profile_template.complete.id +} +``` + +## Example Usage (Custom Segment Profile assignment to Org VDC Network) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "ip-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "mac-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "spoof-guard-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "qos-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "segment-security-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_edgegateway" "existing" { + org = "my-org" + name = "nsxt-gw-v40" +} + +resource "vcd_network_routed_v2" "net1" { + org = "my-org" + name = "routed-net" + + edge_gateway_id = data.vcd_nsxt_edgegateway.existing.id + + gateway = "1.1.1.1" + prefix_length = 24 + + static_ip_pool { + start_address = "1.1.1.10" + end_address = "1.1.1.20" + } +} + +resource "vcd_nsxt_network_segment_profile" "custom-prof" { + org = "my-org" + org_network_id = vcd_network_routed_v2.net1.id + + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `org` - (Optional) The name of organization to use, optional if defined at provider level +* `org_network_id` - (Required) Org VDC Network ID +* `segment_profile_template_id` - (Optional) Segment Profile Template ID to be applied for this Org + VDC Network +* `ip_discovery_profile_id` - (Optional) IP Discovery Profile ID. Can be referenced using + [`vcd_nsxt_segment_ip_discovery_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_ip_discovery_profile) + data source. +* `mac_discovery_profile_id` - (Optional) MAC Discovery Profile ID. Can be referenced using + [`vcd_nsxt_segment_mac_discovery_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_mac_discovery_profile) + data source. +* `spoof_guard_profile_id` - (Optional) Spoof Guard Profile ID. Can be referenced using + [`vcd_nsxt_segment_spoof_guard_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_spoof_guard_profile) + data source. +* `qos_profile_id` - (Optional) QoS Profile ID. Can be referenced using + [`vcd_nsxt_segment_qos_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_qos_profile) + data source. +* `segment_security_profile_id` - (Optional) Segment Security Profile ID. Can be referenced using + [`vcd_nsxt_segment_security_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_security_profile) + data source. + +## Importing + +~> **Note:** The current implementation of Terraform import can only import resources into the state. +It does not generate configuration. [More information.](https://www.terraform.io/docs/import/) + +An existing NSX-T Org VDC Network Segment Profile configuration can be [imported][docs-import] into +this resource via supplying the full dot separated path for Org VDC Network. An example is below: + +[docs-import]: https://www.terraform.io/docs/import/ + +``` +terraform import vcd_nsxt_network_segment_profile.my-profile org-name.vdc-org-vdc-group-name.org_network_name +``` + +NOTE: the default separator (.) can be changed using Provider.import_separator or variable VCD_IMPORT_SEPARATOR diff --git a/website/docs/r/nsxt_segment_profile_template.html.markdown b/website/docs/r/nsxt_segment_profile_template.html.markdown new file mode 100644 index 000000000..5ba1f3666 --- /dev/null +++ b/website/docs/r/nsxt_segment_profile_template.html.markdown @@ -0,0 +1,95 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_nsxt_segment_profile_template" +sidebar_current: "docs-vcd-resource-nsxt-segment-profile-template" +description: |- + Provides a resource to manage NSX-T Segment Profile Templates. +--- + +# vcd\_nsxt\_segment\_profile\_template + +Provides a resource to manage NSX-T Segment Profile Templates. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. Requires System Administrator privileges. + +## Example Usage (Example with all Segment Profiles) + +```hcl +data "vcd_nsxt_manager" "nsxt" { + name = "nsxManager1" +} + +data "vcd_nsxt_segment_ip_discovery_profile" "first" { + name = "ip-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_mac_discovery_profile" "first" { + name = "mac-discovery-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_spoof_guard_profile" "first" { + name = "spoof-guard-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_qos_profile" "first" { + name = "qos-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +data "vcd_nsxt_segment_security_profile" "first" { + name = "segment-security-profile-0" + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id +} + +resource "vcd_nsxt_segment_profile_template" "complete" { + nsxt_manager_id = data.vcd_nsxt_manager.nsxt.id + + name = "my-first-segment-profile-template" + description = "my description" + + ip_discovery_profile_id = data.vcd_nsxt_segment_ip_discovery_profile.first.id + mac_discovery_profile_id = data.vcd_nsxt_segment_mac_discovery_profile.first.id + spoof_guard_profile_id = data.vcd_nsxt_segment_spoof_guard_profile.first.id + qos_profile_id = data.vcd_nsxt_segment_qos_profile.first.id + segment_security_profile_id = data.vcd_nsxt_segment_security_profile.first.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `nsxt_manager_id` - (Required) NSX-T Manager ID (can be referenced using + [`vcd_nsxt_manager`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_manager) datasource) +* `name` - (Required) Name for Segment Profile Template +* `description` - (Optional) Description of Segment Profile Template +* `ip_discovery_profile_id` - (Optional) IP Discovery Profile ID. can be referenced using + [`vcd_nsxt_segment_ip_discovery_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_ip_discovery_profile) +* `mac_discovery_profile_id` - (Optional) IP Discovery Profile ID. can be referenced using + [`vcd_nsxt_segment_mac_discovery_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_mac_discovery_profile) +* `spoof_guard_profile_id` - (Optional) IP Discovery Profile ID. can be referenced using + [`vcd_nsxt_segment_spoof_guard_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_spoof_guard_profile) +* `qos_profile_id` - (Optional) IP Discovery Profile ID. can be referenced using + [`vcd_nsxt_segment_qos_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_qos_profile) +* `segment_security_profile_id` - (Optional) IP Discovery Profile ID. can be referenced using + [`vcd_nsxt_segment_security_profile`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_segment_security_profile) + + +## Importing + +~> The current implementation of Terraform import can only import resources into the state. +It does not generate configuration. [More information.](https://www.terraform.io/docs/import/) + +An existing NSX-T Segment Profile Template configuration can be [imported][docs-import] into this +resource via supplying path for it. An example is below: + +[docs-import]: https://www.terraform.io/docs/import/ + +``` +terraform import vcd_nsxt_segment_profile_template.imported segment-profile-name +``` + +The above would import the `segment-profile-name` NSX-T Segment Profile Template. diff --git a/website/docs/r/org_vdc.html.markdown b/website/docs/r/org_vdc.html.markdown index f4ea4f920..4fb3a66fe 100644 --- a/website/docs/r/org_vdc.html.markdown +++ b/website/docs/r/org_vdc.html.markdown @@ -241,9 +241,10 @@ The following arguments are supported: * `default_vm_sizing_policy_id` - (Deprecated; Optional, *v3.0+*, *VCD 10.2+*) ID of the default Compute Policy for this VDC. It can be a VM Sizing Policy, a VM Placement Policy or a vGPU Policy. Deprecated in favor of `default_compute_policy_id`. * `vm_sizing_policy_ids` - (Optional, *v3.0+*, *VCD 10.2+*) Set of IDs of VM Sizing policies that are assigned to this VDC. This field requires `default_compute_policy_id` to be configured together. * `vm_placement_policy_ids` - (Optional, *v3.8+*, *VCD 10.2+*) Set of IDs of VM Placement policies that are assigned to this VDC. This field requires `default_compute_policy_id` to be configured together. -* `edge_cluster_id` - (Optional, *v3.8+*, *VCD 10.3+*) An ID of NSX-T Edge Cluster which should - provide vApp Networking Services or DHCP for isolated networks. Can be looked up using - `vcd_nsxt_edge_cluster` data source. +* `edge_cluster_id` - (Deprecated; Optional, *v3.8+*, *VCD 10.3+*) An ID of NSX-T Edge Cluster which + should provide vApp Networking Services or DHCP for isolated networks. Can be looked up using + `vcd_nsxt_edge_cluster` data source. This field is **deprecated** in favor of + [`vcd_org_vdc_nsxt_network_profile`](/providers/vmware/vcd/latest/docs/resources/org_vdc_nsxt_network_profile). * `enable_nsxv_distributed_firewall` - (Optional, *v3.9+*, *VCD 10.3+*) Enables or disables the NSX-V distributed firewall. diff --git a/website/docs/r/org_vdc_nsxt_network_profile.html.markdown b/website/docs/r/org_vdc_nsxt_network_profile.html.markdown new file mode 100644 index 000000000..2d441abc3 --- /dev/null +++ b/website/docs/r/org_vdc_nsxt_network_profile.html.markdown @@ -0,0 +1,73 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_org_vdc_nsxt_network_profile +sidebar_current: "docs-vcd-resource-vcd-org-vdc-nsxt-network-profile" +description: |- + Provides a resource to manage NSX-T Org VDC Network Profile. +--- + +# vcd\_org\_vdc\_nsxt\_network\_profile + +Provides a resource to manage NSX-T Org VDC Network Profile. + +Supported in provider *v3.11+* and VCD 10.4.0+ with NSX-T. + +-> This resource is a "singleton" per VDC as it modifies VDC property (network profile +configuration) + +## Example Usage + +```hcl +data "vcd_org_vdc" "nsxt" { + org = "my-org" + name = "my-vdc" +} + +data "vcd_nsxt_edge_cluster" "first" { + org = "my-org" + vdc_id = data.vcd_org_vdc.nsxt.id + name = "my-edge-cluster" +} + +resource "vcd_org_vdc_nsxt_network_profile" "nsxt" { + org = "my-org" + vdc = "my-vdc" + + edge_cluster_id = data.vcd_nsxt_edge_cluster.first.id + vdc_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id + vapp_networks_default_segment_profile_template_id = vcd_nsxt_segment_profile_template.complete.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `edge_cluster_id` - (Optional) - Edge Cluster ID to be used for this VDC +* `vdc_networks_default_segment_profile_template_id` - (Optional) - Default Segment Profile + Template ID for all VDC Networks in a VDC +* `vapp_networks_default_segment_profile_template_id` - (Optional) - Default Segment Profile + Template ID for all vApp Networks in a VDC + + +## Importing + + +~> **Note:** The current implementation of Terraform import can only import resources into the state. +It does not generate configuration. [More information.](https://www.terraform.io/docs/import/) + +An existing an organization VDC NSX-T Network Profile configuration can be [imported][docs-import] into +this resource via supplying the full dot separated path to VDC. An example is below: + +``` +terraform import vcd_org_vdc_nsxt_network_profile.my-cfg my-org.my-vdc +``` + +NOTE: the default separator (.) can be changed using Provider.import_separator or variable VCD_IMPORT_SEPARATOR + +[docs-import]:https://www.terraform.io/docs/import/ + +After that, you can expand the configuration file and either update or delete the VDC Network +Profile as needed. Running `terraform plan` at this stage will show the difference between the +minimal configuration file and the VDC's stored properties. + diff --git a/website/vcd.erb b/website/vcd.erb index 7636607ea..cc4104608 100644 --- a/website/vcd.erb +++ b/website/vcd.erb @@ -373,6 +373,33 @@