From cc7c11d0a600aa6bfc694d10de6733fc3f87ef58 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 | 66 +++++++++++++++++ nsxt/data_source_nsxt_policy_groups_test.go | 74 +++++++++++++++++++ nsxt/data_source_nsxt_policy_services.go | 63 ++++++++++++++++ nsxt/data_source_nsxt_policy_services_test.go | 65 ++++++++++++++++ nsxt/provider.go | 2 + website/docs/d/ns_services.html.markdown | 2 +- website/docs/d/policy_groups.html.markdown | 69 +++++++++++++++++ website/docs/d/policy_services.html.markdown | 50 +++++++++++++ 8 files changed, 390 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..308a5a8a4 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups.go @@ -0,0 +1,66 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "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.TypeList, + Description: "Mapping of service UUID by display name", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + }, + "display_name": { + 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) + + var groupsList []interface{} + results, err := client.List(domainName, nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + groupMap := make(map[string]interface{}) + groupMap["id"] = r.Id + groupMap["display_name"] = r.DisplayName + groupMap["path"] = r.Path + groupsList = append(groupsList, groupMap) + } + + d.SetId(newUUID()) + d.Set("items", groupsList) + 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..245320fc6 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups_test.go @@ -0,0 +1,74 @@ +/* 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 +} + +locals { + group_from_list = data.nsxt_policy_groups.test.items[index(data.nsxt_policy_groups.test.items.*.display_name, "%s")] +} + +data "nsxt_policy_group" "test" { + id = local.group_from_list.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..2a3608cc6 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services.go @@ -0,0 +1,63 @@ +/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "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.TypeList, + Description: "List of services", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + }, + "display_name": { + 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) + + var servicesList []interface{} + results, err := client.List(nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + serviceMap := make(map[string]interface{}) + serviceMap["id"] = r.Id + serviceMap["display_name"] = r.DisplayName + serviceMap["path"] = r.Path + servicesList = append(servicesList, serviceMap) + } + + d.SetId(newUUID()) + d.Set("items", servicesList) + 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..4fd82f21c --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services_test.go @@ -0,0 +1,65 @@ +/* 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 +} + +locals { + service_from_list = data.nsxt_policy_services.test.items[index(data.nsxt_policy_services.test.service_from_list.*.display_name, "%s")] +} + +data "nsxt_policy_service" "test" { + id = local.service_from_list.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..c8ba9f429 --- /dev/null +++ b/website/docs/d/policy_groups.html.markdown @@ -0,0 +1,69 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_groups" +description: A policy groups data source. This data source builds a list representation of the whole groups table, containing `id`, `display_name` and `path` attributes. +--- + +# nsxt_policy_groups + +This data source builds a list of the whole policy Groups table. Such list can be referenced in configuration to obtain object identifier attributes lookup 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" "grouplist" { +} + +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.test.items[index(data.nsxt_policy_groups.test.items.*.display_name, "Cats")].path, + data.nsxt_policy_groups.test.items[index(data.nsxt_policy_groups.test.items.*.display_name, "Dogs")].path + ] + action = "ALLOW" + services = [nsxt_policy_service.icmp.path] + logged = true + } + + rule { + display_name = "allow_udp" + source_groups = [data.nsxt_policy_groups.grouplist.items[index(data.nsxt_policy_groups.grouplist.items.*.display_name, "Fish")].path] + sources_excluded = true + scope = [data.nsxt_policy_groups.grouplist.items[index(data.nsxt_policy_groups.grouplist.items.*.display_name, "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` - List of policy group entries. + * `id` - The ID of the group. + * `display_name` - Display name of the group entry. + * `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..885cc8ea9 --- /dev/null +++ b/website/docs/d/policy_services.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_services" +description: A policy services data source. This data source builds a list representation of the whole services table, containing `id`, `display_name` and `path` attributes. +--- + +# nsxt_policy_services + +This data source builds a list of the whole policy Services table. Such list can be referenced in configuration to obtain object identifier attributes lookup 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" "servicelist" { +} + +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.servicelist.items[index(data.nsxt_policy_services.servicelist.service_from_list.*.display_name, "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` - List of policy service entries. + * `id` - The ID of the service. + * `display_name` - Display name of the service entry. + * `path` - The NSX path of the policy resource.