diff --git a/api/rdb/v1/rdb_utils.go b/api/rdb/v1/rdb_utils.go index 70f52cec0..e0178206a 100644 --- a/api/rdb/v1/rdb_utils.go +++ b/api/rdb/v1/rdb_utils.go @@ -61,3 +61,50 @@ func (s *API) WaitForInstance(req *WaitForInstanceRequest) (*Instance, error) { } return instance.(*Instance), nil } + +type WaitForDatabaseBackupRequest struct { + DatabaseBackupID string + Region scw.Region + Timeout *time.Duration + RetryInterval *time.Duration +} + +// WaitForDatabaseBackup waits for the backup to be in a "terminal state" before returning. +// This function can be used to wait for a backup to be ready for example. +func (s *API) WaitForDatabaseBackup(req *WaitForDatabaseBackupRequest) (*DatabaseBackup, error) { + timeout := defaultTimeout + if req.Timeout != nil { + timeout = *req.Timeout + } + retryInterval := defaultRetryInterval + if req.RetryInterval != nil { + retryInterval = *req.RetryInterval + } + + terminalStatus := map[DatabaseBackupStatus]struct{}{ + DatabaseBackupStatusReady: {}, + DatabaseBackupStatusError: {}, + } + + backup, err := async.WaitSync(&async.WaitSyncConfig{ + Get: func() (interface{}, bool, error) { + res, err := s.GetDatabaseBackup(&GetDatabaseBackupRequest{ + DatabaseBackupID: req.DatabaseBackupID, + Region: req.Region, + }) + + if err != nil { + return nil, false, err + } + _, isTerminal := terminalStatus[res.Status] + + return res, isTerminal, nil + }, + Timeout: timeout, + IntervalStrategy: async.LinearIntervalStrategy(retryInterval), + }) + if err != nil { + return nil, errors.Wrap(err, "waiting for database backup failed") + } + return backup.(*DatabaseBackup), nil +}