Skip to content

Commit d6ba18c

Browse files
committed
feat(rdb): allow volume size increase when disk is full
1 parent 4464578 commit d6ba18c

28 files changed

+6841
-6933
lines changed

docs/resources/rdb_instance.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ The following arguments are supported:
119119
~> **Important:** Updates to `node_type` will upgrade the Database Instance to the desired `node_type` without any
120120
interruption. Keep in mind that you cannot downgrade a Database Instance.
121121

122+
~> **Important:** Once your instance reaches `disk_full` status, if you are using `lssd` storage, you should upgrade the node_type,
123+
and if you are using `bssd` storage, you should increase the volume size before making any other change to your instance.
124+
122125
- `engine` - (Required) Database Instance's engine version (e.g. `PostgreSQL-11`).
123126

124127
~> **Important:** Updates to `engine` will recreate the Database Instance.
@@ -127,6 +130,8 @@ interruption. Keep in mind that you cannot downgrade a Database Instance.
127130

128131
- `volume_size_in_gb` - (Optional) Volume size (in GB) when `volume_type` is set to `bssd`.
129132

133+
~> **Important:** Once your instance reaches `disk_full` status, you should increase the volume size before making any other change to your instance.
134+
130135
- `user_name` - (Optional) Identifier for the first user of the database instance.
131136

132137
~> **Important:** Updates to `user_name` will recreate the Database Instance.

scaleway/resource_rdb_instance.go

Lines changed: 93 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -451,59 +451,23 @@ func resourceScalewayRdbInstanceUpdate(ctx context.Context, d *schema.ResourceDa
451451
return diag.FromErr(err)
452452
}
453453

454-
req := &rdb.UpdateInstanceRequest{
454+
////////////////////
455+
// Upgrade instance
456+
////////////////////
457+
upgradeInstanceRequests := []rdb.UpgradeInstanceRequest(nil)
458+
459+
rdbInstance, err := rdbAPI.GetInstance(&rdb.GetInstanceRequest{
455460
Region: region,
456461
InstanceID: ID,
457-
}
458-
459-
if d.HasChange("name") {
460-
req.Name = expandStringPtr(d.Get("name"))
461-
}
462-
if d.HasChange("disable_backup") {
463-
req.IsBackupScheduleDisabled = scw.BoolPtr(d.Get("disable_backup").(bool))
464-
}
465-
if d.HasChange("backup_schedule_frequency") {
466-
req.BackupScheduleFrequency = scw.Uint32Ptr(uint32(d.Get("backup_schedule_frequency").(int)))
467-
}
468-
if d.HasChange("backup_schedule_retention") {
469-
req.BackupScheduleRetention = scw.Uint32Ptr(uint32(d.Get("backup_schedule_retention").(int)))
470-
}
471-
if d.HasChange("backup_same_region") {
472-
req.BackupSameRegion = expandBoolPtr(d.Get("backup_same_region"))
473-
}
474-
if d.HasChange("tags") {
475-
req.Tags = expandUpdatedStringsPtr(d.Get("tags"))
476-
}
477-
478-
_, err = waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
479-
if err != nil {
480-
return diag.FromErr(err)
481-
}
482-
483-
_, err = rdbAPI.UpdateInstance(req, scw.WithContext(ctx))
462+
}, scw.WithContext(ctx))
484463
if err != nil {
485464
return diag.FromErr(err)
486465
}
487-
// Change settings
488-
if d.HasChange("settings") {
489-
_, err = waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
490-
if err != nil && !is404Error(err) {
491-
return diag.FromErr(err)
492-
}
493-
_, err := rdbAPI.SetInstanceSettings(&rdb.SetInstanceSettingsRequest{
494-
InstanceID: ID,
495-
Region: region,
496-
Settings: expandInstanceSettings(d.Get("settings")),
497-
}, scw.WithContext(ctx))
498-
if err != nil {
499-
return diag.FromErr(err)
500-
}
501-
}
466+
diskIsFull := rdbInstance.Status == rdb.InstanceStatusDiskFull
467+
volType := rdb.VolumeType(d.Get("volume_type").(string))
502468

503-
upgradeInstanceRequests := []rdb.UpgradeInstanceRequest(nil)
469+
// Volume type and size
504470
if d.HasChanges("volume_type", "volume_size_in_gb") {
505-
volType := rdb.VolumeType(d.Get("volume_type").(string))
506-
507471
switch volType {
508472
case rdb.VolumeTypeBssd:
509473
if d.HasChange("volume_type") {
@@ -551,15 +515,29 @@ func resourceScalewayRdbInstanceUpdate(ctx context.Context, d *schema.ResourceDa
551515
}
552516
}
553517

518+
// Node type
554519
if d.HasChange("node_type") {
555-
upgradeInstanceRequests = append(upgradeInstanceRequests,
556-
rdb.UpgradeInstanceRequest{
557-
Region: region,
558-
InstanceID: ID,
559-
NodeType: expandStringPtr(d.Get("node_type")),
560-
})
520+
// Upgrading the node_type with block storage is not allowed when the disk is full, so if we are in this case,
521+
// we can only allow this action if an increase of the size of the volume is also scheduled before it.
522+
if !diskIsFull || volType == rdb.VolumeTypeLssd || len(upgradeInstanceRequests) > 0 {
523+
upgradeInstanceRequests = append(upgradeInstanceRequests,
524+
rdb.UpgradeInstanceRequest{
525+
Region: region,
526+
InstanceID: ID,
527+
NodeType: expandStringPtr(d.Get("node_type")),
528+
})
529+
} else {
530+
return diag.Diagnostics{
531+
{
532+
Severity: diag.Error,
533+
Summary: "Node type upgrade forbidden when disk is full",
534+
Detail: "You cannot upgrade the node_type of an instance that is using bssd storage once it is in disk_full state. Please increase the volume_size_in_gb first.",
535+
},
536+
}
537+
}
561538
}
562539

540+
// HA cluster
563541
if d.HasChange("is_ha_cluster") {
564542
upgradeInstanceRequests = append(upgradeInstanceRequests,
565543
rdb.UpgradeInstanceRequest{
@@ -568,6 +546,8 @@ func resourceScalewayRdbInstanceUpdate(ctx context.Context, d *schema.ResourceDa
568546
EnableHa: scw.BoolPtr(d.Get("is_ha_cluster").(bool)),
569547
})
570548
}
549+
550+
// Carry out the upgrades
571551
for i := range upgradeInstanceRequests {
572552
_, err = waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
573553
if err != nil && !is404Error(err) {
@@ -585,6 +565,64 @@ func resourceScalewayRdbInstanceUpdate(ctx context.Context, d *schema.ResourceDa
585565
}
586566
}
587567

568+
////////////////////
569+
// Update instance
570+
////////////////////
571+
req := &rdb.UpdateInstanceRequest{
572+
Region: region,
573+
InstanceID: ID,
574+
}
575+
576+
if d.HasChange("name") {
577+
req.Name = expandStringPtr(d.Get("name"))
578+
}
579+
if d.HasChange("disable_backup") {
580+
req.IsBackupScheduleDisabled = scw.BoolPtr(d.Get("disable_backup").(bool))
581+
}
582+
if d.HasChange("backup_schedule_frequency") {
583+
req.BackupScheduleFrequency = scw.Uint32Ptr(uint32(d.Get("backup_schedule_frequency").(int)))
584+
}
585+
if d.HasChange("backup_schedule_retention") {
586+
req.BackupScheduleRetention = scw.Uint32Ptr(uint32(d.Get("backup_schedule_retention").(int)))
587+
}
588+
if d.HasChange("backup_same_region") {
589+
req.BackupSameRegion = expandBoolPtr(d.Get("backup_same_region"))
590+
}
591+
if d.HasChange("tags") {
592+
req.Tags = expandUpdatedStringsPtr(d.Get("tags"))
593+
}
594+
595+
_, err = waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
596+
if err != nil {
597+
return diag.FromErr(err)
598+
}
599+
600+
_, err = rdbAPI.UpdateInstance(req, scw.WithContext(ctx))
601+
if err != nil {
602+
return diag.FromErr(err)
603+
}
604+
605+
////////////////////
606+
// Change settings
607+
////////////////////
608+
if d.HasChange("settings") {
609+
_, err = waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
610+
if err != nil && !is404Error(err) {
611+
return diag.FromErr(err)
612+
}
613+
_, err := rdbAPI.SetInstanceSettings(&rdb.SetInstanceSettingsRequest{
614+
InstanceID: ID,
615+
Region: region,
616+
Settings: expandInstanceSettings(d.Get("settings")),
617+
}, scw.WithContext(ctx))
618+
if err != nil {
619+
return diag.FromErr(err)
620+
}
621+
}
622+
623+
////////////////////
624+
// Update user
625+
////////////////////
588626
if d.HasChange("password") {
589627
_, err := waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))
590628
if err != nil {
@@ -604,6 +642,9 @@ func resourceScalewayRdbInstanceUpdate(ctx context.Context, d *schema.ResourceDa
604642
}
605643
}
606644

645+
////////////////////
646+
// Update endpoints
647+
////////////////////
607648
if d.HasChanges("private_network") {
608649
// retrieve state
609650
res, err := waitForRDBInstance(ctx, rdbAPI, region, ID, d.Timeout(schema.TimeoutUpdate))

0 commit comments

Comments
 (0)