Repository: MagaluCloud/terraform-provider-mgc
Pull request #124: feat: add virtual machine snapshots datasource
Author: login: geffersonFerraz
Created: 2025-03-19T13:57:43Z | Merged: 2025-03-19T17:27:25Z

## What does this PR do?
<!-- Provide a clear and concise description of the changes -->

## How Has This Been Tested?
<!-- Please describe the tests you ran to verify your changes and how you tested them. Include any relevant details and evidence. -->

## Checklist
- [x] My code follows the style guidelines of this project
- [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

![image](https://github.com/user-attachments/assets/1d9d675b-316e-4f66-9ab7-8ecf88b509c7)




Diff:
diff --git a/docs/data-sources/virtual_machine_snapshots.md b/docs/data-sources/virtual_machine_snapshots.md
new file mode 100644
index 0000000..c9cf8bf
--- /dev/null
+++ b/docs/data-sources/virtual_machine_snapshots.md
@@ -0,0 +1,45 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mgc_virtual_machine_snapshots Data Source - terraform-provider-mgc"
+subcategory: "Virtual Machine"
+description: |-
+  This data source provides a list of virtual machine snapshots.
+---
+
+# mgc_virtual_machine_snapshots (Data Source)
+
+This data source provides a list of virtual machine snapshots.
+
+## Example Usage
+
+```terraform
+data "mgc_virtual_machine_snapshots" "snaps" {
+}
+
+output "vm_snapshots" {
+  value = data.mgc_virtual_machine_snapshots.snaps
+}
+```
+
+<!-- schema generated by tfplugindocs -->
+## Schema
+
+### Read-Only
+
+- `snapshots` (Attributes List) List of available VM machine-types. (see [below for nested schema](#nestedatt--snapshots))
+
+<a id="nestedatt--snapshots"></a>
+### Nested Schema for `snapshots`
+
+Read-Only:
+
+- `created_at` (String) The timestamp when the snapshot was created.
+- `id` (String) The ID of the snapshot.
+- `image_id` (String) The ID of the image.
+- `instance_id` (String) The ID of the instance.
+- `name` (String) The name of the snapshot.
+- `size` (Number) The size of the snapshot.
+- `state` (String) The state of the snapshot.
+- `status` (String) The status of the snapshot.
+- `updated_at` (String) The timestamp when the snapshot was last updated.
+- `virtual_machine_id` (String) The ID of the virtual machine.
diff --git a/examples/data-sources/mgc_virtual_machine_snapshots/data-source.tf b/examples/data-sources/mgc_virtual_machine_snapshots/data-source.tf
new file mode 100644
index 0000000..edb5275
--- /dev/null
+++ b/examples/data-sources/mgc_virtual_machine_snapshots/data-source.tf
@@ -0,0 +1,6 @@
+data "mgc_virtual_machine_snapshots" "snaps" {
+}
+
+output "vm_snapshots" {
+  value = data.mgc_virtual_machine_snapshots.snaps
+}
diff --git a/mgc/datasources/mgc_vm_machine_instance.go b/mgc/datasources/mgc_vm_instance.go
similarity index 100%
rename from mgc/datasources/mgc_vm_machine_instance.go
rename to mgc/datasources/mgc_vm_instance.go
diff --git a/mgc/datasources/mgc_vm_machine_instances.go b/mgc/datasources/mgc_vm_instances.go
similarity index 100%
rename from mgc/datasources/mgc_vm_machine_instances.go
rename to mgc/datasources/mgc_vm_instances.go
diff --git a/mgc/datasources/mgc_vm_snapshots.go b/mgc/datasources/mgc_vm_snapshots.go
new file mode 100644
index 0000000..c24cdb2
--- /dev/null
+++ b/mgc/datasources/mgc_vm_snapshots.go
@@ -0,0 +1,141 @@
+package datasources
+
+import (
+	"context"
+	"time"
+
+	vmSDK "github.com/MagaluCloud/mgc-sdk-go/compute"
+	"github.com/MagaluCloud/terraform-provider-mgc/mgc/tfutil"
+	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ datasource.DataSource = &DataSourceVmSnapshots{}
+
+type DataSourceVmSnapshots struct {
+	vmSnapshot vmSDK.SnapshotService
+}
+
+func (r *DataSourceVmSnapshots) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+	resp.TypeName = req.ProviderTypeName + "_virtual_machine_snapshots"
+}
+
+func NewDataSourceVmSnapshots() datasource.DataSource {
+	return &DataSourceVmSnapshots{}
+}
+
+type vmSnapshotsModel struct {
+	ID               types.String `tfsdk:"id"`
+	Name             types.String `tfsdk:"name"`
+	InstanceID       types.String `tfsdk:"instance_id"`
+	VirtualMachineID types.String `tfsdk:"virtual_machine_id"`
+	ImageID          types.String `tfsdk:"image_id"`
+	Size             types.Int64  `tfsdk:"size"`
+	State            types.String `tfsdk:"state"`
+	Status           types.String `tfsdk:"status"`
+	UpdatedAt        types.String `tfsdk:"updated_at"`
+	CreatedAt        types.String `tfsdk:"created_at"`
+}
+
+type vmSnapshotsListModel struct {
+	Snapshots []vmSnapshotsModel `tfsdk:"snapshots"`
+}
+
+func (r *DataSourceVmSnapshots) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+	resp.Schema = schema.Schema{
+		Description: "This data source provides a list of virtual machine snapshots.",
+		Attributes: map[string]schema.Attribute{
+			"snapshots": schema.ListNestedAttribute{
+				Computed:    true,
+				Description: "List of available VM machine-types.",
+				NestedObject: schema.NestedAttributeObject{
+					Attributes: map[string]schema.Attribute{
+						"id": schema.StringAttribute{
+							Description: "The ID of the snapshot.",
+							Computed:    true,
+						},
+						"name": schema.StringAttribute{
+							Description: "The name of the snapshot.",
+							Computed:    true,
+						},
+						"virtual_machine_id": schema.StringAttribute{
+							Description: "The ID of the virtual machine.",
+							Computed:    true,
+						},
+						"instance_id": schema.StringAttribute{
+							Description: "The ID of the instance.",
+							Computed:    true,
+						},
+						"image_id": schema.StringAttribute{
+							Description: "The ID of the image.",
+							Computed:    true,
+						},
+						"size": schema.Int64Attribute{
+							Description: "The size of the snapshot.",
+							Computed:    true,
+						},
+						"state": schema.StringAttribute{
+							Description: "The state of the snapshot.",
+							Computed:    true,
+						},
+						"status": schema.StringAttribute{
+							Description: "The status of the snapshot.",
+							Computed:    true,
+						},
+						"updated_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was last updated.",
+							Computed:    true,
+						},
+						"created_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was created.",
+							Computed:    true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func (r *DataSourceVmSnapshots) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+	if req.ProviderData == nil {
+		return
+	}
+	dataConfig, ok := req.ProviderData.(tfutil.DataConfig)
+	if !ok {
+		resp.Diagnostics.AddError("Failed to get provider data", "Failed to get provider data")
+		return
+	}
+
+	r.vmSnapshot = vmSDK.New(&dataConfig.CoreConfig).Snapshots()
+}
+
+func (r *DataSourceVmSnapshots) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+	var data vmSnapshotsListModel
+
+	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+	snapList, err := r.vmSnapshot.List(ctx, vmSDK.ListOptions{})
+	if err != nil {
+		resp.Diagnostics.AddError(tfutil.ParseSDKError(err))
+		return
+	}
+
+	for _, snap := range snapList {
+		data.Snapshots = append(data.Snapshots, vmSnapshotsModel{
+			ID:               types.StringValue(snap.ID),
+			Name:             types.StringValue(snap.Name),
+			InstanceID:       types.StringValue(snap.Instance.ID),
+			VirtualMachineID: types.StringPointerValue(snap.Instance.MachineType.ID),
+			ImageID:          types.StringPointerValue(snap.Instance.Image.ID),
+			Size:             types.Int64Value(int64(snap.Size)),
+			State:            types.StringValue(snap.State),
+			Status:           types.StringValue(snap.Status),
+			UpdatedAt:        types.StringValue(snap.UpdatedAt.Format(time.RFC3339)),
+			CreatedAt:        types.StringValue(snap.CreatedAt.Format(time.RFC3339)),
+		})
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
diff --git a/mgc/provider.go b/mgc/provider.go
index a2e0e15..87eb75b 100644
--- a/mgc/provider.go
+++ b/mgc/provider.go
@@ -219,6 +219,7 @@ func (p *mgcProvider) DataSources(ctx context.Context) []func() datasource.DataS
 		datasources.NewDataSourceSSH,
 		datasources.NewDatasourceBucket,
 		datasources.NewDatasourceBuckets,
+		datasources.NewDataSourceVmSnapshots,
 	}
 }
 


Reviews:
user: login: publi0
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T14:27:50Z
user: login: geffersonFerraz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T14:36:56Z
user: login: publi0
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T15:39:42Z
user: login: publi0
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T15:40:46Z
user: login: publi0
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T17:27:17Z

Review comments:
diff_hunk: @@ -0,0 +1,140 @@
+package datasources
+
+import (
+	"context"
+	"time"
+
+	vmSDK "github.com/MagaluCloud/mgc-sdk-go/compute"
+	"github.com/MagaluCloud/terraform-provider-mgc/mgc/tfutil"
+	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ datasource.DataSource = &DataSourceVmSnapshots{}
+
+type DataSourceVmSnapshots struct {
+	vmSnapshot vmSDK.SnapshotService
+}
+
+func (r *DataSourceVmSnapshots) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+	resp.TypeName = req.ProviderTypeName + "_virtual_machine_snapshots"
+}
+
+func NewDataSourceVmSnapshots() datasource.DataSource {
+	return &DataSourceVmSnapshots{}
+}
+
+type vmSnapshotsModel struct {
+	ID               types.String `tfsdk:"id"`
+	Name             types.String `tfsdk:"name"`
+	InstanceID       types.String `tfsdk:"instance_id"`
+	VirtualMachineID types.String `tfsdk:"virtual_machine_id"`
+	ImageID          types.String `tfsdk:"image_id"`
+	Size             types.Int64  `tfsdk:"size"`
+	State            types.String `tfsdk:"state"`
+	Status           types.String `tfsdk:"status"`
+	UpdatedAt        types.String `tfsdk:"updated_at"`
+	CreatedAt        types.String `tfsdk:"created_at"`
+}
+
+type vmSnapshotsListModel struct {
+	Snapshots []vmSnapshotsModel `tfsdk:"snapshots"`
+}
+
+func (r *DataSourceVmSnapshots) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+	resp.Schema = schema.Schema{
+		Attributes: map[string]schema.Attribute{
+			"snapshots": schema.ListNestedAttribute{
+				Computed:    true,
+				Description: "List of available VM machine-types.",
+				NestedObject: schema.NestedAttributeObject{
+					Attributes: map[string]schema.Attribute{
+						"id": schema.StringAttribute{
+							Description: "The ID of the snapshot.",
+							Computed:    true,
+						},
+						"name": schema.StringAttribute{
+							Description: "The name of the snapshot.",
+							Computed:    true,
+						},
+						"virtual_machine_id": schema.StringAttribute{
+							Description: "The ID of the virtual machine.",
+							Computed:    true,
+						},
+						"instance_id": schema.StringAttribute{
+							Description: "The ID of the instance.",
+							Computed:    true,
+						},
+						"image_id": schema.StringAttribute{
+							Description: "The ID of the image.",
+							Computed:    true,
+						},
+						"size": schema.Int64Attribute{
+							Description: "The size of the snapshot.",
+							Computed:    true,
+						},
+						"state": schema.StringAttribute{
+							Description: "The state of the snapshot.",
+							Computed:    true,
+						},
+						"status": schema.StringAttribute{
+							Description: "The status of the snapshot.",
+							Computed:    true,
+						},
+						"updated_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was last updated.",
+							Computed:    true,
+						},
+						"created_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was created.",
+							Computed:    true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func (r *DataSourceVmSnapshots) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+	if req.ProviderData == nil {
+		return
+	}
+	dataConfig, ok := req.ProviderData.(tfutil.DataConfig)
+	if !ok {
+		resp.Diagnostics.AddError("Failed to get provider data", "Failed to get provider data")
+		return
+	}
+
+	r.vmSnapshot = vmSDK.New(&dataConfig.CoreConfig).Snapshots()
+}
+
+func (r *DataSourceVmSnapshots) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+	var data vmSnapshotsListModel
+
+	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+	snapList, err := r.vmSnapshot.List(ctx, vmSDK.ListOptions{Expand: []string{vmSDK.SnapshotImageExpand, vmSDK.SnapshotMachineTypeExpand}})
path: mgc/datasources/mgc_vm_snapshots.go
user: login: publi0
body: Está sendo solicitado os expand de Image e Machine Type, mas esses valores não estão sendo usados
created_at: 2025-03-19T14:27:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,140 @@
+package datasources
+
+import (
+	"context"
+	"time"
+
+	vmSDK "github.com/MagaluCloud/mgc-sdk-go/compute"
+	"github.com/MagaluCloud/terraform-provider-mgc/mgc/tfutil"
+	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ datasource.DataSource = &DataSourceVmSnapshots{}
+
+type DataSourceVmSnapshots struct {
+	vmSnapshot vmSDK.SnapshotService
+}
+
+func (r *DataSourceVmSnapshots) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+	resp.TypeName = req.ProviderTypeName + "_virtual_machine_snapshots"
+}
+
+func NewDataSourceVmSnapshots() datasource.DataSource {
+	return &DataSourceVmSnapshots{}
+}
+
+type vmSnapshotsModel struct {
+	ID               types.String `tfsdk:"id"`
+	Name             types.String `tfsdk:"name"`
+	InstanceID       types.String `tfsdk:"instance_id"`
+	VirtualMachineID types.String `tfsdk:"virtual_machine_id"`
+	ImageID          types.String `tfsdk:"image_id"`
+	Size             types.Int64  `tfsdk:"size"`
+	State            types.String `tfsdk:"state"`
+	Status           types.String `tfsdk:"status"`
+	UpdatedAt        types.String `tfsdk:"updated_at"`
+	CreatedAt        types.String `tfsdk:"created_at"`
+}
+
+type vmSnapshotsListModel struct {
+	Snapshots []vmSnapshotsModel `tfsdk:"snapshots"`
+}
+
+func (r *DataSourceVmSnapshots) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+	resp.Schema = schema.Schema{
+		Attributes: map[string]schema.Attribute{
+			"snapshots": schema.ListNestedAttribute{
+				Computed:    true,
+				Description: "List of available VM machine-types.",
+				NestedObject: schema.NestedAttributeObject{
+					Attributes: map[string]schema.Attribute{
+						"id": schema.StringAttribute{
+							Description: "The ID of the snapshot.",
+							Computed:    true,
+						},
+						"name": schema.StringAttribute{
+							Description: "The name of the snapshot.",
+							Computed:    true,
+						},
+						"virtual_machine_id": schema.StringAttribute{
+							Description: "The ID of the virtual machine.",
+							Computed:    true,
+						},
+						"instance_id": schema.StringAttribute{
+							Description: "The ID of the instance.",
+							Computed:    true,
+						},
+						"image_id": schema.StringAttribute{
+							Description: "The ID of the image.",
+							Computed:    true,
+						},
+						"size": schema.Int64Attribute{
+							Description: "The size of the snapshot.",
+							Computed:    true,
+						},
+						"state": schema.StringAttribute{
+							Description: "The state of the snapshot.",
+							Computed:    true,
+						},
+						"status": schema.StringAttribute{
+							Description: "The status of the snapshot.",
+							Computed:    true,
+						},
+						"updated_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was last updated.",
+							Computed:    true,
+						},
+						"created_at": schema.StringAttribute{
+							Description: "The timestamp when the snapshot was created.",
+							Computed:    true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func (r *DataSourceVmSnapshots) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+	if req.ProviderData == nil {
+		return
+	}
+	dataConfig, ok := req.ProviderData.(tfutil.DataConfig)
+	if !ok {
+		resp.Diagnostics.AddError("Failed to get provider data", "Failed to get provider data")
+		return
+	}
+
+	r.vmSnapshot = vmSDK.New(&dataConfig.CoreConfig).Snapshots()
+}
+
+func (r *DataSourceVmSnapshots) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+	var data vmSnapshotsListModel
+
+	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+	snapList, err := r.vmSnapshot.List(ctx, vmSDK.ListOptions{Expand: []string{vmSDK.SnapshotImageExpand, vmSDK.SnapshotMachineTypeExpand}})
path: mgc/datasources/mgc_vm_snapshots.go
user: login: geffersonFerraz
body: tais certo, feito ajuste o/ 
created_at: 2025-03-19T14:36:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,140 @@
+package datasources
+
+import (
+	"context"
+	"time"
+
+	vmSDK "github.com/MagaluCloud/mgc-sdk-go/compute"
+	"github.com/MagaluCloud/terraform-provider-mgc/mgc/tfutil"
+	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ datasource.DataSource = &DataSourceVmSnapshots{}
+
+type DataSourceVmSnapshots struct {
+	vmSnapshot vmSDK.SnapshotService
+}
+
+func (r *DataSourceVmSnapshots) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+	resp.TypeName = req.ProviderTypeName + "_virtual_machine_snapshots"
+}
+
+func NewDataSourceVmSnapshots() datasource.DataSource {
+	return &DataSourceVmSnapshots{}
+}
+
+type vmSnapshotsModel struct {
+	ID               types.String `tfsdk:"id"`
+	Name             types.String `tfsdk:"name"`
+	InstanceID       types.String `tfsdk:"instance_id"`
+	VirtualMachineID types.String `tfsdk:"virtual_machine_id"`
+	ImageID          types.String `tfsdk:"image_id"`
+	Size             types.Int64  `tfsdk:"size"`
+	State            types.String `tfsdk:"state"`
+	Status           types.String `tfsdk:"status"`
+	UpdatedAt        types.String `tfsdk:"updated_at"`
+	CreatedAt        types.String `tfsdk:"created_at"`
+}
+
+type vmSnapshotsListModel struct {
+	Snapshots []vmSnapshotsModel `tfsdk:"snapshots"`
+}
+
+func (r *DataSourceVmSnapshots) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+	resp.Schema = schema.Schema{
+		Attributes: map[string]schema.Attribute{
path: mgc/datasources/mgc_vm_snapshots.go
user: login: publi0
body: Só sendo mais um tico chato, só vi agora olhando pra doc, faltou adicionar a descrição do recurso
created_at: 2025-03-19T15:40:41Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-19T16:11:05Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=MagaluCloud_terraform-provider-mgc&pullRequest=124) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=MagaluCloud_terraform-provider-mgc&pullRequest=124&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=MagaluCloud_terraform-provider-mgc&pullRequest=124&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=MagaluCloud_terraform-provider-mgc&pullRequest=124&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=MagaluCloud_terraform-provider-mgc&pullRequest=124&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=MagaluCloud_terraform-provider-mgc&pullRequest=124&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=MagaluCloud_terraform-provider-mgc&pullRequest=124)


author_association: NONE