Skip to content

Commit 9ba3580

Browse files
committed
refactor(instance): extract block helpers to a package
1 parent 6cddf65 commit 9ba3580

14 files changed

+134
-483
lines changed

internal/services/instance/helpers_instance.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
2121
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
2222
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/block"
23+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/instancehelpers"
2324
"github.com/scaleway/terraform-provider-scaleway/v2/internal/transport"
2425
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
2526
)
@@ -40,7 +41,6 @@ const (
4041
defaultInstancePlacementGroupTimeout = 1 * time.Minute
4142
defaultInstanceIPTimeout = 1 * time.Minute
4243
defaultInstanceIPReverseDNSTimeout = 10 * time.Minute
43-
defaultInstanceRetryInterval = 5 * time.Second
4444

4545
defaultInstanceSnapshotWaitTimeout = 1 * time.Hour
4646

@@ -148,7 +148,7 @@ func serverStateExpand(rawState string) (instance.ServerState, error) {
148148
return apiState, nil
149149
}
150150

151-
func reachState(ctx context.Context, api *BlockAndInstanceAPI, zone scw.Zone, serverID string, toState instance.ServerState) error {
151+
func reachState(ctx context.Context, api *instancehelpers.BlockAndInstanceAPI, zone scw.Zone, serverID string, toState instance.ServerState) error {
152152
response, err := api.GetServer(&instance.GetServerRequest{
153153
Zone: zone,
154154
ServerID: serverID,
@@ -180,7 +180,7 @@ func reachState(ctx context.Context, api *BlockAndInstanceAPI, zone scw.Zone, se
180180
// We need to check that all volumes are ready
181181
for _, volume := range response.Server.Volumes {
182182
if volume.VolumeType == block.BlockVolumeType {
183-
_, err := api.blockAPI.WaitForVolumeAndReferences(&blockSDK.WaitForVolumeAndReferencesRequest{
183+
_, err := api.BlockAPI.WaitForVolumeAndReferences(&blockSDK.WaitForVolumeAndReferencesRequest{
184184
VolumeID: volume.ID,
185185
Zone: zone,
186186
RetryInterval: transport.DefaultWaitRetryInterval,
@@ -351,7 +351,7 @@ func (ph *privateNICsHandler) detach(ctx context.Context, o interface{}, timeout
351351
PrivateNicID: p.ID,
352352
Zone: ph.zone,
353353
Timeout: &timeout,
354-
RetryInterval: scw.TimeDurationPtr(defaultInstanceRetryInterval),
354+
RetryInterval: scw.TimeDurationPtr(instancehelpers.DefaultInstanceRetryInterval),
355355
})
356356
if err != nil && !httperrors.Is404(err) {
357357
return err
@@ -455,7 +455,7 @@ func retryUpdateReverseDNS(ctx context.Context, instanceAPI *instance.API, req *
455455

456456
for {
457457
select {
458-
case <-time.After(defaultInstanceRetryInterval):
458+
case <-time.After(instancehelpers.DefaultInstanceRetryInterval):
459459
_, err := instanceAPI.UpdateIP(req, scw.WithContext(ctx))
460460
if err != nil && IsIPReverseDNSResolveError(err) {
461461
continue
@@ -495,8 +495,8 @@ func instanceIPHasMigrated(d *schema.ResourceData) bool {
495495
return false
496496
}
497497

498-
func instanceServerAdditionalVolumeTemplate(api *BlockAndInstanceAPI, zone scw.Zone, volumeID string) (*instance.VolumeServerTemplate, error) {
499-
vol, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
498+
func instanceServerAdditionalVolumeTemplate(api *instancehelpers.BlockAndInstanceAPI, zone scw.Zone, volumeID string) (*instance.VolumeServerTemplate, error) {
499+
vol, err := api.GetUnknownVolume(&instancehelpers.GetUnknownVolumeRequest{
500500
VolumeID: locality.ExpandID(volumeID),
501501
Zone: zone,
502502
})
@@ -507,7 +507,7 @@ func instanceServerAdditionalVolumeTemplate(api *BlockAndInstanceAPI, zone scw.Z
507507
return vol.VolumeTemplate(), nil
508508
}
509509

510-
func prepareRootVolume(rootVolumeI map[string]any, serverType *instance.ServerType, image string) *UnknownVolume {
510+
func prepareRootVolume(rootVolumeI map[string]any, serverType *instance.ServerType, image string) *instancehelpers.UnknownVolume {
511511
rootVolumeIsBootVolume := types.ExpandBoolPtr(types.GetMapValue[bool](rootVolumeI, "boot"))
512512
rootVolumeType := types.GetMapValue[string](rootVolumeI, "volume_type")
513513
sizeInput := types.GetMapValue[int](rootVolumeI, "size_in_gb")
@@ -528,7 +528,7 @@ func prepareRootVolume(rootVolumeI map[string]any, serverType *instance.ServerTy
528528
rootVolumeSize = scw.SizePtr(scw.Size(uint64(sizeInput) * gb))
529529
}
530530

531-
return &UnknownVolume{
531+
return &instancehelpers.UnknownVolume{
532532
Name: rootVolumeName,
533533
ID: rootVolumeID,
534534
InstanceVolumeType: instance.VolumeVolumeType(rootVolumeType),

internal/services/instance/helpers_instance_block.go

Lines changed: 0 additions & 269 deletions
Original file line numberDiff line numberDiff line change
@@ -1,279 +1,10 @@
11
package instance
22

33
import (
4-
"errors"
5-
6-
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7-
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
84
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
95
"github.com/scaleway/scaleway-sdk-go/api/marketplace/v2"
10-
"github.com/scaleway/scaleway-sdk-go/scw"
11-
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
12-
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
136
)
147

15-
type BlockAndInstanceAPI struct {
16-
*instance.API
17-
blockAPI *block.API
18-
}
19-
20-
type GetUnknownVolumeRequest struct {
21-
VolumeID string
22-
Zone scw.Zone
23-
}
24-
25-
type ResizeUnknownVolumeRequest struct {
26-
VolumeID string
27-
Zone scw.Zone
28-
Size *scw.Size
29-
}
30-
31-
type DeleteUnknownVolumeRequest struct {
32-
VolumeID string
33-
Zone scw.Zone
34-
}
35-
36-
type UnknownVolume struct {
37-
Zone scw.Zone
38-
ID string
39-
Name string
40-
Size *scw.Size
41-
ServerID *string
42-
Boot *bool
43-
44-
// Iops is set for Block volume only, use IsBlockVolume
45-
// Can be nil if not available in the Block API.
46-
Iops *uint32
47-
48-
InstanceVolumeType instance.VolumeVolumeType
49-
}
50-
51-
// VolumeTemplate returns a template to be used for servers requests.
52-
func (volume *UnknownVolume) VolumeTemplate() *instance.VolumeServerTemplate {
53-
template := &instance.VolumeServerTemplate{}
54-
55-
if volume.ID != "" {
56-
template.ID = &volume.ID
57-
if !volume.IsBlockVolume() {
58-
template.Name = &volume.Name
59-
}
60-
} else {
61-
template.VolumeType = volume.InstanceVolumeType
62-
template.Size = volume.Size
63-
}
64-
65-
if volume.Boot != nil {
66-
template.Boot = volume.Boot
67-
}
68-
69-
if volume.IsBlockVolume() {
70-
template.VolumeType = volume.InstanceVolumeType
71-
}
72-
73-
return template
74-
}
75-
76-
// IsLocal returns true if the volume is a local volume
77-
func (volume *UnknownVolume) IsLocal() bool {
78-
return !volume.IsBlockVolume() && volume.InstanceVolumeType == instance.VolumeVolumeTypeLSSD
79-
}
80-
81-
// IsBlockVolume is true if volume is managed by block API
82-
func (volume *UnknownVolume) IsBlockVolume() bool {
83-
return volume.InstanceVolumeType == instance.VolumeVolumeTypeSbsVolume
84-
}
85-
86-
// IsAttached returns true if the volume is attached to a server
87-
func (volume *UnknownVolume) IsAttached() bool {
88-
return volume.ServerID != nil && *volume.ServerID != ""
89-
}
90-
91-
type UnknownSnapshot struct {
92-
Zone scw.Zone
93-
ID string
94-
Name string
95-
VolumeType instance.VolumeVolumeType
96-
}
97-
98-
func (api *BlockAndInstanceAPI) GetUnknownVolume(req *GetUnknownVolumeRequest, opts ...scw.RequestOption) (*UnknownVolume, error) {
99-
getVolumeResponse, err := api.API.GetVolume(&instance.GetVolumeRequest{
100-
Zone: req.Zone,
101-
VolumeID: req.VolumeID,
102-
}, opts...)
103-
notFoundErr := &scw.ResourceNotFoundError{}
104-
105-
if err != nil && !errors.As(err, &notFoundErr) {
106-
return nil, err
107-
}
108-
109-
if getVolumeResponse != nil {
110-
vol := &UnknownVolume{
111-
Zone: getVolumeResponse.Volume.Zone,
112-
ID: getVolumeResponse.Volume.ID,
113-
Name: getVolumeResponse.Volume.Name,
114-
Size: &getVolumeResponse.Volume.Size,
115-
InstanceVolumeType: getVolumeResponse.Volume.VolumeType,
116-
}
117-
if getVolumeResponse.Volume.Server != nil {
118-
vol.ServerID = &getVolumeResponse.Volume.Server.ID
119-
}
120-
121-
return vol, nil
122-
}
123-
124-
blockVolume, err := api.blockAPI.GetVolume(&block.GetVolumeRequest{
125-
Zone: req.Zone,
126-
VolumeID: req.VolumeID,
127-
}, opts...)
128-
if err != nil {
129-
return nil, err
130-
}
131-
132-
vol := &UnknownVolume{
133-
Zone: blockVolume.Zone,
134-
ID: blockVolume.ID,
135-
Name: blockVolume.Name,
136-
Size: &blockVolume.Size,
137-
InstanceVolumeType: instance.VolumeVolumeTypeSbsVolume,
138-
}
139-
if blockVolume.Specs != nil {
140-
vol.Iops = blockVolume.Specs.PerfIops
141-
}
142-
143-
for _, ref := range blockVolume.References {
144-
if ref.ProductResourceType == "instance_server" {
145-
vol.ServerID = &ref.ProductResourceID
146-
}
147-
}
148-
149-
return vol, nil
150-
}
151-
152-
func (api *BlockAndInstanceAPI) ResizeUnknownVolume(req *ResizeUnknownVolumeRequest, opts ...scw.RequestOption) error {
153-
unknownVolume, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
154-
VolumeID: req.VolumeID,
155-
Zone: req.Zone,
156-
}, opts...)
157-
if err != nil {
158-
return err
159-
}
160-
161-
if unknownVolume.IsBlockVolume() {
162-
_, err = api.blockAPI.UpdateVolume(&block.UpdateVolumeRequest{
163-
Zone: req.Zone,
164-
VolumeID: req.VolumeID,
165-
Size: req.Size,
166-
}, opts...)
167-
} else {
168-
_, err = api.API.UpdateVolume(&instance.UpdateVolumeRequest{
169-
Zone: req.Zone,
170-
VolumeID: req.VolumeID,
171-
Size: req.Size,
172-
}, opts...)
173-
}
174-
175-
return err
176-
}
177-
178-
func (api *BlockAndInstanceAPI) DeleteUnknownVolume(req *DeleteUnknownVolumeRequest, opts ...scw.RequestOption) error {
179-
unknownVolume, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
180-
VolumeID: req.VolumeID,
181-
Zone: req.Zone,
182-
}, opts...)
183-
if err != nil {
184-
return err
185-
}
186-
187-
if unknownVolume.IsBlockVolume() {
188-
err = api.blockAPI.DeleteVolume(&block.DeleteVolumeRequest{
189-
Zone: req.Zone,
190-
VolumeID: req.VolumeID,
191-
}, opts...)
192-
} else {
193-
err = api.API.DeleteVolume(&instance.DeleteVolumeRequest{
194-
Zone: req.Zone,
195-
VolumeID: req.VolumeID,
196-
}, opts...)
197-
}
198-
199-
return err
200-
}
201-
202-
type GetUnknownSnapshotRequest struct {
203-
Zone scw.Zone
204-
SnapshotID string
205-
}
206-
207-
func (api *BlockAndInstanceAPI) GetUnknownSnapshot(req *GetUnknownSnapshotRequest, opts ...scw.RequestOption) (*UnknownSnapshot, error) {
208-
getSnapshotResponse, err := api.GetSnapshot(&instance.GetSnapshotRequest{
209-
Zone: req.Zone,
210-
SnapshotID: req.SnapshotID,
211-
}, opts...)
212-
notFoundErr := &scw.ResourceNotFoundError{}
213-
214-
if err != nil && !errors.As(err, &notFoundErr) {
215-
return nil, err
216-
}
217-
218-
if getSnapshotResponse != nil {
219-
snap := &UnknownSnapshot{
220-
Zone: getSnapshotResponse.Snapshot.Zone,
221-
ID: getSnapshotResponse.Snapshot.ID,
222-
Name: getSnapshotResponse.Snapshot.Name,
223-
VolumeType: getSnapshotResponse.Snapshot.VolumeType,
224-
}
225-
226-
return snap, nil
227-
}
228-
229-
blockSnapshot, err := api.blockAPI.GetSnapshot(&block.GetSnapshotRequest{
230-
Zone: req.Zone,
231-
SnapshotID: req.SnapshotID,
232-
}, opts...)
233-
if err != nil {
234-
return nil, err
235-
}
236-
237-
snap := &UnknownSnapshot{
238-
Zone: blockSnapshot.Zone,
239-
ID: blockSnapshot.ID,
240-
Name: blockSnapshot.Name,
241-
VolumeType: instance.VolumeVolumeTypeSbsSnapshot,
242-
}
243-
244-
return snap, nil
245-
}
246-
247-
func NewBlockAndInstanceAPI(client *scw.Client) *BlockAndInstanceAPI {
248-
instanceAPI := instance.NewAPI(client)
249-
blockAPI := block.NewAPI(client)
250-
251-
return &BlockAndInstanceAPI{
252-
API: instanceAPI,
253-
blockAPI: blockAPI,
254-
}
255-
}
256-
257-
// newAPIWithZone returns a new instance API and the zone for a Create request
258-
func instanceAndBlockAPIWithZone(d *schema.ResourceData, m interface{}) (*BlockAndInstanceAPI, scw.Zone, error) {
259-
zone, err := meta.ExtractZone(d, m)
260-
if err != nil {
261-
return nil, "", err
262-
}
263-
264-
return NewBlockAndInstanceAPI(meta.ExtractScwClient(m)), zone, nil
265-
}
266-
267-
// NewAPIWithZoneAndID returns an instance API with zone and ID extracted from the state
268-
func instanceAndBlockAPIWithZoneAndID(m interface{}, zonedID string) (*BlockAndInstanceAPI, scw.Zone, string, error) {
269-
zone, ID, err := zonal.ParseID(zonedID)
270-
if err != nil {
271-
return nil, "", "", err
272-
}
273-
274-
return NewBlockAndInstanceAPI(meta.ExtractScwClient(m)), zone, ID, nil
275-
}
276-
2778
func volumeTypeToMarketplaceFilter(volumeType instance.VolumeVolumeType) marketplace.LocalImageType {
2789
switch volumeType {
27910
case instance.VolumeVolumeTypeSbsVolume:

0 commit comments

Comments
 (0)