Repository: dell/terraform-provider-powerstore
Pull request #139: fix bug filesystem snapshot
Author: login: Krishnan-Priyanshu
Created: 2025-03-03T01:16:14Z | Merged: 2025-03-05T11:02:45Z

# Description
PR is raised to fix the bugs for filesystem snapshot resource

# GitHub Issues
List the GitHub issues impacted by this PR:

| GitHub Issue # |
| -------------- |
| https://github.com/dell/terraform-provider-powerstore/issues/120 |

# Checklist:

- [x] I have performed a self-review of my own code to ensure there are no formatting, vetting, linting, or security issues
- [ ] I have verified that new and existing unit tests pass locally with my changes
- [x] I have not allowed coverage numbers to degenerate
- [ ] I have maintained at least 90% code coverage
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] Backward compatibility is not broken

# How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [ ] Acceptance tests


Diff:
diff --git a/docs/resources/filesystem_snapshot.md b/docs/resources/filesystem_snapshot.md
index b20ee983..715b8528 100644
--- a/docs/resources/filesystem_snapshot.md
+++ b/docs/resources/filesystem_snapshot.md
@@ -78,7 +78,7 @@ After the execution of above resource block, filesystem snapshot would have been
 
 - `access_type` (String) Access type of the filesystem snapshot. Access type can be 'Snapshot' or 'Protocol'. Cannot be updated.
 - `description` (String) Description of the filesystem snapshot.
-- `expiration_timestamp` (String) Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot.Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z
+- `expiration_timestamp` (String) Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot. To remove the expiration timestamp, specify it as an empty string. Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z
 - `name` (String) Name of the filesystem snapshot.The default name of the filesystem snapshot is the date and time when the snapshot is taken.
 
 ### Read-Only
diff --git a/go.mod b/go.mod
index 9f777323..109a37eb 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.23
 toolchain go1.23.2
 
 require (
-	github.com/dell/gopowerstore v1.17.1-0.20250218155721-3545eab38216
+	github.com/dell/gopowerstore v1.17.1-0.20250304113024-bed4dd01d316
 	github.com/hashicorp/terraform-plugin-framework v1.13.0
 	github.com/hashicorp/terraform-plugin-framework-validators v0.15.0
 	github.com/hashicorp/terraform-plugin-go v0.25.0
diff --git a/go.sum b/go.sum
index 55b72ea1..67940fc9 100644
--- a/go.sum
+++ b/go.sum
@@ -35,6 +35,10 @@ github.com/dell/gopowerstore v1.17.1-0.20250217170101-78b629f4e7b3 h1:ej7QRdTlh+
 github.com/dell/gopowerstore v1.17.1-0.20250217170101-78b629f4e7b3/go.mod h1:b1+xAG8+447LpvdKFwIp0dq6wCpQyAcDXa/jgPkJo8Q=
 github.com/dell/gopowerstore v1.17.1-0.20250218155721-3545eab38216 h1:bYsbOG/pQomYu1klwYZRL9Q+/Hb4sV6flCSD7bFQfpY=
 github.com/dell/gopowerstore v1.17.1-0.20250218155721-3545eab38216/go.mod h1:b1+xAG8+447LpvdKFwIp0dq6wCpQyAcDXa/jgPkJo8Q=
+github.com/dell/gopowerstore v1.17.1-0.20250304082303-2d980715c3e1 h1:B+6qujCEf9dYBE8mB/6h/aCN8eP+nSYqeqbdlF7SBgI=
+github.com/dell/gopowerstore v1.17.1-0.20250304082303-2d980715c3e1/go.mod h1:b1+xAG8+447LpvdKFwIp0dq6wCpQyAcDXa/jgPkJo8Q=
+github.com/dell/gopowerstore v1.17.1-0.20250304113024-bed4dd01d316 h1:X5oam5xfhqbeWOLrUTryJYth6ALS6lEoMIA+xjPE2x8=
+github.com/dell/gopowerstore v1.17.1-0.20250304113024-bed4dd01d316/go.mod h1:b1+xAG8+447LpvdKFwIp0dq6wCpQyAcDXa/jgPkJo8Q=
 github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
 github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
diff --git a/powerstore/resource_filesystem.go b/powerstore/resource_filesystem.go
index c4ee4976..ce43504e 100644
--- a/powerstore/resource_filesystem.go
+++ b/powerstore/resource_filesystem.go
@@ -25,6 +25,8 @@ import (
 	client "terraform-provider-powerstore/client"
 	"terraform-provider-powerstore/models"
 
+	"terraform-provider-powerstore/powerstore/helper"
+
 	"github.com/dell/gopowerstore"
 	"github.com/hashicorp/terraform-plugin-framework-validators/int32validator"
 	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
@@ -36,7 +38,6 @@ import (
 	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
 	"github.com/hashicorp/terraform-plugin-framework/types"
 	"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
-	"terraform-provider-powerstore/powerstore/helper"
 )
 
 type fileSystemResource struct {
@@ -545,13 +546,13 @@ func (r fileSystemResource) Update(ctx context.Context, req resource.UpdateReque
 	}
 
 	fsModify := &gopowerstore.FSModify{
-		Description:                plan.Description.ValueString(),
+		Description:                plan.Description.ValueStringPointer(),
 		Size:                       int(valInBytes),
 		AccessPolicy:               plan.AccessPolicy.ValueString(),
 		LockingPolicy:              plan.LockingPolicy.ValueString(),
 		FolderRenamePolicy:         plan.FolderRenamePolicy.ValueString(),
 		IsAsyncMtimeEnabled:        helper.GetKnownBoolPointer(plan.IsAsyncMTimeEnabled),
-		ProtectionPolicyID:         plan.ProtectionPolicyID.ValueString(),
+		ProtectionPolicyID:         plan.ProtectionPolicyID.ValueStringPointer(),
 		FileEventsPublishingMode:   plan.FileEventsPublishingMode.ValueString(),
 		IsSmbSyncWritesEnabled:     helper.GetKnownBoolPointer(plan.IsSmbSyncWritesEnabled),
 		IsSmbNoNotifyEnabled:       helper.GetKnownBoolPointer(plan.IsSmbNoNotifyEnabled),
diff --git a/powerstore/resource_filesystem_snapshot.go b/powerstore/resource_filesystem_snapshot.go
index beee827e..f1c18f62 100644
--- a/powerstore/resource_filesystem_snapshot.go
+++ b/powerstore/resource_filesystem_snapshot.go
@@ -22,8 +22,6 @@ import (
 	"fmt"
 	"log"
 	"regexp"
-	"terraform-provider-powerstore/client"
-	"terraform-provider-powerstore/models"
 
 	"github.com/dell/gopowerstore"
 	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
@@ -33,6 +31,16 @@ import (
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
 	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
 	"github.com/hashicorp/terraform-plugin-framework/types"
+
+	"terraform-provider-powerstore/client"
+	"terraform-provider-powerstore/models"
+)
+
+const (
+	// DefaultExpirationTimestamp is the default expiration timestamp when not specified
+	DefaultExpirationTimestamp = "1970-01-01T00:00:00.000Z"
+	// SpaceDescription is the default description when not specified
+	SpaceDescription = " "
 )
 
 // newFileSystemSnapshotResource returns snapshot new resource instance
@@ -84,15 +92,12 @@ func (r *resourceFileSystemSnapshot) Schema(ctx context.Context, req resource.Sc
 				Computed:            true,
 				Description:         "Description of the filesystem snapshot.",
 				MarkdownDescription: "Description of the filesystem snapshot.",
-				Validators: []validator.String{
-					stringvalidator.LengthAtLeast(1),
-				},
 			},
 			"expiration_timestamp": schema.StringAttribute{
 				Optional:            true,
 				Computed:            true,
-				Description:         "Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot.Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z",
-				MarkdownDescription: "Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot.Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z",
+				Description:         "Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot. To remove the expiration timestamp, specify it as an empty string. Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z",
+				MarkdownDescription: "Expiration Timestamp of the filesystem snapshot, if not provided there will no expiration for the snapshot. To remove the expiration timestamp, specify it as an empty string. Only UTC (+Z) format is allowed eg: 2023-05-06T09:01:47Z",
 				Validators: []validator.String{
 					stringvalidator.RegexMatches(
 						regexp.MustCompile(`(^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$|^$)`),
@@ -103,7 +108,7 @@ func (r *resourceFileSystemSnapshot) Schema(ctx context.Context, req resource.Sc
 			"access_type": schema.StringAttribute{
 				Optional:            true,
 				Computed:            true,
-				Description:         "Access type of the filesystem snapshot. Access type can be 'Snapshot' or 'Protocol'.Cannot be updated.",
+				Description:         "Access type of the filesystem snapshot. Access type can be 'Snapshot' or 'Protocol'. Cannot be updated.",
 				MarkdownDescription: "Access type of the filesystem snapshot. Access type can be 'Snapshot' or 'Protocol'. Cannot be updated.",
 				Validators: []validator.String{
 					stringvalidator.OneOf("Snapshot", "Protocol"),
@@ -336,11 +341,13 @@ func (r resourceFileSystemSnapshot) updateSnapshotState(_, state *models.FileSys
 }
 
 func (r resourceFileSystemSnapshot) planToServer(plan models.FileSystemSnapshot) *gopowerstore.FSModify {
-	description := plan.Description.ValueString()
-	expirationTimeStamp := plan.ExpirationTimestamp.ValueString()
-	volSnapshotUpdate := &gopowerstore.FSModify{
-		Description:         description,
-		ExpirationTimestamp: expirationTimeStamp,
+	expirationTimestamp := plan.ExpirationTimestamp.ValueString()
+	if !plan.ExpirationTimestamp.IsNull() && expirationTimestamp == "" {
+		expirationTimestamp = "1970-01-01T00:00:00.000Z"
+	}
+	fsSnapshotUpdate := &gopowerstore.FSModify{
+		Description:         plan.Description.ValueStringPointer(),
+		ExpirationTimestamp: expirationTimestamp,
 	}
-	return volSnapshotUpdate
+	return fsSnapshotUpdate
 }


Reviews:
user: login: shenda1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T03:59:51Z
user: login: shenda1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T04:00:56Z
user: login: shenda1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T05:18:32Z
user: login: Krishnan-Priyanshu
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-04T07:55:47Z
user: login: rounak-adhikary
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T08:22:46Z
user: login: Sakshi-dell
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-05T10:09:52Z

Review comments:
diff_hunk: @@ -33,6 +31,16 @@ import (
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
 	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
 	"github.com/hashicorp/terraform-plugin-framework/types"
+
+	"terraform-provider-powerstore/client"
+	"terraform-provider-powerstore/models"
+)
+
+const (
+	// DefaultExpirationTimestamp is the default expiration timestamp when not specified
+	DefaultExpirationTimestamp = "1970-01-01T00:00:00.000Z"
+	// SpaceDescription is the default description when not specified
+	SpaceDescription = " "
path: powerstore/resource_filesystem_snapshot.go
user: login: shenda1
body: it should be an empty string?
created_at: 2025-03-03T03:59:51Z
author_association: COLLABORATOR
diff_hunk: @@ -33,6 +31,16 @@ import (
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
 	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
 	"github.com/hashicorp/terraform-plugin-framework/types"
+
+	"terraform-provider-powerstore/client"
+	"terraform-provider-powerstore/models"
+)
+
+const (
+	// DefaultExpirationTimestamp is the default expiration timestamp when not specified
path: powerstore/resource_filesystem_snapshot.go
user: login: shenda1
body: Update the documentation to use this value for setting unlimited retention after snapshot creation
created_at: 2025-03-03T04:00:56Z
author_association: COLLABORATOR
diff_hunk: @@ -84,9 +92,6 @@ func (r *resourceFileSystemSnapshot) Schema(ctx context.Context, req resource.Sc
 				Computed:            true,
 				Description:         "Description of the filesystem snapshot.",
 				MarkdownDescription: "Description of the filesystem snapshot.",
-				Validators: []validator.String{
-					stringvalidator.LengthAtLeast(1),
-				},
 			},
 			"expiration_timestamp": schema.StringAttribute{
path: powerstore/resource_filesystem_snapshot.go
user: login: shenda1
body: For expiration_timestamp, though regex is applied, it is still accepting "". Is it valid value?
created_at: 2025-03-03T05:18:32Z
author_association: COLLABORATOR
diff_hunk: @@ -84,9 +92,6 @@ func (r *resourceFileSystemSnapshot) Schema(ctx context.Context, req resource.Sc
 				Computed:            true,
 				Description:         "Description of the filesystem snapshot.",
 				MarkdownDescription: "Description of the filesystem snapshot.",
-				Validators: []validator.String{
-					stringvalidator.LengthAtLeast(1),
-				},
 			},
 			"expiration_timestamp": schema.StringAttribute{
path: powerstore/resource_filesystem_snapshot.go
user: login: Krishnan-Priyanshu
body: the expirtation timestamp "" is valid value to set infinite retention
created_at: 2025-03-04T07:55:46Z
author_association: COLLABORATOR

PR comments:
user: login: shenda1
created_at: 2025-03-05T04:14:05Z
body: run e2e test FileSystemSnapshot
author_association: COLLABORATOR
user: login: shenda1
created_at: 2025-03-05T05:06:58Z
body: run e2e test FileSystem_


author_association: COLLABORATOR