diff --git a/docs/data-sources/snapshot.md b/docs/data-sources/snapshot.md new file mode 100644 index 0000000..aa5eaf1 --- /dev/null +++ b/docs/data-sources/snapshot.md @@ -0,0 +1,113 @@ +--- +# Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 +# +# http://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. + +title: "powerscale_snapshot data source" +linkTitle: "powerscale_snapshot" +page_title: "powerscale_snapshot Data Source - terraform-provider-powerscale" +subcategory: "" +description: |- + This datasource is used to query the existing Snapshots from PowerScale array. The information fetched from this datasource can be used for getting the details / for further processing in resource block. PowerScale Snapshots is a logical pointer to data that is stored on a cluster at a specific point in time. +--- + +# powerscale_snapshot (Data Source) + +This datasource is used to query the existing Snapshots from PowerScale array. The information fetched from this datasource can be used for getting the details / for further processing in resource block. PowerScale Snapshots is a logical pointer to data that is stored on a cluster at a specific point in time. + +## Example Usage + +```terraform +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +# Returns all of the PowerScale snapshots and their details +# PowerScale Snapshots is a logical pointer to data that is stored on a cluster at a specific point in time. +data "powerscale_snapshot" "all" { +} + +output "powerscale_snapshot_data_all" { + value = data.powerscale_snapshot.all +} + +# Returns a subset of the PowerScale snapshots based on the path provided in the `paths` filter block and their details +data "powerscale_snapshot" "test" { + # Optional path of the filesystem, this will return all the snapshots related to that particular path + filter { + path = "/ifs/tfacc_file_system_test" + } +} + +output "powerscale_snapshot" { + value = data.powerscale_snapshot.test +} + +# After the successful execution of above said block, We can see the output value by executing 'terraform output' command. +# Also, we can use the fetched information by the variable data.powerscale_snapshot.all +``` + + +## Schema + +### Optional + +- `filter` (Block, Optional) (see [below for nested schema](#nestedblock--filter)) + +### Read-Only + +- `id` (String) Identifier +- `snapshots_details` (Attributes List) List of Snapshots (see [below for nested schema](#nestedatt--snapshots_details)) + + +### Nested Schema for `filter` + +Optional: + +- `path` (String) + + + +### Nested Schema for `snapshots_details` + +Read-Only: + +- `alias` (String) The name of the alias, none for real snapshots. +- `created` (Number) The Unix Epoch time the snapshot was created. +- `expires` (Number) The Unix Epoch time the snapshot will expire and be eligible for automatic deletion. +- `has_locks` (Boolean) True if the snapshot has one or more locks present see, see the locks subresource of a snapshot for a list of lock. +- `id` (Number) The system ID given to the snapshot. This is useful for tracking the status of delete pending snapshots. +- `name` (String) The user or system supplied snapshot name. This will be null for snapshots pending delete. +- `path` (String) The /ifs path snapshotted. +- `pct_filesystem` (Number) Percentage of /ifs used for storing this snapshot. +- `pct_reserve` (Number) Percentage of configured snapshot reserved used for storing this snapshot. +- `schedule` (String) The name of the schedule used to create this snapshot, if applicable. +- `shadow_bytes` (Number) The amount of shadow bytes referred to by this snapshot. +- `size` (Number) The amount of storage in bytes used to store this snapshot. +- `state` (String) Snapshot state. +- `target_id` (Number) The ID of the snapshot pointed to if this is an alias. 18446744073709551615 (max uint64) is returned for an alias to the live filesystem. +- `target_name` (String) The name of the snapshot pointed to if this is an alias. \ No newline at end of file diff --git a/examples/data-sources/powerscale_snapshot/data-source.tf b/examples/data-sources/powerscale_snapshot/data-source.tf new file mode 100644 index 0000000..93517cb --- /dev/null +++ b/examples/data-sources/powerscale_snapshot/data-source.tf @@ -0,0 +1,40 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +# Returns all of the PowerScale snapshots and their details +# PowerScale Snapshots is a logical pointer to data that is stored on a cluster at a specific point in time. +data "powerscale_snapshot" "all" { +} + +output "powerscale_snapshot_data_all" { + value = data.powerscale_snapshot.all +} + +# Returns a subset of the PowerScale snapshots based on the path provided in the `paths` filter block and their details +data "powerscale_snapshot" "test" { + # Optional path of the filesystem, this will return all the snapshots related to that particular path + filter { + path = "/ifs/tfacc_file_system_test" + } +} + +output "powerscale_snapshot" { + value = data.powerscale_snapshot.test +} + +# After the successful execution of above said block, We can see the output value by executing 'terraform output' command. +# Also, we can use the fetched information by the variable data.powerscale_snapshot.all \ No newline at end of file diff --git a/examples/data-sources/powerscale_snapshot/provider.tf b/examples/data-sources/powerscale_snapshot/provider.tf new file mode 100644 index 0000000..f505648 --- /dev/null +++ b/examples/data-sources/powerscale_snapshot/provider.tf @@ -0,0 +1,30 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ +terraform { + required_providers { + powerscale = { + source = "registry.terraform.io/dell/powerscale" + } + } +} + +provider "powerscale" { + username = var.username + password = var.password + endpoint = var.endpoint + insecure = var.insecure +} diff --git a/powerscale/constants/constants.go b/powerscale/constants/constants.go index 8b1a663..04115c4 100644 --- a/powerscale/constants/constants.go +++ b/powerscale/constants/constants.go @@ -18,6 +18,10 @@ limitations under the License. package constants const ( + + // ReadSnapshotErrorMessage specifies error details occurred while reading Snapshots. + ReadSnapshotErrorMessage = "Could not read snapshots" + // ReadAccessZoneErrorMsg specifies error details occurred while reading Access Zones. ReadAccessZoneErrorMsg = "Could not read access zones " diff --git a/powerscale/helper/snapshot_helper.go b/powerscale/helper/snapshot_helper.go new file mode 100644 index 0000000..4fd0dcf --- /dev/null +++ b/powerscale/helper/snapshot_helper.go @@ -0,0 +1,45 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +package helper + +import ( + "context" + powerscale "dell/powerscale-go-client" + "terraform-provider-powerscale/client" + "terraform-provider-powerscale/powerscale/models" + + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// GetAllSnapshots returns the full list of snapshots. +func GetAllSnapshots(ctx context.Context, client *client.Client) ([]powerscale.V1SnapshotSnapshotExtended, error) { + result, _, err := client.PscaleOpenAPIClient.SnapshotApi.ListSnapshotv1SnapshotSnapshots(ctx).Execute() + return result.GetSnapshots(), err +} + +// SnapshotDetailMapper Does the mapping from response to model. +func SnapshotDetailMapper(ctx context.Context, snap powerscale.V1SnapshotSnapshotExtended) (models.SnapshotDetailModel, error) { + model := models.SnapshotDetailModel{} + err := CopyFields(ctx, &snap, &model) + if err != nil { + return model, err + } + model.ID = types.Int64Value(int64(snap.Id)) + model.TargetID = types.Int64Value(int64(snap.TargetId)) + return model, nil +} diff --git a/powerscale/models/snapshot.go b/powerscale/models/snapshot.go new file mode 100644 index 0000000..fe0f825 --- /dev/null +++ b/powerscale/models/snapshot.go @@ -0,0 +1,67 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +package models + +import "github.com/hashicorp/terraform-plugin-framework/types" + +// SnapshotDataSourceModel describes the data source data model. +type SnapshotDataSourceModel struct { + ID types.String `tfsdk:"id"` + Snapshots []SnapshotDetailModel `tfsdk:"snapshots_details"` + // filter + SnapshotFilter *SnapshotFilterType `tfsdk:"filter"` +} + +// SnapshotFilterType describes the filter data model. +type SnapshotFilterType struct { + Path types.String `tfsdk:"path"` +} + +// SnapshotDetailModel details of the individual snapshot. +type SnapshotDetailModel struct { + // The name of the alias, none for real snapshots. + Alias types.String `tfsdk:"alias"` + // The Unix Epoch time the snapshot was created. + Created types.Int64 `tfsdk:"created"` + // The Unix Epoch time the snapshot will expire and be eligible for automatic deletion. + Expires types.Int64 `tfsdk:"expires"` + // True if the snapshot has one or more locks present see, see the locks subresource of a snapshot for a list of locks. + HasLocks types.Bool `tfsdk:"has_locks"` + // The system ID given to the snapshot. This is useful for tracking the status of delete pending snapshots. + ID types.Int64 `tfsdk:"id"` + // The user or system supplied snapshot name. This will be null for snapshots pending delete. + Name types.String `tfsdk:"name"` + // The /ifs path snapshotted. + Path types.String `tfsdk:"path"` + // Percentage of /ifs used for storing this snapshot. + PctFilesystem types.Number `tfsdk:"pct_filesystem"` + // Percentage of configured snapshot reserved used for storing this snapshot. + PctReserve types.Number `tfsdk:"pct_reserve"` + // The name of the schedule used to create this snapshot, if applicable. + Schedule types.String `tfsdk:"schedule"` + // The amount of shadow bytes referred to by this snapshot. + ShadowBytes types.Int64 `tfsdk:"shadow_bytes"` + // The amount of storage in bytes used to store this snapshot. + Size types.Int64 `tfsdk:"size"` + // Snapshot state. + State types.String `tfsdk:"state"` + // The ID of the snapshot pointed to if this is an alias. 18446744073709551615 (max uint64) is returned for an alias to the live filesystem. + TargetID types.Int64 `tfsdk:"target_id"` + // The name of the snapshot pointed to if this is an alias. + TargetName types.String `tfsdk:"target_name"` +} diff --git a/powerscale/provider/provider.go b/powerscale/provider/provider.go index 1ce81ed..3bae0b3 100644 --- a/powerscale/provider/provider.go +++ b/powerscale/provider/provider.go @@ -19,9 +19,10 @@ package provider import ( "context" - "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "terraform-provider-powerscale/client" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -177,6 +178,7 @@ func (p *PscaleProvider) DataSources(ctx context.Context) []func() datasource.Da NewAdsProviderDataSource, NewUserGroupDataSource, NewNfsExportDataSource, + NewSnapshotDataSource, } } diff --git a/powerscale/provider/snapshot_datasource.go b/powerscale/provider/snapshot_datasource.go new file mode 100644 index 0000000..64992ad --- /dev/null +++ b/powerscale/provider/snapshot_datasource.go @@ -0,0 +1,245 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +package provider + +import ( + "context" + "fmt" + "terraform-provider-powerscale/client" + "terraform-provider-powerscale/powerscale/constants" + "terraform-provider-powerscale/powerscale/helper" + "terraform-provider-powerscale/powerscale/models" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ datasource.DataSource = &SnapshotDataSource{} + +// NewSnapshotDataSource creates a new data source. +func NewSnapshotDataSource() datasource.DataSource { + return &SnapshotDataSource{} +} + +// SnapshotDataSource defines the data source implementation. +type SnapshotDataSource struct { + client *client.Client +} + +// Metadata describes the data source arguments. +func (d *SnapshotDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_snapshot" +} + +// Schema describes the data source arguments. +func (d *SnapshotDataSource) 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 datasource is used to query the existing Snapshots from PowerScale array. The information fetched from this datasource can be used for getting the details / for further processing in resource block. PowerScale Snapshots is a logical pointer to data that is stored on a cluster at a specific point in time.", + Description: "This datasource is used to query the existing Snapshots from PowerScale array. The information fetched from this datasource can be used for getting the details / for further processing in resource block. PowerScale Snapshot is a logical pointer to data that is stored on a cluster at a specific point in time.", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "Identifier", + MarkdownDescription: "Identifier", + Computed: true, + }, + "snapshots_details": schema.ListNestedAttribute{ + Description: "List of Snapshots", + MarkdownDescription: "List of Snapshots", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "alias": schema.StringAttribute{ + Description: "The name of the alias, none for real snapshots.", + MarkdownDescription: "The name of the alias, none for real snapshots.", + Computed: true, + }, + "created": schema.Int64Attribute{ + Description: "The Unix Epoch time the snapshot was created.", + MarkdownDescription: "The Unix Epoch time the snapshot was created.", + Computed: true, + }, + "expires": schema.Int64Attribute{ + Description: "The Unix Epoch time the snapshot will expire and be eligible for automatic deletion.", + MarkdownDescription: "The Unix Epoch time the snapshot will expire and be eligible for automatic deletion.", + Computed: true, + }, + "has_locks": schema.BoolAttribute{ + Description: "True if the snapshot has one or more locks present see, see the locks subresource of a snapshot for a list of lock.", + MarkdownDescription: "True if the snapshot has one or more locks present see, see the locks subresource of a snapshot for a list of lock.", + Computed: true, + }, + "id": schema.Int64Attribute{ + Description: "The system ID given to the snapshot. This is useful for tracking the status of delete pending snapshots.", + MarkdownDescription: "The system ID given to the snapshot. This is useful for tracking the status of delete pending snapshots.", + Computed: true, + }, + "name": schema.StringAttribute{ + Description: "The user or system supplied snapshot name. This will be null for snapshots pending delete.", + MarkdownDescription: "The user or system supplied snapshot name. This will be null for snapshots pending delete.", + Computed: true, + }, + "path": schema.StringAttribute{ + Description: "The /ifs path snapshotted.", + MarkdownDescription: "The /ifs path snapshotted.", + Computed: true, + }, + "pct_filesystem": schema.NumberAttribute{ + Description: "Percentage of /ifs used for storing this snapshot.", + MarkdownDescription: "Percentage of /ifs used for storing this snapshot.", + Computed: true, + }, + "pct_reserve": schema.NumberAttribute{ + Description: "Percentage of configured snapshot reserved used for storing this snapshot.", + MarkdownDescription: "Percentage of configured snapshot reserved used for storing this snapshot.", + Computed: true, + }, + "shadow_bytes": schema.Int64Attribute{ + Description: "The amount of shadow bytes referred to by this snapshot.", + MarkdownDescription: "The amount of shadow bytes referred to by this snapshot.", + Computed: true, + }, + "schedule": schema.StringAttribute{ + Description: "The name of the schedule used to create this snapshot, if applicable.", + MarkdownDescription: "The name of the schedule used to create this snapshot, if applicable.", + Computed: true, + }, + "size": schema.Int64Attribute{ + Description: "The amount of storage in bytes used to store this snapshot.", + MarkdownDescription: "The amount of storage in bytes used to store this snapshot.", + Computed: true, + }, + "state": schema.StringAttribute{ + Description: "Snapshot state.", + MarkdownDescription: "Snapshot state.", + Computed: true, + }, + "target_id": schema.Int64Attribute{ + Description: "The ID of the snapshot pointed to if this is an alias. 18446744073709551615 (max uint64) is returned for an alias to the live filesystem.", + MarkdownDescription: "The ID of the snapshot pointed to if this is an alias. 18446744073709551615 (max uint64) is returned for an alias to the live filesystem.", + Computed: true, + }, + "target_name": schema.StringAttribute{ + Description: "The name of the snapshot pointed to if this is an alias.", + MarkdownDescription: "The name of the snapshot pointed to if this is an alias.", + Computed: true, + }, + }, + }, + }, + }, + Blocks: map[string]schema.Block{ + "filter": schema.SingleNestedBlock{ + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ + Optional: true, + }, + }, + }, + }, + } +} + +// Configure configures the data source. +func (d *SnapshotDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + pscaleClient, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + d.client = pscaleClient +} + +// Read reads data from the data source. +func (d *SnapshotDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state models.SnapshotDataSourceModel + var plan models.SnapshotDataSourceModel + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &plan)...) + + if resp.Diagnostics.HasError() { + return + } + + result, err := helper.GetAllSnapshots(ctx, d.client) + if err != nil { + errStr := constants.ReadSnapshotErrorMessage + "with error: " + message := helper.GetErrorString(err, errStr) + resp.Diagnostics.AddError( + "Error getting the list of snapshots", + message, + ) + return + } + + // Do the TF Mapping + fulldetail := []models.SnapshotDetailModel{} + for _, vsse := range result { + detail, err := helper.SnapshotDetailMapper(ctx, vsse) + if err != nil { + errStr := constants.ReadSnapshotErrorMessage + "with error: " + message := helper.GetErrorString(err, errStr) + resp.Diagnostics.AddError( + "Error getting the list of snapshots", + message, + ) + return + } + fulldetail = append(fulldetail, detail) + } + + // Apply the Path Filter if it is set + if plan.SnapshotFilter != nil && plan.SnapshotFilter.Path.ValueString() != "" { + for _, sdm := range fulldetail { + if plan.SnapshotFilter.Path.ValueString() == sdm.Path.ValueString() { + state.Snapshots = append(state.Snapshots, sdm) + } + } + // If after the filter the lenght is still zero then that filter is invalid + if len(state.Snapshots) == 0 { + resp.Diagnostics.AddError( + "Error getting snapshots", + fmt.Sprintf("Path `%s` is invalid, it has no snapshots ", plan.SnapshotFilter.Path.ValueString()), + ) + return + } + } else { + state.Snapshots = append(state.Snapshots, fulldetail...) + } + // save into the Terraform state. + state.ID = types.StringValue("snapshot_datasource") + + tflog.Trace(ctx, "read the snapshot datasource") + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} diff --git a/powerscale/provider/snapshot_datasource_test.go b/powerscale/provider/snapshot_datasource_test.go new file mode 100644 index 0000000..25dd136 --- /dev/null +++ b/powerscale/provider/snapshot_datasource_test.go @@ -0,0 +1,115 @@ +/* +Copyright (c) 2023 Dell Inc., or its subsidiaries. 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 + + http://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. +*/ + +package provider + +import ( + "fmt" + "regexp" + "terraform-provider-powerscale/powerscale/helper" + "testing" + + . "github.com/bytedance/mockey" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccSnapshotDataSource(t *testing.T) { + var snapshotTerraformName = "data.powerscale_snapshot.test" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // filter read testing + { + Config: ProviderConfig + SnapshotDataSourceConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.expires", "0"), + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.has_locks", "false"), + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.pct_reserve", "0"), + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.path", "/ifs/tfacc_file_system_test"), + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.shadow_bytes", "0"), + resource.TestCheckResourceAttr(snapshotTerraformName, "snapshots_details.0.state", "active"), + ), + }, + }, + }) +} + +func TestAccSnapshotDataSourceAll(t *testing.T) { + var azTerraformName = "data.powerscale_snapshot.all" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // read all testing + { + Config: ProviderConfig + SnapshotAllDataSourceConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(azTerraformName, "snapshots_details.#"), + ), + }, + }, + }) +} + +func TestAccSnapshotDataSourceGetErr(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { + FunctionMocker = Mock(helper.GetAllSnapshots).Return(nil, fmt.Errorf("mock error")).Build() + }, + Config: ProviderConfig + SnapshotAllDataSourceConfig, + ExpectError: regexp.MustCompile(`.*mock error*.`), + }, + }, + }) +} + +func TestAccSnapshotDataSourceMapErr(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + PreConfig: func() { + FunctionMocker = Mock(helper.SnapshotDetailMapper).Return(nil, fmt.Errorf("mock error")).Build() + }, + Config: ProviderConfig + SnapshotAllDataSourceConfig, + ExpectError: regexp.MustCompile(`.*mock error*.`), + }, + }, + }) +} + +var SnapshotDataSourceConfig = ` +data "powerscale_snapshot" "test" { + filter { + path = "/ifs/tfacc_file_system_test" + } +} +output "powerscale_snapshot" { + value = data.powerscale_snapshot.test +} +` + +var SnapshotAllDataSourceConfig = ` +data "powerscale_snapshot" "all" { +} +`