Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(instance): extract server volumes update #2743

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 40 additions & 29 deletions internal/services/instance/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,36 +816,11 @@ func ResourceInstanceServerUpdate(ctx context.Context, d *schema.ResourceData, m
updateRequest.DynamicIPRequired = scw.BoolPtr(d.Get("enable_dynamic_ip").(bool))
}

volumes := map[string]*instanceSDK.VolumeServerTemplate{}

if raw, hasAdditionalVolumes := d.GetOk("additional_volume_ids"); d.HasChanges("additional_volume_ids", "root_volume") {
volumes["0"] = &instanceSDK.VolumeServerTemplate{
ID: scw.StringPtr(zonal.ExpandID(d.Get("root_volume.0.volume_id")).ID),
Name: scw.StringPtr(types.NewRandomName("vol")), // name is ignored by the API, any name will work here
Boot: types.ExpandBoolPtr(d.Get("root_volume.0.boot")),
}

if !hasAdditionalVolumes {
raw = []interface{}{} // Set an empty list if not volumes exist
}

for i, volumeID := range raw.([]interface{}) {
volumeHasChange := d.HasChange("additional_volume_ids." + strconv.Itoa(i))
volume, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
VolumeID: zonal.ExpandID(volumeID).ID,
Zone: zone,
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(fmt.Errorf("failed to get updated volume: %w", err))
}

// local volumes can only be added when the server is stopped
if volumeHasChange && !isStopped && volume.IsLocal() && volume.IsAttached() {
return diag.FromErr(errors.New("instanceSDK must be stopped to change local volumes"))
}
volumes[strconv.Itoa(i+1)] = volume.VolumeTemplate()
if d.HasChanges("additional_volume_ids", "root_volume") {
volumes, err := instanceServerVolumesTemplatesUpdate(ctx, d, api, zone, isStopped)
if err != nil {
return diag.FromErr(err)
}

serverShouldUpdate = true
updateRequest.Volumes = &volumes
}
Expand Down Expand Up @@ -1420,3 +1395,39 @@ func ResourceInstanceServerUpdateRootVolumeIOPS(ctx context.Context, api *BlockA

return nil
}

// instanceServerVolumesTemplatesUpdate returns the list of volumes templates that should be updated for the server.
// It uses root_volume and additional_volume_ids to build the volumes templates.
func instanceServerVolumesTemplatesUpdate(ctx context.Context, d *schema.ResourceData, api *BlockAndInstanceAPI, zone scw.Zone, serverIsStopped bool) (map[string]*instanceSDK.VolumeServerTemplate, error) {
volumes := map[string]*instanceSDK.VolumeServerTemplate{}
raw, hasAdditionalVolumes := d.GetOk("additional_volume_ids")

volumes["0"] = &instanceSDK.VolumeServerTemplate{
ID: scw.StringPtr(zonal.ExpandID(d.Get("root_volume.0.volume_id")).ID),
Name: scw.StringPtr(types.NewRandomName("vol")), // name is ignored by the API, any name will work here
Boot: types.ExpandBoolPtr(d.Get("root_volume.0.boot")),
}

if !hasAdditionalVolumes {
raw = []interface{}{} // Set an empty list if not volumes exist
}

for i, volumeID := range raw.([]interface{}) {
volumeHasChange := d.HasChange("additional_volume_ids." + strconv.Itoa(i))
volume, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
VolumeID: zonal.ExpandID(volumeID).ID,
Zone: zone,
}, scw.WithContext(ctx))
if err != nil {
return nil, fmt.Errorf("failed to get updated volume: %w", err)
}

// local volumes can only be added when the server is stopped
if volumeHasChange && !serverIsStopped && volume.IsLocal() && volume.IsAttached() {
return nil, errors.New("instanceSDK must be stopped to change local volumes")
}
volumes[strconv.Itoa(i+1)] = volume.VolumeTemplate()
}

return volumes, nil
}
Loading