@@ -6,11 +6,14 @@ import (
66 "path/filepath"
77 "time"
88
9+ "github.com/hashicorp/terraform-plugin-framework/attr"
10+ diagFramework "github.com/hashicorp/terraform-plugin-framework/diag"
911 "github.com/hashicorp/terraform-plugin-framework/path"
1012 "github.com/hashicorp/terraform-plugin-framework/resource"
1113 "github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
1214 "github.com/hashicorp/terraform-plugin-framework/resource/schema"
1315 "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
16+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/listdefault"
1417 "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1518 "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
1619 "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
@@ -101,22 +104,22 @@ func (m cleanUpFilePath) MarkdownDescription(ctx context.Context) string {
101104}
102105
103106func (m cleanUpFilePath ) PlanModifyString (_ context.Context , req planmodifier.StringRequest , resp * planmodifier.StringResponse ) {
104- // Do nothing if there is no state (resource is being created).
105- if req .State .Raw .IsNull () {
107+ // Do nothing if there is no state (resource is being created)
108+ // or if we're not in a refresh operation (since PlanOnly tests check for no changes)
109+ if req .State .Raw .IsNull () || ! req .PlanValue .IsUnknown () {
106110 return
107111 }
108112
109- // Do nothing if there is a known planned value.
110- if ! req .PlanValue .IsUnknown () {
111- return
112- }
113+ // For refresh operations, we want to ensure the state matches the API
114+ // The API likely normalizes paths, so we should clean them
115+ cleanedPath := filepath .Clean (req .StateValue .String ())
113116
114- // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up.
115- if req . ConfigValue . IsUnknown () {
116- return
117+ // Special case: if the cleaned path is empty or root, ensure it's "/"
118+ if cleanedPath == "." {
119+ cleanedPath = "/"
117120 }
118121
119- resp .PlanValue = types .StringValue (filepath . Clean ( req . StateValue . String ()) )
122+ resp .PlanValue = types .StringValue (cleanedPath )
120123}
121124
122125func (r * ResourceSecret ) Schema (ctx context.Context , request resource.SchemaRequest , response * resource.SchemaResponse ) {
@@ -137,7 +140,9 @@ func (r *ResourceSecret) Schema(ctx context.Context, request resource.SchemaRequ
137140 },
138141 "description" : schema.StringAttribute {
139142 Optional : true ,
143+ Computed : true ,
140144 Description : "Description of the secret" ,
145+ Default : stringdefault .StaticString ("" ),
141146 },
142147 "status" : schema.StringAttribute {
143148 Computed : true ,
@@ -176,6 +181,8 @@ func (r *ResourceSecret) Schema(ctx context.Context, request resource.SchemaRequ
176181 ElementType : types .StringType ,
177182 Description : "List of tags [\" tag1\" , \" tag2\" , ...] associated to secret" ,
178183 Optional : true ,
184+ Computed : true ,
185+ Default : listdefault .StaticValue (types .ListValueMust (types .StringType , []attr.Value {})),
179186 },
180187 "type" : schema.StringAttribute {
181188 PlanModifiers : []planmodifier.String {
@@ -281,11 +288,11 @@ func (r *ResourceSecret) Schema(ctx context.Context, request resource.SchemaRequ
281288}
282289
283290type ResourceSecretModel struct {
284- ID types.String `tfsdk:"id"`
285- Name types.String `tfsdk:"name"`
286- Protected types.Bool `tfsdk:"protected"`
287- Type types.String `tfsdk:"type"`
288- // Tags types.List `tfsdk:"tags"`
291+ ID types.String `tfsdk:"id"`
292+ Name types.String `tfsdk:"name"`
293+ Protected types.Bool `tfsdk:"protected"`
294+ Type types.String `tfsdk:"type"`
295+ Tags types.List `tfsdk:"tags"`
289296 Description types.String `tfsdk:"description"`
290297 Path types.String `tfsdk:"path"`
291298 // EphemeralPolicy types.String `tfsdk:"ephemeral_policy"`
@@ -299,8 +306,8 @@ type ResourceSecretModel struct {
299306 // Timeouts timeouts.Value `tfsdk:"timeouts"`
300307}
301308
302- func NewModelFromSecret (s secret.Secret ) * ResourceSecretModel {
303- return & ResourceSecretModel {
309+ func NewModelFromSecret (ctx context. Context , s secret.Secret ) ( * ResourceSecretModel , diagFramework. Diagnostics ) {
310+ model := & ResourceSecretModel {
304311 Name : types .StringValue (s .Name ),
305312 Status : types .StringValue (s .Status .String ()),
306313 ProjectID : types .StringValue (s .ProjectID ),
@@ -314,17 +321,29 @@ func NewModelFromSecret(s secret.Secret) *ResourceSecretModel {
314321 Region : types .StringValue (s .Region .String ()),
315322 Path : types .StringValue (s .Path ),
316323 }
324+
325+ tags , diags := types .ListValueFrom (ctx , types .StringType , s .Tags )
326+ model .Tags = tags
327+
328+ return model , diags
317329}
318330
319331func (r * ResourceSecret ) Create (ctx context.Context , request resource.CreateRequest , response * resource.CreateResponse ) {
320332 var data ResourceSecretModel
321333
322334 response .Diagnostics .Append (request .Plan .Get (ctx , & data )... )
323335
336+ if response .Diagnostics .HasError () {
337+ return
338+ }
339+
324340 secretCreateRequest := & secret.CreateSecretRequest {
325341 Name : data .Name .ValueString (),
326342 Protected : data .Protected .ValueBool (),
327- Type : secret .SecretType (data .Type .ValueString ()),
343+ }
344+
345+ if ! data .Type .IsNull () {
346+ secretCreateRequest .Type = secret .SecretType (data .Type .ValueString ())
328347 }
329348
330349 if ! data .Region .IsNull () {
@@ -335,9 +354,12 @@ func (r *ResourceSecret) Create(ctx context.Context, request resource.CreateRequ
335354 secretCreateRequest .ProjectID = data .ProjectID .ValueString ()
336355 }
337356
338- //if !data.Tags.IsNull() {
339- // secretCreateRequest.Tags = data.Tags.Elements()
340- //}
357+ if ! data .Tags .IsNull () {
358+ elements := make ([]string , 0 , len (data .Tags .Elements ()))
359+ diags := data .Tags .ElementsAs (ctx , & elements , false )
360+ response .Diagnostics .Append (diags ... )
361+ secretCreateRequest .Tags = elements
362+ }
341363
342364 if ! data .Description .IsNull () {
343365 secretCreateRequest .Description = data .Description .ValueStringPointer ()
@@ -384,7 +406,7 @@ func (r *ResourceSecret) Create(ctx context.Context, request resource.CreateRequ
384406 response .Diagnostics .Append (response .Identity .Set (ctx , identity )... )
385407
386408 // Save data into Terraform state
387- dataToSave := NewModelFromSecret (* apiResponse )
409+ dataToSave , _ := NewModelFromSecret (ctx , * apiResponse )
388410
389411 response .Diagnostics .Append (response .State .Set (ctx , & dataToSave )... )
390412}
@@ -451,7 +473,7 @@ func (r *ResourceSecret) Read(ctx context.Context, request resource.ReadRequest,
451473 //_ = d.Set("versions", versionsList)
452474
453475 // Save updated data into Terraform state
454- dataToSave := NewModelFromSecret (* secretResponse )
476+ dataToSave , _ := NewModelFromSecret (ctx , * secretResponse )
455477 response .Diagnostics .Append (response .State .Set (ctx , & dataToSave )... )
456478}
457479
@@ -469,7 +491,8 @@ func (r *ResourceSecret) Update(ctx context.Context, request resource.UpdateRequ
469491 hasChanged := false
470492
471493 if ! plan .Description .Equal (state .Description ) {
472- updateRequest .Description = plan .Description .ValueStringPointer ()
494+ desc := plan .Description .ValueString ()
495+ updateRequest .Description = & desc
473496 hasChanged = true
474497 }
475498
@@ -478,13 +501,19 @@ func (r *ResourceSecret) Update(ctx context.Context, request resource.UpdateRequ
478501 hasChanged = true
479502 }
480503
481- //if !plan.Tags.Equal(state.Tags) {
482- // updateRequest.Tags = plan.Tags.
483- // hasChanged = true
484- //}
485- //if d.HasChange("tags") {
486- // updateRequest.Tags = types.ExpandUpdatedStringsPtr(d.Get("tags"))
487- //}
504+ if ! plan .Tags .Equal (state .Tags ) {
505+ updateRequest .Tags = & []string {}
506+
507+ elements := make ([]string , 0 , len (plan .Tags .Elements ()))
508+ diags := plan .Tags .ElementsAs (ctx , & elements , false )
509+ response .Diagnostics .Append (diags ... )
510+
511+ if elements != nil {
512+ updateRequest .Tags = & elements
513+ }
514+
515+ hasChanged = true
516+ }
488517
489518 if ! plan .Path .Equal (state .Path ) {
490519 updateRequest .Path = plan .Path .ValueStringPointer ()
@@ -510,7 +539,7 @@ func (r *ResourceSecret) Update(ctx context.Context, request resource.UpdateRequ
510539 return
511540 }
512541
513- dataToSave := NewModelFromSecret (* secretResponse )
542+ dataToSave , _ := NewModelFromSecret (ctx , * secretResponse )
514543
515544 // Save updated data into Terraform state
516545 response .Diagnostics .Append (response .State .Set (ctx , & dataToSave )... )
0 commit comments