diff --git a/.changelog/42663.txt b/.changelog/42663.txt new file mode 100644 index 00000000000..7eadbff48e9 --- /dev/null +++ b/.changelog/42663.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_verifiedpermissions_policy_store: Add `tags` argument and `tags_all` attribute. This functionality requires the `verifiedpermissions:ListTagsForResource`, `verifiedpermissions:TagResource`, and `verifiedpermissions:UntagResource` IAM permissions +``` + +```release-note:enhancement +data-source/aws_verifiedpermissions_policy_store: Add `tags` attribute. This functionality requires the `verifiedpermissions:ListTagsForResource` IAM permission +``` \ No newline at end of file diff --git a/internal/service/verifiedpermissions/generate.go b/internal/service/verifiedpermissions/generate.go index 6ea5165dc1f..5d687fd4478 100644 --- a/internal/service/verifiedpermissions/generate.go +++ b/internal/service/verifiedpermissions/generate.go @@ -1,6 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 +//go:generate go run ../../generate/tags/main.go -ListTags -KVTValues=true -ServiceTagsMap -UpdateTags //go:generate go run ../../generate/servicepackage/main.go // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/verifiedpermissions/policy_store.go b/internal/service/verifiedpermissions/policy_store.go index 97a7a588a80..6ac7fcb7a37 100644 --- a/internal/service/verifiedpermissions/policy_store.go +++ b/internal/service/verifiedpermissions/policy_store.go @@ -10,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/verifiedpermissions" awstypes "github.com/aws/aws-sdk-go-v2/service/verifiedpermissions/types" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" - "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" @@ -18,18 +17,22 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + sdkid "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" "github.com/hashicorp/terraform-provider-aws/internal/framework" - "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) // @FrameworkResource("aws_verifiedpermissions_policy_store", name="Policy Store") +// @Tags(identifierAttribute="arn") +// @Testing(tagsTest=false) func newResourcePolicyStore(context.Context) (resource.ResourceWithConfigure, error) { r := &resourcePolicyStore{} @@ -42,6 +45,7 @@ const ( type resourcePolicyStore struct { framework.ResourceWithConfigure + framework.WithImportByID } func (r *resourcePolicyStore) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { @@ -58,6 +62,8 @@ func (r *resourcePolicyStore) Schema(ctx context.Context, request resource.Schem stringplanmodifier.UseStateForUnknown(), }, }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), }, Blocks: map[string]schema.Block{ "validation_settings": schema.ListNestedBlock{ @@ -82,26 +88,26 @@ func (r *resourcePolicyStore) Schema(ctx context.Context, request resource.Schem } func (r *resourcePolicyStore) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { - conn := r.Meta().VerifiedPermissionsClient(ctx) - var plan resourcePolicyStoreData - - response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) - + var data resourcePolicyStoreData + response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) if response.Diagnostics.HasError() { return } - input := &verifiedpermissions.CreatePolicyStoreInput{} - response.Diagnostics.Append(flex.Expand(ctx, plan, input)...) + conn := r.Meta().VerifiedPermissionsClient(ctx) + var input verifiedpermissions.CreatePolicyStoreInput + response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) if response.Diagnostics.HasError() { return } - clientToken := id.UniqueId() + // Additional fields. + clientToken := sdkid.UniqueId() input.ClientToken = aws.String(clientToken) + input.Tags = getTagsIn(ctx) - output, err := conn.CreatePolicyStore(ctx, input) + output, err := conn.CreatePolicyStore(ctx, &input) if err != nil { response.Diagnostics.AddError( @@ -111,111 +117,102 @@ func (r *resourcePolicyStore) Create(ctx context.Context, request resource.Creat return } - state := plan - state.ID = flex.StringToFramework(ctx, output.PolicyStoreId) - - response.Diagnostics.Append(flex.Flatten(ctx, output, &state)...) - + // Set values for unknowns. + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) if response.Diagnostics.HasError() { return } + data.ID = fwflex.StringToFramework(ctx, output.PolicyStoreId) - response.Diagnostics.Append(response.State.Set(ctx, &state)...) + response.Diagnostics.Append(response.State.Set(ctx, &data)...) } func (r *resourcePolicyStore) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { - conn := r.Meta().VerifiedPermissionsClient(ctx) - var state resourcePolicyStoreData - - response.Diagnostics.Append(request.State.Get(ctx, &state)...) - + var data resourcePolicyStoreData + response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return } - output, err := findPolicyStoreByID(ctx, conn, state.ID.ValueString()) + conn := r.Meta().VerifiedPermissionsClient(ctx) + + output, err := findPolicyStoreByID(ctx, conn, data.ID.ValueString()) if tfresource.NotFound(err) { + response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) response.State.RemoveResource(ctx) + return } if err != nil { response.Diagnostics.AddError( - create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionReading, ResNamePolicyStore, state.PolicyStoreID.ValueString(), err), + create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionReading, ResNamePolicyStore, data.PolicyStoreID.ValueString(), err), err.Error(), ) return } - response.Diagnostics.Append(flex.Flatten(ctx, output, &state)...) - + // Set attributes for import. + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) if response.Diagnostics.HasError() { return } - response.Diagnostics.Append(response.State.Set(ctx, &state)...) + response.Diagnostics.Append(response.State.Set(ctx, &data)...) } func (r *resourcePolicyStore) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { - conn := r.Meta().VerifiedPermissionsClient(ctx) - var state, plan resourcePolicyStoreData - - response.Diagnostics.Append(request.State.Get(ctx, &state)...) - + var old, new resourcePolicyStoreData + response.Diagnostics.Append(request.State.Get(ctx, &old)...) if response.Diagnostics.HasError() { return } - - response.Diagnostics.Append(request.Plan.Get(ctx, &plan)...) - + response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) if response.Diagnostics.HasError() { return } - if !plan.Description.Equal(state.Description) || !plan.ValidationSettings.Equal(state.ValidationSettings) { - input := &verifiedpermissions.UpdatePolicyStoreInput{} - response.Diagnostics.Append(flex.Expand(ctx, plan, input)...) + conn := r.Meta().VerifiedPermissionsClient(ctx) + if !new.Description.Equal(old.Description) || !new.ValidationSettings.Equal(old.ValidationSettings) { + var input verifiedpermissions.UpdatePolicyStoreInput + response.Diagnostics.Append(fwflex.Expand(ctx, new, &input)...) if response.Diagnostics.HasError() { return } - output, err := conn.UpdatePolicyStore(ctx, input) + _, err := conn.UpdatePolicyStore(ctx, &input) if err != nil { response.Diagnostics.AddError( - create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionUpdating, ResNamePolicyStore, state.PolicyStoreID.ValueString(), err), + create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionUpdating, ResNamePolicyStore, old.PolicyStoreID.ValueString(), err), err.Error(), ) return } - - response.Diagnostics.Append(flex.Flatten(ctx, output, &plan)...) } - response.Diagnostics.Append(response.State.Set(ctx, &plan)...) + response.Diagnostics.Append(response.State.Set(ctx, &new)...) } func (r *resourcePolicyStore) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { - conn := r.Meta().VerifiedPermissionsClient(ctx) - var state resourcePolicyStoreData - - response.Diagnostics.Append(request.State.Get(ctx, &state)...) - + var data resourcePolicyStoreData + response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return } + conn := r.Meta().VerifiedPermissionsClient(ctx) + tflog.Debug(ctx, "deleting Verified Permissions Policy Store", map[string]any{ - names.AttrID: state.ID.ValueString(), + names.AttrID: data.ID.ValueString(), }) - input := &verifiedpermissions.DeletePolicyStoreInput{ - PolicyStoreId: flex.StringFromFramework(ctx, state.ID), + input := verifiedpermissions.DeletePolicyStoreInput{ + PolicyStoreId: fwflex.StringFromFramework(ctx, data.ID), } - - _, err := conn.DeletePolicyStore(ctx, input) + _, err := conn.DeletePolicyStore(ctx, &input) if errs.IsA[*awstypes.ResourceNotFoundException](err) { return @@ -223,22 +220,20 @@ func (r *resourcePolicyStore) Delete(ctx context.Context, request resource.Delet if err != nil { response.Diagnostics.AddError( - create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionDeleting, ResNamePolicyStore, state.PolicyStoreID.ValueString(), err), + create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionDeleting, ResNamePolicyStore, data.PolicyStoreID.ValueString(), err), err.Error(), ) return } } -func (r *resourcePolicyStore) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root(names.AttrID), request, response) -} - type resourcePolicyStoreData struct { ARN types.String `tfsdk:"arn"` Description types.String `tfsdk:"description"` ID types.String `tfsdk:"id"` PolicyStoreID types.String `tfsdk:"policy_store_id"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` ValidationSettings fwtypes.ListNestedObjectValueOf[validationSettings] `tfsdk:"validation_settings"` } diff --git a/internal/service/verifiedpermissions/policy_store_data_source.go b/internal/service/verifiedpermissions/policy_store_data_source.go index 1c8fa27ec9f..eac93726ffe 100644 --- a/internal/service/verifiedpermissions/policy_store_data_source.go +++ b/internal/service/verifiedpermissions/policy_store_data_source.go @@ -15,10 +15,12 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/framework" fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/names" ) // @FrameworkDataSource("aws_verifiedpermissions_policy_store", name="Policy Store") +// @Tags(identifierAttribute="arn") func newDataSourcePolicyStore(context.Context) (datasource.DataSourceWithConfigure, error) { return &dataSourcePolicyStore{}, nil } @@ -31,8 +33,8 @@ type dataSourcePolicyStore struct { framework.DataSourceWithConfigure } -func (d *dataSourcePolicyStore) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = schema.Schema{ +func (d *dataSourcePolicyStore) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { + response.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ names.AttrARN: framework.ARNAttributeComputedOnly(), names.AttrCreatedDate: schema.StringAttribute{ @@ -49,6 +51,7 @@ func (d *dataSourcePolicyStore) Schema(ctx context.Context, req datasource.Schem CustomType: timetypes.RFC3339Type{}, Computed: true, }, + names.AttrTags: tftags.TagsAttributeComputedOnly(), "validation_settings": schema.ListAttribute{ CustomType: fwtypes.NewListNestedObjectTypeOf[validationSettingsDataSource](ctx), ElementType: fwtypes.NewObjectTypeOf[validationSettingsDataSource](ctx), @@ -57,32 +60,31 @@ func (d *dataSourcePolicyStore) Schema(ctx context.Context, req datasource.Schem }, } } -func (d *dataSourcePolicyStore) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - conn := d.Meta().VerifiedPermissionsClient(ctx) - +func (d *dataSourcePolicyStore) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { var data dataSourcePolicyStoreData - resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { + response.Diagnostics.Append(request.Config.Get(ctx, &data)...) + if response.Diagnostics.HasError() { return } - out, err := findPolicyStoreByID(ctx, conn, data.ID.ValueString()) + conn := d.Meta().VerifiedPermissionsClient(ctx) + + output, err := findPolicyStoreByID(ctx, conn, data.ID.ValueString()) if err != nil { - resp.Diagnostics.AddError( + response.Diagnostics.AddError( create.ProblemStandardMessage(names.VerifiedPermissions, create.ErrActionReading, DSNamePolicyStore, data.ID.ValueString(), err), err.Error(), ) return } - resp.Diagnostics.Append(fwflex.Flatten(ctx, out, &data)...) - - if resp.Diagnostics.HasError() { + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) + if response.Diagnostics.HasError() { return } - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + response.Diagnostics.Append(response.State.Set(ctx, &data)...) } type dataSourcePolicyStoreData struct { @@ -91,6 +93,7 @@ type dataSourcePolicyStoreData struct { Description types.String `tfsdk:"description"` ID types.String `tfsdk:"id"` LastUpdatedDate timetypes.RFC3339 `tfsdk:"last_updated_date"` + Tags tftags.Map `tfsdk:"tags"` ValidationSettings fwtypes.ListNestedObjectValueOf[validationSettingsDataSource] `tfsdk:"validation_settings"` } diff --git a/internal/service/verifiedpermissions/policy_store_data_source_test.go b/internal/service/verifiedpermissions/policy_store_data_source_test.go index 023dc3761e5..6ed4b4a466f 100644 --- a/internal/service/verifiedpermissions/policy_store_data_source_test.go +++ b/internal/service/verifiedpermissions/policy_store_data_source_test.go @@ -42,6 +42,41 @@ func TestAccVerifiedPermissionsPolicyStoreDataSource_basic(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, names.AttrARN, dataSourceName, names.AttrARN), resource.TestCheckResourceAttrSet(dataSourceName, names.AttrCreatedDate), resource.TestCheckResourceAttrSet(dataSourceName, names.AttrLastUpdatedDate), + resource.TestCheckResourceAttr(dataSourceName, acctest.CtTagsPercent, "0"), + ), + }, + }, + }) +} + +func TestAccVerifiedPermissionsPolicyStoreDataSource_tags(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var policystore verifiedpermissions.GetPolicyStoreOutput + dataSourceName := "data.aws_verifiedpermissions_policy_store.test" + resourceName := "aws_verifiedpermissions_policy_store.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.VerifiedPermissionsEndpointID) + testAccPolicyStoresPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.VerifiedPermissionsServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckPolicyStoreDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccPolicyStoreDataSourceConfig_tags("OFF", acctest.CtKey1, acctest.CtValue1, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeTestCheckFunc( + testAccCheckPolicyStoreExists(ctx, dataSourceName, &policystore), + resource.TestCheckResourceAttrPair(resourceName, names.AttrARN, dataSourceName, names.AttrARN), + resource.TestCheckResourceAttr(dataSourceName, acctest.CtTagsPercent, "2"), + resource.TestCheckResourceAttrPair(resourceName, acctest.CtTagsKey1, dataSourceName, acctest.CtTagsKey1), + resource.TestCheckResourceAttrPair(resourceName, acctest.CtTagsKey2, dataSourceName, acctest.CtTagsKey2), ), }, }, @@ -62,3 +97,22 @@ data "aws_verifiedpermissions_policy_store" "test" { } `, mode) } + +func testAccPolicyStoreDataSourceConfig_tags(mode string, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_verifiedpermissions_policy_store" "test" { + description = "Terraform acceptance test" + validation_settings { + mode = %[1]q + } + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} + +data "aws_verifiedpermissions_policy_store" "test" { + id = aws_verifiedpermissions_policy_store.test.id +} +`, mode, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/internal/service/verifiedpermissions/policy_store_test.go b/internal/service/verifiedpermissions/policy_store_test.go index 7baf6a80917..d4dc48b363d 100644 --- a/internal/service/verifiedpermissions/policy_store_test.go +++ b/internal/service/verifiedpermissions/policy_store_test.go @@ -46,6 +46,8 @@ func TestAccVerifiedPermissionsPolicyStore_basic(t *testing.T) { testAccCheckPolicyStoreExists(ctx, resourceName, &policystore), resource.TestCheckResourceAttr(resourceName, "validation_settings.0.mode", "OFF"), resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "Terraform acceptance test"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsAllPercent, "0"), acctest.MatchResourceAttrGlobalARN(ctx, resourceName, names.AttrARN, "verifiedpermissions", regexache.MustCompile(`policy-store/.+$`)), ), }, @@ -125,6 +127,59 @@ func TestAccVerifiedPermissionsPolicyStore_disappears(t *testing.T) { }) } +func TestAccVerifiedPermissionsPolicyStore_tags(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var policystore verifiedpermissions.GetPolicyStoreOutput + resourceName := "aws_verifiedpermissions_policy_store.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.VerifiedPermissionsEndpointID) + testAccPolicyStoresPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.VerifiedPermissionsServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckPolicyStoreDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccPolicyStoreConfig_tags1("OFF", acctest.CtKey1, acctest.CtValue1), + Check: resource.ComposeTestCheckFunc( + testAccCheckPolicyStoreExists(ctx, resourceName, &policystore), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccPolicyStoreConfig_tags2("OFF", acctest.CtKey1, acctest.CtValue1, acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeTestCheckFunc( + testAccCheckPolicyStoreExists(ctx, resourceName, &policystore), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "2"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2), + ), + }, + { + Config: testAccPolicyStoreConfig_tags1("OFF", acctest.CtKey2, acctest.CtValue2), + Check: resource.ComposeTestCheckFunc( + testAccCheckPolicyStoreExists(ctx, resourceName, &policystore), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2), + ), + }, + }, + }) +} + func testAccCheckPolicyStoreDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).VerifiedPermissionsClient(ctx) @@ -198,3 +253,30 @@ resource "aws_verifiedpermissions_policy_store" "test" { } }`, mode) } + +func testAccPolicyStoreConfig_tags1(mode, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_verifiedpermissions_policy_store" "test" { + description = "Terraform acceptance test" + validation_settings { + mode = %[1]q + } + tags = { + %[2]q = %[3]q + } +}`, mode, tagKey1, tagValue1) +} + +func testAccPolicyStoreConfig_tags2(mode, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_verifiedpermissions_policy_store" "test" { + description = "Terraform acceptance test" + validation_settings { + mode = %[1]q + } + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +}`, mode, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/internal/service/verifiedpermissions/service_package_gen.go b/internal/service/verifiedpermissions/service_package_gen.go index 13ee626436b..8a49e0e0478 100644 --- a/internal/service/verifiedpermissions/service_package_gen.go +++ b/internal/service/verifiedpermissions/service_package_gen.go @@ -20,6 +20,9 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv Factory: newDataSourcePolicyStore, TypeName: "aws_verifiedpermissions_policy_store", Name: "Policy Store", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }, }, } } @@ -40,6 +43,9 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic Factory: newResourcePolicyStore, TypeName: "aws_verifiedpermissions_policy_store", Name: "Policy Store", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }, }, { Factory: newResourcePolicyTemplate, diff --git a/internal/service/verifiedpermissions/tags_gen.go b/internal/service/verifiedpermissions/tags_gen.go new file mode 100644 index 00000000000..0b4febbb898 --- /dev/null +++ b/internal/service/verifiedpermissions/tags_gen.go @@ -0,0 +1,128 @@ +// Code generated by internal/generate/tags/main.go; DO NOT EDIT. +package verifiedpermissions + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/verifiedpermissions" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/logging" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/types/option" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// listTags lists verifiedpermissions service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func listTags(ctx context.Context, conn *verifiedpermissions.Client, identifier string, optFns ...func(*verifiedpermissions.Options)) (tftags.KeyValueTags, error) { + input := verifiedpermissions.ListTagsForResourceInput{ + ResourceArn: aws.String(identifier), + } + + output, err := conn.ListTagsForResource(ctx, &input, optFns...) + + if err != nil { + return tftags.New(ctx, nil), err + } + + return keyValueTags(ctx, output.Tags), nil +} + +// ListTags lists verifiedpermissions service tags and set them in Context. +// It is called from outside this package. +func (p *servicePackage) ListTags(ctx context.Context, meta any, identifier string) error { + tags, err := listTags(ctx, meta.(*conns.AWSClient).VerifiedPermissionsClient(ctx), identifier) + + if err != nil { + return err + } + + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(tags) + } + + return nil +} + +// map[string]string handling + +// svcTags returns verifiedpermissions service tags. +func svcTags(tags tftags.KeyValueTags) map[string]string { + return tags.Map() +} + +// keyValueTags creates tftags.KeyValueTags from verifiedpermissions service tags. +func keyValueTags(ctx context.Context, tags map[string]string) tftags.KeyValueTags { + return tftags.New(ctx, tags) +} + +// getTagsIn returns verifiedpermissions service tags from Context. +// nil is returned if there are no input tags. +func getTagsIn(ctx context.Context) map[string]string { + if inContext, ok := tftags.FromContext(ctx); ok { + if tags := svcTags(inContext.TagsIn.UnwrapOrDefault()); len(tags) > 0 { + return tags + } + } + + return nil +} + +// setTagsOut sets verifiedpermissions service tags in Context. +func setTagsOut(ctx context.Context, tags map[string]string) { + if inContext, ok := tftags.FromContext(ctx); ok { + inContext.TagsOut = option.Some(keyValueTags(ctx, tags)) + } +} + +// updateTags updates verifiedpermissions service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func updateTags(ctx context.Context, conn *verifiedpermissions.Client, identifier string, oldTagsMap, newTagsMap any, optFns ...func(*verifiedpermissions.Options)) error { + oldTags := tftags.New(ctx, oldTagsMap) + newTags := tftags.New(ctx, newTagsMap) + + ctx = tflog.SetField(ctx, logging.KeyResourceId, identifier) + + removedTags := oldTags.Removed(newTags) + removedTags = removedTags.IgnoreSystem(names.VerifiedPermissions) + if len(removedTags) > 0 { + input := verifiedpermissions.UntagResourceInput{ + ResourceArn: aws.String(identifier), + TagKeys: removedTags.Keys(), + } + + _, err := conn.UntagResource(ctx, &input, optFns...) + + if err != nil { + return fmt.Errorf("untagging resource (%s): %w", identifier, err) + } + } + + updatedTags := oldTags.Updated(newTags) + updatedTags = updatedTags.IgnoreSystem(names.VerifiedPermissions) + if len(updatedTags) > 0 { + input := verifiedpermissions.TagResourceInput{ + ResourceArn: aws.String(identifier), + Tags: svcTags(updatedTags), + } + + _, err := conn.TagResource(ctx, &input, optFns...) + + if err != nil { + return fmt.Errorf("tagging resource (%s): %w", identifier, err) + } + } + + return nil +} + +// UpdateTags updates verifiedpermissions service tags. +// It is called from outside this package. +func (p *servicePackage) UpdateTags(ctx context.Context, meta any, identifier string, oldTags, newTags any) error { + return updateTags(ctx, meta.(*conns.AWSClient).VerifiedPermissionsClient(ctx), identifier, oldTags, newTags) +} diff --git a/website/docs/d/verifiedpermissions_policy_store.html.markdown b/website/docs/d/verifiedpermissions_policy_store.html.markdown index e75674e10bd..c76f5cd72e0 100644 --- a/website/docs/d/verifiedpermissions_policy_store.html.markdown +++ b/website/docs/d/verifiedpermissions_policy_store.html.markdown @@ -33,4 +33,5 @@ This data source exports the following attributes in addition to the arguments a * `arn` - The ARN of the Policy Store. * `created_date` - The date the Policy Store was created. * `last_updated_date` - The date the Policy Store was last updated. +* `tags` - Map of key-value pairs associated with the policy store. * `validation_settings` - Validation settings for the policy store. diff --git a/website/docs/r/verifiedpermissions_policy_store.html.markdown b/website/docs/r/verifiedpermissions_policy_store.html.markdown index a16ffd03b46..1c19d41ce4e 100644 --- a/website/docs/r/verifiedpermissions_policy_store.html.markdown +++ b/website/docs/r/verifiedpermissions_policy_store.html.markdown @@ -32,6 +32,7 @@ The following arguments are required: The following arguments are optional: * `description` - (Optional) A description of the Policy Store. +* `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attribute Reference @@ -39,6 +40,7 @@ This resource exports the following attributes in addition to the arguments abov * `policy_store_id` - The ID of the Policy Store. * `arn` - The ARN of the Policy Store. +* `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import