Skip to content

Commit

Permalink
feat(instance_server): allow root_volume size update (#2745)
Browse files Browse the repository at this point in the history
* feat(instance_server): allow root_volume size update

* add tests

* record new test
  • Loading branch information
Codelax authored Oct 1, 2024
1 parent 148e0c8 commit 82c9f80
Show file tree
Hide file tree
Showing 6 changed files with 5,055 additions and 1,092 deletions.
32 changes: 32 additions & 0 deletions internal/services/instance/helpers_instance_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ type GetUnknownVolumeRequest struct {
Zone scw.Zone
}

type ResizeUnknownVolumeRequest struct {
VolumeID string
Zone scw.Zone
Size *scw.Size
}

type UnknownVolume struct {
Zone scw.Zone
ID string
Expand Down Expand Up @@ -129,6 +135,32 @@ func (api *BlockAndInstanceAPI) GetUnknownVolume(req *GetUnknownVolumeRequest, o
return vol, nil
}

func (api *BlockAndInstanceAPI) ResizeUnknownVolume(req *ResizeUnknownVolumeRequest, opts ...scw.RequestOption) error {
unknownVolume, err := api.GetUnknownVolume(&GetUnknownVolumeRequest{
VolumeID: req.VolumeID,
Zone: req.Zone,
}, opts...)
if err != nil {
return err
}

if unknownVolume.IsBlockVolume() {
_, err = api.blockAPI.UpdateVolume(&block.UpdateVolumeRequest{
Zone: req.Zone,
VolumeID: req.VolumeID,
Size: req.Size,
}, opts...)
} else {
_, err = api.API.UpdateVolume(&instance.UpdateVolumeRequest{
Zone: req.Zone,
VolumeID: req.VolumeID,
Size: req.Size,
}, opts...)
}

return err
}

// newAPIWithZone returns a new instance API and the zone for a Create request
func instanceAndBlockAPIWithZone(d *schema.ResourceData, m interface{}) (*BlockAndInstanceAPI, scw.Zone, error) {
instanceAPI := instance.NewAPI(meta.ExtractScwClient(m))
Expand Down
17 changes: 14 additions & 3 deletions internal/services/instance/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ func ResourceInstanceServerUpdate(ctx context.Context, d *schema.ResourceData, m
}

if d.HasChanges("additional_volume_ids", "root_volume") {
volumes, err := instanceServerVolumesTemplatesUpdate(ctx, d, api, zone, isStopped)
volumes, err := instanceServerVolumesUpdate(ctx, d, api, zone, isStopped)
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -1396,12 +1396,23 @@ func ResourceInstanceServerUpdateRootVolumeIOPS(ctx context.Context, api *BlockA
return nil
}

// instanceServerVolumesTemplatesUpdate returns the list of volumes templates that should be updated for the server.
// instanceServerVolumesUpdate updates root_volume size and 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) {
func instanceServerVolumesUpdate(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")

if d.HasChange("root_volume.0.size_in_gb") {
err := api.ResizeUnknownVolume(&ResizeUnknownVolumeRequest{
VolumeID: zonal.ExpandID(d.Get("root_volume.0.volume_id")).ID,
Zone: zone,
Size: scw.SizePtr(scw.Size(d.Get("root_volume.0.size_in_gb").(int)) * scw.GB),
}, scw.WithContext(ctx))
if err != nil {
return nil, err
}
}

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
Expand Down
38 changes: 38 additions & 0 deletions internal/services/instance/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,24 @@ func TestAccServer_RootVolume1(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
isServerPresent(tt, "scaleway_instance_server.base"),
serverHasNewVolume(tt, "scaleway_instance_server.base"),
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.size_in_gb", "10"),
),
},
{
Config: `
resource "scaleway_instance_server" "base" {
image = "ubuntu_focal"
type = "DEV1-S"
root_volume {
size_in_gb = 20
delete_on_termination = true
}
tags = [ "terraform-test", "scaleway_instance_server", "root_volume" ]
}`,
Check: resource.ComposeTestCheckFunc(
isServerPresent(tt, "scaleway_instance_server.base"),
serverHasNewVolume(tt, "scaleway_instance_server.base"),
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.size_in_gb", "20"),
),
},
},
Expand Down Expand Up @@ -2008,6 +2026,26 @@ func TestAccServer_BlockExternalRootVolume(t *testing.T) {
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.size_in_gb", "50"),
),
},
{
Config: `
resource "scaleway_instance_server" "main" {
name = "tf-tests-instance-block-external-root-volume"
image = "ubuntu_jammy"
type = "PLAY2-PICO"
root_volume {
volume_type = "sbs_volume"
size_in_gb = 60
sbs_iops = 15000
}
}`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("scaleway_instance_server.main", "type", "PLAY2-PICO"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "additional_volume_ids.#", "0"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.volume_type", string(instanceSDK.VolumeVolumeTypeSbsVolume)),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.sbs_iops", "15000"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.size_in_gb", "60"),
),
},
},
})
}
Expand Down
1,053 changes: 502 additions & 551 deletions internal/services/instance/testdata/private-nic-with-ipam.cassette.yaml

Large diffs are not rendered by default.

Loading

0 comments on commit 82c9f80

Please sign in to comment.