From 873c26dfc01ddef0aa34260c2d9e52981a317067 Mon Sep 17 00:00:00 2001 From: Kobi Samoray Date: Tue, 3 Dec 2024 11:59:35 +0200 Subject: [PATCH] Implement map data sources for policy services and groups These data sources allows the retrieval of the entire tables from NSX to save multiple calls to the backend. Fixes: #696 Signed-off-by: Kobi Samoray --- nsxt/data_source_nsxt_policy_groups.go | 65 +++++++++++++++++ nsxt/data_source_nsxt_policy_groups_test.go | 71 +++++++++++++++++++ nsxt/data_source_nsxt_policy_services.go | 62 ++++++++++++++++ nsxt/data_source_nsxt_policy_services_test.go | 62 ++++++++++++++++ nsxt/provider.go | 2 + website/docs/d/ns_services.html.markdown | 2 +- website/docs/d/policy_groups.html.markdown | 65 +++++++++++++++++ website/docs/d/policy_services.html.markdown | 49 +++++++++++++ 8 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 nsxt/data_source_nsxt_policy_groups.go create mode 100644 nsxt/data_source_nsxt_policy_groups_test.go create mode 100644 nsxt/data_source_nsxt_policy_services.go create mode 100644 nsxt/data_source_nsxt_policy_services_test.go create mode 100644 website/docs/d/policy_groups.html.markdown create mode 100644 website/docs/d/policy_services.html.markdown diff --git a/nsxt/data_source_nsxt_policy_groups.go b/nsxt/data_source_nsxt_policy_groups.go new file mode 100644 index 000000000..cfa3723d7 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups.go @@ -0,0 +1,65 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/vmware/terraform-provider-nsxt/api/infra/domains" +) + +func dataSourceNsxtPolicyGroups() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNsxtPolicyGroupsRead, + + Schema: map[string]*schema.Schema{ + "context": getContextSchema(false, false, false), + "domain": getDomainNameSchema(), + "items": { + Type: schema.TypeMap, + Description: "Mapping of service UUID by display name", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + }, + "path": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceNsxtPolicyGroupsRead(d *schema.ResourceData, m interface{}) error { + connector := getPolicyConnector(m) + domainName := d.Get("domain").(string) + + client := domains.NewGroupsClient(getSessionContext(d, m), connector) + + groupsMap := make(map[string]interface{}) + results, err := client.List(domainName, nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + if _, ok := groupsMap[*r.DisplayName]; ok { + return fmt.Errorf("found duplicate policy group %s", *r.DisplayName) + } + groupMap := make(map[string]interface{}) + groupMap["id"] = r.Id + groupMap["path"] = r.Path + groupsMap[*r.DisplayName] = groupMap + } + + d.SetId(newUUID()) + d.Set("items", groupsMap) + return nil +} diff --git a/nsxt/data_source_nsxt_policy_groups_test.go b/nsxt/data_source_nsxt_policy_groups_test.go new file mode 100644 index 000000000..d3ec2b324 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups_test.go @@ -0,0 +1,71 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccDataSourceNsxtPolicyGroups_basic(t *testing.T) { + testAccDataSourceNsxtPolicyGroupsBasic(t, false, func() { + testAccPreCheck(t) + }) +} + +func TestAccDataSourceNsxtPolicyGroups_multitenancy(t *testing.T) { + testAccDataSourceNsxtPolicyGroupsBasic(t, true, func() { + testAccPreCheck(t) + testAccOnlyMultitenancy(t) + }) +} + +func testAccDataSourceNsxtPolicyGroupsBasic(t *testing.T, withContext bool, preCheck func()) { + domain := "default" + groupName := getAccTestDataSourceName() + testResourceName := "data.nsxt_policy_Groups.test" + checkResourceName := "data.nsxt_policy_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: preCheck, + Providers: testAccProviders, + CheckDestroy: func(state *terraform.State) error { + return testAccDataSourceNsxtPolicyGroupDeleteByName(domain, groupName) + }, + Steps: []resource.TestStep{ + { + PreConfig: func() { + if err := testAccDataSourceNsxtPolicyGroupCreate(domain, groupName); err != nil { + t.Error(err) + } + }, + Config: testAccNSXPolicyGroupsReadTemplate(groupName, withContext), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(testResourceName, "id"), + resource.TestCheckResourceAttr(checkResourceName, "display_name", groupName), + ), + }, + }, + }) +} + +func testAccNSXPolicyGroupsReadTemplate(groupName string, withContext bool) string { + context := "" + if withContext { + context = testAccNsxtPolicyMultitenancyContext() + } + return fmt.Sprintf(` +data "nsxt_policy_groups" "test" { +%s +} + +data "nsxt_policy_group" "test" { + id = data.nsxt_policy_groups.test.items["%s"].id +} + +`, context, groupName) +} diff --git a/nsxt/data_source_nsxt_policy_services.go b/nsxt/data_source_nsxt_policy_services.go new file mode 100644 index 000000000..1b491be35 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services.go @@ -0,0 +1,62 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/vmware/terraform-provider-nsxt/api/infra" +) + +func dataSourceNsxtPolicyServices() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNsxtPolicyServicesRead, + + Schema: map[string]*schema.Schema{ + "context": getContextSchema(false, false, false), + "items": { + Type: schema.TypeMap, + Description: "Mapping of service UUID by display name", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + }, + "path": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceNsxtPolicyServicesRead(d *schema.ResourceData, m interface{}) error { + connector := getPolicyConnector(m) + client := infra.NewServicesClient(getSessionContext(d, m), connector) + + servicesMap := make(map[string]interface{}) + results, err := client.List(nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + if _, ok := servicesMap[*r.DisplayName]; ok { + return fmt.Errorf("found duplicate policy service %s", *r.DisplayName) + } + serviceMap := make(map[string]interface{}) + serviceMap["id"] = r.Id + serviceMap["path"] = r.Path + servicesMap[*r.DisplayName] = serviceMap + } + + d.SetId(newUUID()) + d.Set("items", servicesMap) + return nil +} diff --git a/nsxt/data_source_nsxt_policy_services_test.go b/nsxt/data_source_nsxt_policy_services_test.go new file mode 100644 index 000000000..15c12eabd --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services_test.go @@ -0,0 +1,62 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceNsxtPolicyServices_basic(t *testing.T) { + testAccDataSourceNsxtPolicyServicesBasic(t, false, func() { + testAccPreCheck(t) + }) +} + +func TestAccDataSourceNsxtPolicyServices_multitenancy(t *testing.T) { + testAccDataSourceNsxtPolicyServicesBasic(t, true, func() { + testAccPreCheck(t) + testAccOnlyMultitenancy(t) + }) +} + +func testAccDataSourceNsxtPolicyServicesBasic(t *testing.T, withContext bool, preCheck func()) { + serviceName := getAccTestDataSourceName() + testResourceName := "data.nsxt_policy_services.test" + checkResourceName := "data.nsxt_policy_service.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: preCheck, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccNSXPolicyServicesReadTemplate(serviceName, withContext), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(testResourceName, "id"), + resource.TestCheckResourceAttr(checkResourceName, "display_name", serviceName), + ), + }, + }, + }) +} + +func testAccNSXPolicyServicesReadTemplate(serviceName string, withContext bool) string { + context := "" + if withContext { + context = testAccNsxtPolicyMultitenancyContext() + } + return testAccNsxtPolicyIcmpTypeServiceCreateTypeCodeTemplate(serviceName, "3", "1", "ICMPv4", withContext) + fmt.Sprintf(` +data "nsxt_policy_services" "test" { + depends_on = [nsxt_policy_service.test] +%s +} + +data "nsxt_policy_service" "test" { + id = data.nsxt_policy_services.test.items["%s"].id +} + +`, context, serviceName) +} diff --git a/nsxt/provider.go b/nsxt/provider.go index af2c05488..0607cf6ba 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -328,6 +328,8 @@ func Provider() *schema.Provider { "nsxt_policy_gateway_flood_protection_profile": dataSourceNsxtPolicyGatewayFloodProtectionProfile(), "nsxt_manager_info": dataSourceNsxtManagerInfo(), "nsxt_vpc": dataSourceNsxtVPC(), + "nsxt_policy_services": dataSourceNsxtPolicyServices(), + "nsxt_policy_groups": dataSourceNsxtPolicyGroups(), }, ResourcesMap: map[string]*schema.Resource{ diff --git a/website/docs/d/ns_services.html.markdown b/website/docs/d/ns_services.html.markdown index c5409c25a..563232efe 100644 --- a/website/docs/d/ns_services.html.markdown +++ b/website/docs/d/ns_services.html.markdown @@ -7,7 +7,7 @@ description: A networking and security services data source. This data source bu # nsxt_ns_services -This data source builds a "name to uuid" map of the whole NS Services table. Such map can be referenced in configuration to obtain object uuids by display name at a cost of single roudtrip to NSX, which improves apply and refresh +This data source builds a "name to uuid" map of the whole NS Services table. Such map can be referenced in configuration to obtain object uuids by display name at a cost of single roundtrip to NSX, which improves apply and refresh time at scale, compared to multiple instances of `nsxt_ns_service` data source. ## Example Usage diff --git a/website/docs/d/policy_groups.html.markdown b/website/docs/d/policy_groups.html.markdown new file mode 100644 index 000000000..b0604b5ad --- /dev/null +++ b/website/docs/d/policy_groups.html.markdown @@ -0,0 +1,65 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_groups" +description: A policy groups data source. This data source builds "display name to identifiers" map representation of the whole table. +--- + +# nsxt_policy_groups + +This data source builds a "name to identifiers" map of the whole policy Groups table. Such map can be referenced in configuration to obtain object identifier attributes by display name at a cost of single roundtrip to NSX, which improves apply and refresh +time at scale, compared to multiple instances of `nsxt_policy_group` data source. + +## Example Usage + +```hcl +data "nsxt_policy_groups" "map" { +} + +resource "nsxt_policy_predefined_security_policy" "test" { + path = data.nsxt_policy_security_policy.default_l3.path + + tag { + scope = "color" + tag = "orange" + } + + rule { + display_name = "allow_icmp" + destination_groups = [data.nsxt_policy_groups.items["Cats"].path, data.nsxt_policy_groups.items["Dogs"].path] + action = "ALLOW" + services = [nsxt_policy_service.icmp.path] + logged = true + } + + rule { + display_name = "allow_udp" + source_groups = [data.nsxt_policy_groups.items["Fish"].path] + sources_excluded = true + scope = [data.nsxt_policy_groups.items["Aquarium"].path] + action = "ALLOW" + services = [nsxt_policy_service.udp.path] + logged = true + disabled = true + } + + default_rule { + action = "DROP" + } + +} +``` + +## Argument Reference + +* `domain` - (Optional) The domain this Group belongs to. For VMware Cloud on AWS use `cgw`. For Global Manager, please use site id for this field. If not specified, this field is default to `default`. +* `context` - (Optional) The context which the object belongs to + * `project_id` - (Required) The ID of the project which the object belongs to + +## Attributes Reference + +In addition to arguments listed above, the following attributes are exported: + +* `items` - Map of policy service identifiers keyed by display name. + * `id` - The ID of the service. + * `path` - The NSX path of the policy resource. diff --git a/website/docs/d/policy_services.html.markdown b/website/docs/d/policy_services.html.markdown new file mode 100644 index 000000000..d96f73905 --- /dev/null +++ b/website/docs/d/policy_services.html.markdown @@ -0,0 +1,49 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_services" +description: A policy services data source. This data source builds "display name to identifiers" map representation of the whole table. +--- + +# nsxt_policy_services + +This data source builds a "name to identifiers" map of the whole policy Services table. Such map can be referenced in configuration to obtain object identifier attributes by display name at a cost of single roundtrip to NSX, which improves apply and refresh +time at scale, compared to multiple instances of `nsxt_policy_service` data source. + +## Example Usage + +```hcl +data "nsxt_policy_services" "map" { +} + +resource "nsxt_policy_nat_rule" "dnat1" { + display_name = "dnat_rule1" + action = "DNAT" + source_networks = ["9.1.1.1", "9.2.1.1"] + destination_networks = ["11.1.1.1"] + translated_networks = ["10.1.1.1"] + gateway_path = nsxt_policy_tier1_gateway.t1gateway.path + logging = false + firewall_match = "MATCH_INTERNAL_ADDRESS" + policy_based_vpn_mode = "BYPASS" + service = data.nsxt_policy_services.map.items["DNS-UDP"].path + + tag { + scope = "color" + tag = "blue" + } +} +``` + +## Argument Reference + +* `context` - (Optional) The context which the object belongs to + * `project_id` - (Required) The ID of the project which the object belongs to + +## Attributes Reference + +In addition to arguments listed above, the following attributes are exported: + +* `items` - Map of policy service identifiers keyed by display name. + * `id` - The ID of the service. + * `path` - The NSX path of the policy resource.