Skip to content

Commit 51570a1

Browse files
rdb: add support for wait on backup resource (#1192)
Co-authored-by: Jerome Quere <[email protected]>
1 parent aed1ed4 commit 51570a1

14 files changed

+2379
-1
lines changed

cmd/scw/testdata/test-all-usage-rdb-backup-create-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ARGS:
1414

1515
FLAGS:
1616
-h, --help help for create
17+
-w, --wait wait until the backup is ready
1718

1819
GLOBAL FLAGS:
1920
-c, --config string The path to the config file

cmd/scw/testdata/test-all-usage-rdb-backup-export-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ ARGS:
1111

1212
FLAGS:
1313
-h, --help help for export
14+
-w, --wait wait until the backup is ready
1415

1516
GLOBAL FLAGS:
1617
-c, --config string The path to the config file

cmd/scw/testdata/test-all-usage-rdb-backup-restore-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ARGS:
1313

1414
FLAGS:
1515
-h, --help help for restore
16+
-w, --wait wait until the backup is ready
1617

1718
GLOBAL FLAGS:
1819
-c, --config string The path to the config file

cmd/scw/testdata/test-all-usage-rdb-backup-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ AVAILABLE COMMANDS:
1313
list List database backups
1414
restore Restore a database backup
1515
update Update a database backup
16+
wait Wait for a backup to reach a stable state
1617

1718
FLAGS:
1819
-h, --help help for backup
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
2+
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
3+
Wait for a backup to reach a stable state. This is similar to using --wait flag.
4+
5+
USAGE:
6+
scw rdb backup wait <backup-id ...> [arg=value ...]
7+
8+
EXAMPLES:
9+
Wait for a backup to reach a stable state
10+
scw rdb backup wait
11+
12+
ARGS:
13+
backup-id ID of the backup you want to wait for.
14+
[region=fr-par] Region to target. If none is passed will use default region from the config (fr-par | nl-ams)
15+
16+
FLAGS:
17+
-h, --help help for wait
18+
19+
GLOBAL FLAGS:
20+
-c, --config string The path to the config file
21+
-D, --debug Enable debug mode
22+
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human")
23+
-p, --profile string The config profile to use

internal/namespaces/rdb/v1/custom.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@ func GetCommands() *core.Commands {
2727
cmds.Merge(core.NewCommands(
2828
instanceWaitCommand(),
2929
instanceConnectCommand(),
30+
backupWaitCommand(),
3031
))
32+
cmds.MustFind("rdb", "backup", "create").Override(backupCreateBuilder)
33+
cmds.MustFind("rdb", "backup", "export").Override(backupExportBuilder)
34+
cmds.MustFind("rdb", "backup", "restore").Override(backupRestoreBuilder)
35+
3136
cmds.MustFind("rdb", "instance", "create").Override(instanceCreateBuilder)
3237
cmds.MustFind("rdb", "instance", "clone").Override(instanceCloneBuilder)
3338
cmds.MustFind("rdb", "instance", "create").Override(instanceCreateBuilder)
34-
3539
cmds.MustFind("rdb", "instance", "upgrade").Override(instanceUpgradeBuilder)
3640

3741
cmds.MustFind("rdb", "engine", "list").Override(engineListBuilder)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package rdb
2+
3+
import (
4+
"context"
5+
"reflect"
6+
"time"
7+
8+
"github.com/scaleway/scaleway-cli/internal/core"
9+
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
)
12+
13+
const (
14+
backupActionTimeout = 20 * time.Minute
15+
)
16+
17+
type backupWaitRequest struct {
18+
DatabaseBackupID string
19+
Region scw.Region
20+
}
21+
22+
func backupWaitCommand() *core.Command {
23+
return &core.Command{
24+
Short: `Wait for a backup to reach a stable state`,
25+
Long: `Wait for a backup to reach a stable state. This is similar to using --wait flag.`,
26+
Namespace: "rdb",
27+
Resource: "backup",
28+
Verb: "wait",
29+
ArgsType: reflect.TypeOf(backupWaitRequest{}),
30+
Run: func(ctx context.Context, argsI interface{}) (i interface{}, err error) {
31+
api := rdb.NewAPI(core.ExtractClient(ctx))
32+
return api.WaitForDatabaseBackup(&rdb.WaitForDatabaseBackupRequest{
33+
DatabaseBackupID: argsI.(*backupWaitRequest).DatabaseBackupID,
34+
Region: argsI.(*backupWaitRequest).Region,
35+
Timeout: scw.TimeDurationPtr(backupActionTimeout),
36+
RetryInterval: core.DefaultRetryInterval,
37+
})
38+
},
39+
ArgSpecs: core.ArgSpecs{
40+
{
41+
Name: "backup-id",
42+
Short: `ID of the backup you want to wait for.`,
43+
Required: true,
44+
Positional: true,
45+
},
46+
core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms),
47+
},
48+
Examples: []*core.Example{
49+
{
50+
Short: "Wait for a backup to reach a stable state",
51+
ArgsJSON: `{"backup_id": "11111111-1111-1111-1111-111111111111"}`,
52+
},
53+
},
54+
}
55+
}
56+
57+
func backupCreateBuilder(c *core.Command) *core.Command {
58+
timeout := backupActionTimeout
59+
c.WaitFunc = func(ctx context.Context, argsI, respI interface{}) (interface{}, error) {
60+
api := rdb.NewAPI(core.ExtractClient(ctx))
61+
return api.WaitForDatabaseBackup(&rdb.WaitForDatabaseBackupRequest{
62+
DatabaseBackupID: respI.(*rdb.DatabaseBackup).ID,
63+
Region: respI.(*rdb.DatabaseBackup).Region,
64+
Timeout: &timeout,
65+
RetryInterval: core.DefaultRetryInterval,
66+
})
67+
}
68+
69+
return c
70+
}
71+
72+
func backupExportBuilder(c *core.Command) *core.Command {
73+
timeout := backupActionTimeout
74+
c.WaitFunc = func(ctx context.Context, argsI, respI interface{}) (interface{}, error) {
75+
api := rdb.NewAPI(core.ExtractClient(ctx))
76+
return api.WaitForDatabaseBackup(&rdb.WaitForDatabaseBackupRequest{
77+
DatabaseBackupID: respI.(*rdb.DatabaseBackup).ID,
78+
Region: respI.(*rdb.DatabaseBackup).Region,
79+
Timeout: &timeout,
80+
RetryInterval: core.DefaultRetryInterval,
81+
})
82+
}
83+
84+
return c
85+
}
86+
87+
func backupRestoreBuilder(c *core.Command) *core.Command {
88+
timeout := backupActionTimeout
89+
c.WaitFunc = func(ctx context.Context, argsI, respI interface{}) (interface{}, error) {
90+
api := rdb.NewAPI(core.ExtractClient(ctx))
91+
return api.WaitForDatabaseBackup(&rdb.WaitForDatabaseBackupRequest{
92+
DatabaseBackupID: respI.(*rdb.DatabaseBackup).ID,
93+
Region: respI.(*rdb.DatabaseBackup).Region,
94+
Timeout: &timeout,
95+
RetryInterval: core.DefaultRetryInterval,
96+
})
97+
}
98+
99+
return c
100+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package rdb
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/scaleway/scaleway-cli/internal/core"
8+
"github.com/scaleway/scaleway-sdk-go/scw"
9+
)
10+
11+
func Test_CreateBackup(t *testing.T) {
12+
t.Run("Simple", core.Test(&core.TestConfig{
13+
Commands: GetCommands(),
14+
BeforeFunc: core.BeforeFuncCombine(
15+
createInstance(engine),
16+
// We opened an internal issue about the fact that the instance is considered ready even if rdb is not yet available.
17+
core.BeforeFuncWhenUpdatingCassette(
18+
func(ctx *core.BeforeFuncCtx) error {
19+
time.Sleep(1 * time.Minute)
20+
return nil
21+
},
22+
),
23+
),
24+
Cmd: "scw rdb backup create name=foobar expires-at=2999-01-02T15:04:05-07:00 instance-id={{ .Instance.ID }} database-name=rdb --wait",
25+
Check: core.TestCheckGolden(),
26+
AfterFunc: deleteInstance(),
27+
DefaultRegion: scw.RegionNlAms,
28+
}))
29+
}
30+
31+
func Test_RestoreBackup(t *testing.T) {
32+
t.Run("Simple", core.Test(&core.TestConfig{
33+
Commands: GetCommands(),
34+
BeforeFunc: core.BeforeFuncCombine(
35+
createInstance(engine),
36+
// We opened an internal issue about the fact that the instance is considered ready even if rdb is not yet available.
37+
core.BeforeFuncWhenUpdatingCassette(
38+
func(ctx *core.BeforeFuncCtx) error {
39+
time.Sleep(1 * time.Minute)
40+
return nil
41+
},
42+
),
43+
core.ExecStoreBeforeCmd(
44+
"Backup",
45+
"scw rdb backup create name=foobar expires-at=2999-01-02T15:04:05-07:00 instance-id={{ .Instance.ID }} database-name=rdb --wait",
46+
),
47+
),
48+
Cmd: "scw rdb backup restore {{ .Backup.ID }} instance-id={{ .Instance.ID }} --wait",
49+
Check: core.TestCheckCombine(
50+
core.TestCheckGolden(),
51+
core.TestCheckExitCode(0),
52+
),
53+
AfterFunc: deleteInstance(),
54+
DefaultRegion: scw.RegionNlAms,
55+
}))
56+
}
57+
58+
func Test_ExportBackup(t *testing.T) {
59+
t.Run("Simple", core.Test(&core.TestConfig{
60+
Commands: GetCommands(),
61+
BeforeFunc: core.BeforeFuncCombine(
62+
createInstance(engine),
63+
// We opened an internal issue about the fact that the instance is considered ready even if rdb is not yet available.
64+
core.BeforeFuncWhenUpdatingCassette(
65+
func(ctx *core.BeforeFuncCtx) error {
66+
time.Sleep(1 * time.Minute)
67+
return nil
68+
},
69+
),
70+
core.ExecStoreBeforeCmd(
71+
"Backup",
72+
"scw rdb backup create name=foobar expires-at=2999-01-02T15:04:05-07:00 instance-id={{ .Instance.ID }} database-name=rdb --wait",
73+
),
74+
),
75+
Cmd: "scw rdb backup export {{ .Backup.ID }} --wait",
76+
Check: core.TestCheckCombine(
77+
core.TestCheckGolden(),
78+
core.TestCheckExitCode(0),
79+
),
80+
AfterFunc: deleteInstance(),
81+
DefaultRegion: scw.RegionNlAms,
82+
}))
83+
}

0 commit comments

Comments
 (0)