From 06b59bf26b75988db6696cbf096747b853facb2b 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 | 50 ++++++++++++ nsxt/data_source_nsxt_policy_groups_test.go | 78 +++++++++++++++++++ nsxt/data_source_nsxt_policy_services.go | 47 +++++++++++ nsxt/data_source_nsxt_policy_services_test.go | 69 ++++++++++++++++ nsxt/provider.go | 2 + website/docs/d/ns_services.html.markdown | 2 +- website/docs/d/policy_groups.html.markdown | 63 +++++++++++++++ website/docs/d/policy_services.html.markdown | 47 +++++++++++ 8 files changed, 357 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..cc09e8bf4 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups.go @@ -0,0 +1,50 @@ +// © Broadcom. All Rights Reserved. +// The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +// 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.TypeMap, + Description: "Mapping of service policy path by display name", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +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]string) + results, err := client.List(domainName, nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + groupsMap[*r.DisplayName] = *r.Path + } + + d.Set("items", groupsMap) + d.SetId(newUUID()) + 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..d646b53ff --- /dev/null +++ b/nsxt/data_source_nsxt_policy_groups_test.go @@ -0,0 +1,78 @@ +// © Broadcom. All Rights Reserved. +// The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +// 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 { +// Get id from path + path_split = split("/", data.nsxt_policy_groups.test.items["%s"]) + group_id = element(local.path_split, length(local.path_split) - 1) +} + +data "nsxt_policy_group" "test" { +%s + id = local.group_id +} +`, context, groupName, context) +} diff --git a/nsxt/data_source_nsxt_policy_services.go b/nsxt/data_source_nsxt_policy_services.go new file mode 100644 index 000000000..c8d121865 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services.go @@ -0,0 +1,47 @@ +// © Broadcom. All Rights Reserved. +// The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +// 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.TypeMap, + Description: "Mapping of services policy path by display name", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func dataSourceNsxtPolicyServicesRead(d *schema.ResourceData, m interface{}) error { + connector := getPolicyConnector(m) + client := infra.NewServicesClient(getSessionContext(d, m), connector) + + servicesMap := make(map[string]string) + results, err := client.List(nil, nil, nil, nil, nil, nil, nil) + if err != nil { + return err + } + for _, r := range results.Results { + servicesMap[*r.DisplayName] = *r.Path + } + + d.Set("items", servicesMap) + d.SetId(newUUID()) + 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..7295dc356 --- /dev/null +++ b/nsxt/data_source_nsxt_policy_services_test.go @@ -0,0 +1,69 @@ +// © Broadcom. All Rights Reserved. +// The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. +// 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 { +// Get id from path + path_split = split("/", data.nsxt_policy_services.test.items["%s"]) + service_id = element(local.path_split, length(local.path_split) - 1) +} + +data "nsxt_policy_service" "test" { +%s + id = local.service_id +} +`, context, serviceName, context) +} diff --git a/nsxt/provider.go b/nsxt/provider.go index 9c9d5a153..eb6f33b97 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -340,6 +340,8 @@ func Provider() *schema.Provider { "nsxt_vpc_ip_address_allocation": dataSourceNsxtVpcIpAddressAllocation(), "nsxt_policy_gateway_connection": dataSourceNsxtPolicyGatewayConnection(), "nsxt_policy_distributed_vlan_connection": dataSourceNsxtPolicyDistributedVlanConnection(), + "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..9fc9ab022 --- /dev/null +++ b/website/docs/d/policy_groups.html.markdown @@ -0,0 +1,63 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_groups" +description: A policy groups data source. This data source builds "display name to policy paths" map representation of the whole table. +--- + +# nsxt_policy_groups + +This data source builds a "name to paths" 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"], data.nsxt_policy_groups.items["Dogs"]] + action = "ALLOW" + services = [nsxt_policy_service.icmp.path] + logged = true + } + + rule { + display_name = "allow_udp" + source_groups = [data.nsxt_policy_groups.items["Fish"]] + sources_excluded = true + scope = [data.nsxt_policy_groups.items["Aquarium"]] + 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 policy paths keyed by display name. diff --git a/website/docs/d/policy_services.html.markdown b/website/docs/d/policy_services.html.markdown new file mode 100644 index 000000000..ab6adfb9a --- /dev/null +++ b/website/docs/d/policy_services.html.markdown @@ -0,0 +1,47 @@ +--- +subcategory: "Firewall" +layout: "nsxt" +page_title: "NSXT: policy_services" +description: A policy services data source. This data source builds "display name to policy path" map representation of the whole table. +--- + +# nsxt_policy_services + +This data source builds a "name to policy path" 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"] + + 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 policy paths keyed by display name.