Skip to content

Commit 5e52355

Browse files
committed
add CreateSnapshot action
1 parent 8acce48 commit 5e52355

File tree

5 files changed

+3649
-1
lines changed

5 files changed

+3649
-1
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package instance
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/action"
8+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
11+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
12+
"github.com/scaleway/scaleway-sdk-go/scw"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
15+
)
16+
17+
var (
18+
_ action.Action = (*CreateSnapshot)(nil)
19+
_ action.ActionWithConfigure = (*CreateSnapshot)(nil)
20+
)
21+
22+
type CreateSnapshot struct {
23+
instanceAPI *instance.API
24+
}
25+
26+
func (c *CreateSnapshot) Configure(_ context.Context, req action.ConfigureRequest, resp *action.ConfigureResponse) {
27+
if req.ProviderData == nil {
28+
return
29+
}
30+
31+
m, ok := req.ProviderData.(*meta.Meta)
32+
if !ok {
33+
resp.Diagnostics.AddError(
34+
"Unexpected Action Configure Type",
35+
fmt.Sprintf("Expected *scw.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
36+
)
37+
38+
return
39+
}
40+
41+
client := m.ScwClient()
42+
c.instanceAPI = instance.NewAPI(client)
43+
}
44+
45+
func (c *CreateSnapshot) Metadata(_ context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
46+
resp.TypeName = req.ProviderTypeName + "_instance_create_snapshot"
47+
}
48+
49+
type CreateSnapshotModel struct {
50+
Zone types.String `tfsdk:"zone"`
51+
VolumeID types.String `tfsdk:"volume_id"`
52+
Name types.String `tfsdk:"name"`
53+
Tags types.List `tfsdk:"tags"`
54+
Wait types.Bool `tfsdk:"wait"`
55+
}
56+
57+
func NewCreateSnapshot() action.Action {
58+
return &CreateSnapshot{}
59+
}
60+
61+
func (c *CreateSnapshot) Schema(_ context.Context, _ action.SchemaRequest, resp *action.SchemaResponse) {
62+
resp.Schema = schema.Schema{
63+
Attributes: map[string]schema.Attribute{
64+
"volume_id": schema.StringAttribute{
65+
Required: true,
66+
Description: "ID of the volume to snapshot",
67+
},
68+
"zone": schema.StringAttribute{
69+
Optional: true,
70+
Description: "Zone of the volume to snapshot",
71+
},
72+
"name": schema.StringAttribute{
73+
Optional: true,
74+
Description: "Name of the snapshot",
75+
},
76+
"tags": schema.ListAttribute{
77+
Optional: true,
78+
ElementType: basetypes.StringType{},
79+
Description: "List of tags associated with the snapshot",
80+
},
81+
"wait": schema.BoolAttribute{
82+
Optional: true,
83+
Description: "Wait for snapshotting operation to be finished",
84+
},
85+
},
86+
}
87+
}
88+
89+
func (c *CreateSnapshot) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
90+
var data CreateSnapshotModel
91+
// Read action config data into the model
92+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
93+
94+
if resp.Diagnostics.HasError() {
95+
return
96+
}
97+
98+
if c.instanceAPI == nil {
99+
resp.Diagnostics.AddError(
100+
"Unconfigured instanceAPI",
101+
"The action was not properly configured. The Scaleway client is missing. "+
102+
"This is usually a bug in the provider. Please report it to the maintainers.",
103+
)
104+
105+
return
106+
}
107+
108+
actionReq := &instance.CreateSnapshotRequest{
109+
VolumeID: scw.StringPtr(locality.ExpandID(data.VolumeID.ValueString())),
110+
}
111+
if !data.Zone.IsNull() {
112+
actionReq.Zone = scw.Zone(data.Zone.ValueString())
113+
}
114+
115+
if !data.Name.IsNull() {
116+
actionReq.Name = data.Name.ValueString()
117+
}
118+
119+
if len(data.Tags.Elements()) > 0 {
120+
tags := make([]string, 0, len(data.Tags.Elements()))
121+
122+
diags := data.Tags.ElementsAs(ctx, &tags, false)
123+
if diags.HasError() {
124+
resp.Diagnostics.Append(diags...)
125+
} else {
126+
actionReq.Tags = &tags
127+
}
128+
}
129+
130+
snapshot, err := c.instanceAPI.CreateSnapshot(actionReq)
131+
if err != nil {
132+
resp.Diagnostics.AddError(
133+
"error creating snapshot",
134+
fmt.Sprintf("%s", err))
135+
136+
return
137+
}
138+
139+
if data.Wait.ValueBool() {
140+
waitReq := &instance.WaitForSnapshotRequest{
141+
SnapshotID: snapshot.Snapshot.ID,
142+
Zone: scw.Zone(data.Zone.ValueString()),
143+
}
144+
145+
if !data.Zone.IsNull() {
146+
waitReq.Zone = scw.Zone(data.Zone.ValueString())
147+
}
148+
149+
_, errWait := c.instanceAPI.WaitForSnapshot(waitReq)
150+
if errWait != nil {
151+
resp.Diagnostics.AddError(
152+
"error waiting for snapshot",
153+
fmt.Sprintf("%s", err))
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)