From 9c70dfb3afb8229b288f38c514fbf2f4a3301a11 Mon Sep 17 00:00:00 2001 From: Wojciech Spyra Date: Fri, 8 Nov 2024 15:13:24 +0100 Subject: [PATCH] Add policy assignment resource and data source (#91) applying change requests --- gen/definitions/policyassignments.yaml | 6 +- .../data_source_fmc_policy_assignments.go | 193 ------------------ ...data_source_fmc_policy_assignments_test.go | 102 --------- .../resource_fmc_policy_assignments_test.go | 10 +- 4 files changed, 12 insertions(+), 299 deletions(-) delete mode 100644 internal/provider/data_source_fmc_policy_assignments.go delete mode 100644 internal/provider/data_source_fmc_policy_assignments_test.go diff --git a/gen/definitions/policyassignments.yaml b/gen/definitions/policyassignments.yaml index 90bd6d59..7148965b 100644 --- a/gen/definitions/policyassignments.yaml +++ b/gen/definitions/policyassignments.yaml @@ -5,6 +5,7 @@ no_delete: true no_data_source: true no_import: true doc_category: Policy Assignments +test_tags: [TF_VAR_target_id] attributes: - model_name: type type: String @@ -43,6 +44,7 @@ attributes: id: true mandatory: true example: "9862719c-8d5f-11ef-99a6-aef0794da1c1" + test_value: var.target_id - model_name: type type: String enum_values: [Device,DeviceHAPair,DeviceGroup] @@ -65,4 +67,6 @@ test_prerequisites: |- default_action_send_syslog = false name = "policy-example-test" rules = [] - } \ No newline at end of file + } + + variable "target_id" { default = null } // tests will set $TF_VAR_target_id \ No newline at end of file diff --git a/internal/provider/data_source_fmc_policy_assignments.go b/internal/provider/data_source_fmc_policy_assignments.go deleted file mode 100644 index 08f8f41f..00000000 --- a/internal/provider/data_source_fmc_policy_assignments.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright © 2023 Cisco Systems, Inc. and its affiliates. -// All rights reserved. -// -// Licensed under the Mozilla Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://mozilla.org/MPL/2.0/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: MPL-2.0 - -package provider - -// Section below is generated&owned by "gen/generator.go". //template:begin imports -import ( - "context" - "fmt" - "net/url" - - "github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/netascode/go-fmc" - "github.com/tidwall/gjson" -) - -// End of section. //template:end imports - -// Section below is generated&owned by "gen/generator.go". //template:begin model - -// Ensure the implementation satisfies the expected interfaces. -var ( - _ datasource.DataSource = &PolicyAssignmentsDataSource{} - _ datasource.DataSourceWithConfigure = &PolicyAssignmentsDataSource{} -) - -func NewPolicyAssignmentsDataSource() datasource.DataSource { - return &PolicyAssignmentsDataSource{} -} - -type PolicyAssignmentsDataSource struct { - client *fmc.Client -} - -func (d *PolicyAssignmentsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_policy_assignments" -} - -func (d *PolicyAssignmentsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = schema.Schema{ - // This description is used by the documentation generator and the language server. - MarkdownDescription: "This data source can read the Policy Assignments.", - - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - MarkdownDescription: "The id of the object", - Optional: true, - Computed: true, - }, - "domain": schema.StringAttribute{ - MarkdownDescription: "The name of the FMC domain", - Optional: true, - }, - "name": schema.StringAttribute{ - MarkdownDescription: "User-created name of the resource.", - Optional: true, - Computed: true, - }, - "type": schema.StringAttribute{ - MarkdownDescription: "", - Computed: true, - }, - "policy_id": schema.StringAttribute{ - MarkdownDescription: "", - Computed: true, - }, - "targets": schema.SetNestedAttribute{ - MarkdownDescription: "", - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - MarkdownDescription: "", - Computed: true, - }, - "type": schema.StringAttribute{ - MarkdownDescription: "", - Computed: true, - }, - "name": schema.StringAttribute{ - MarkdownDescription: "", - Computed: true, - }, - }, - }, - }, - }, - } -} -func (d *PolicyAssignmentsDataSource) ConfigValidators(ctx context.Context) []datasource.ConfigValidator { - return []datasource.ConfigValidator{ - datasourcevalidator.ExactlyOneOf( - path.MatchRoot("id"), - path.MatchRoot("name"), - ), - } -} - -func (d *PolicyAssignmentsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { - if req.ProviderData == nil { - return - } - - d.client = req.ProviderData.(*FmcProviderData).Client -} - -// End of section. //template:end model - -// Section below is generated&owned by "gen/generator.go". //template:begin read - -func (d *PolicyAssignmentsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var config PolicyAssignments - - // Read config - diags := req.Config.Get(ctx, &config) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - // Set request domain if provided - reqMods := [](func(*fmc.Req)){} - if !config.Domain.IsNull() && config.Domain.ValueString() != "" { - reqMods = append(reqMods, fmc.DomainName(config.Domain.ValueString())) - } - - tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.Id.String())) - if config.Id.IsNull() && !config.Name.IsNull() { - offset := 0 - limit := 1000 - for page := 1; ; page++ { - queryString := fmt.Sprintf("?limit=%d&offset=%d", limit, offset) - res, err := d.client.Get(config.getPath()+queryString, reqMods...) - if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve objects, got error: %s", err)) - return - } - if value := res.Get("items"); len(value.Array()) > 0 { - value.ForEach(func(k, v gjson.Result) bool { - if config.Name.ValueString() == v.Get("name").String() { - config.Id = types.StringValue(v.Get("id").String()) - tflog.Debug(ctx, fmt.Sprintf("%s: Found object with name '%v', id: %v", config.Id.String(), config.Name.ValueString(), config.Id.String())) - return false - } - return true - }) - } - if !config.Id.IsNull() || !res.Get("paging.next.0").Exists() { - break - } - offset += limit - } - - if config.Id.IsNull() { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to find object with name: %s", config.Name.ValueString())) - return - } - } - - res, err := d.client.Get(config.getPath()+"/"+url.QueryEscape(config.Id.ValueString()), reqMods...) - if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err)) - return - } - - config.fromBody(ctx, res) - - tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString())) - - diags = resp.State.Set(ctx, &config) - resp.Diagnostics.Append(diags...) -} - -// End of section. //template:end read diff --git a/internal/provider/data_source_fmc_policy_assignments_test.go b/internal/provider/data_source_fmc_policy_assignments_test.go deleted file mode 100644 index a07d32f9..00000000 --- a/internal/provider/data_source_fmc_policy_assignments_test.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright © 2023 Cisco Systems, Inc. and its affiliates. -// All rights reserved. -// -// Licensed under the Mozilla Public License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://mozilla.org/MPL/2.0/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: MPL-2.0 - -package provider - -// Section below is generated&owned by "gen/generator.go". //template:begin imports -import ( - "testing" - - "github.com/hashicorp/terraform-plugin-testing/helper/resource" -) - -// End of section. //template:end imports - -// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource - -func TestAccDataSourceFmcPolicyAssignments(t *testing.T) { - var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "name", "AccessPolicyName")) - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "type", "AccessPolicy")) - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "policy_id", "0050568A-2561-0ed3-0000-004294972836")) - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "targets.0.id", "9862719c-8d5f-11ef-99a6-aef0794da1c1")) - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "targets.0.type", "DeviceGroup")) - checks = append(checks, resource.TestCheckResourceAttr("data.fmc_policy_assignments.test", "targets.0.name", "FTD_Device1")) - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - { - Config: testAccDataSourceFmcPolicyAssignmentsConfig(), - Check: resource.ComposeTestCheckFunc(checks...), - }, - { - Config: testAccNamedDataSourceFmcPolicyAssignmentsConfig(), - Check: resource.ComposeTestCheckFunc(checks...), - }, - }, - }) -} - -// End of section. //template:end testAccDataSource - -// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites -// End of section. //template:end testPrerequisites - -// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig - -func testAccDataSourceFmcPolicyAssignmentsConfig() string { - config := `resource "fmc_policy_assignments" "test" {` + "\n" - config += ` name = "AccessPolicyName"` + "\n" - config += ` type = "AccessPolicy"` + "\n" - config += ` policy_id = "0050568A-2561-0ed3-0000-004294972836"` + "\n" - config += ` targets = [{` + "\n" - config += ` id = "9862719c-8d5f-11ef-99a6-aef0794da1c1"` + "\n" - config += ` type = "DeviceGroup"` + "\n" - config += ` name = "FTD_Device1"` + "\n" - config += ` }]` + "\n" - config += `}` + "\n" - - config += ` - data "fmc_policy_assignments" "test" { - id = fmc_policy_assignments.test.id - } - ` - return config -} - -func testAccNamedDataSourceFmcPolicyAssignmentsConfig() string { - config := `resource "fmc_policy_assignments" "test" {` + "\n" - config += ` name = "AccessPolicyName"` + "\n" - config += ` type = "AccessPolicy"` + "\n" - config += ` policy_id = "0050568A-2561-0ed3-0000-004294972836"` + "\n" - config += ` targets = [{` + "\n" - config += ` id = "9862719c-8d5f-11ef-99a6-aef0794da1c1"` + "\n" - config += ` type = "DeviceGroup"` + "\n" - config += ` name = "FTD_Device1"` + "\n" - config += ` }]` + "\n" - config += `}` + "\n" - - config += ` - data "fmc_policy_assignments" "test" { - name = fmc_policy_assignments.test.name - } - ` - return config -} - -// End of section. //template:end testAccDataSourceConfig diff --git a/internal/provider/resource_fmc_policy_assignments_test.go b/internal/provider/resource_fmc_policy_assignments_test.go index 6b5c3f2b..35908162 100644 --- a/internal/provider/resource_fmc_policy_assignments_test.go +++ b/internal/provider/resource_fmc_policy_assignments_test.go @@ -30,8 +30,10 @@ import ( // Section below is generated&owned by "gen/generator.go". //template:begin testAcc func TestAccFmcPolicyAssignments(t *testing.T) { + if os.Getenv("TF_VAR_target_id") == "" { + t.Skip("skipping test, set environment variable TF_VAR_target_id") + } var checks []resource.TestCheckFunc - checks = append(checks, resource.TestCheckResourceAttr("fmc_policy_assignments.test", "targets.0.id", "9862719c-8d5f-11ef-99a6-aef0794da1c1")) checks = append(checks, resource.TestCheckResourceAttr("fmc_policy_assignments.test", "targets.0.type", "DeviceGroup")) var steps []resource.TestStep @@ -67,6 +69,8 @@ resource "fmc_access_control_policy" "example" { name = "policy-example-test" rules = [] } + +variable "target_id" { default = null } // tests will set $TF_VAR_target_id ` // End of section. //template:end testPrerequisites @@ -77,7 +81,7 @@ func testAccFmcPolicyAssignmentsConfig_minimum() string { config := `resource "fmc_policy_assignments" "test" {` + "\n" config += ` policy_id = fmc_access_control_policy.example.id` + "\n" config += ` targets = [{` + "\n" - config += ` id = "9862719c-8d5f-11ef-99a6-aef0794da1c1"` + "\n" + config += ` id = var.target_id` + "\n" config += ` type = "DeviceGroup"` + "\n" config += ` }]` + "\n" config += `}` + "\n" @@ -92,7 +96,7 @@ func testAccFmcPolicyAssignmentsConfig_all() string { config := `resource "fmc_policy_assignments" "test" {` + "\n" config += ` policy_id = fmc_access_control_policy.example.id` + "\n" config += ` targets = [{` + "\n" - config += ` id = "9862719c-8d5f-11ef-99a6-aef0794da1c1"` + "\n" + config += ` id = var.target_id` + "\n" config += ` type = "DeviceGroup"` + "\n" config += ` }]` + "\n" config += `}` + "\n"