Skip to content

Commit a539cbc

Browse files
committed
feat(backup): add public backups API
1 parent 75f3720 commit a539cbc

File tree

4 files changed

+887
-0
lines changed

4 files changed

+887
-0
lines changed

backup/client.go

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
package backup
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/weaviate/weaviate-go-client/v6/internal"
9+
"github.com/weaviate/weaviate-go-client/v6/internal/api"
10+
"github.com/weaviate/weaviate-go-client/v6/internal/dev"
11+
)
12+
13+
func NewClient(t internal.Transport) *Client {
14+
dev.AssertNotNil(t, "transport")
15+
return &Client{transport: t}
16+
}
17+
18+
type Client struct {
19+
transport internal.Transport
20+
}
21+
22+
type Info struct {
23+
Backend string // Backup storage backend
24+
ID string // Backup ID
25+
Path string // Path to backup in the backend storage
26+
Error string // Backup creation / restoration error.
27+
Status Status // Backup creation / restoration status.
28+
StartedAt time.Time // Time at which the backup creation started.
29+
CompletedAt *time.Time // Time at which the backup was completed, successfully or otherwise.
30+
31+
// IncludesCollections is always empty for backups that are still being created.
32+
// This field will be populated for restored backups and already-created backups
33+
// returned from List, provided these backups included at least one collection.
34+
IncludesCollections []string // Collections included in the backup
35+
36+
// Backup size in GiB. Similarly to IncludesCollections,
37+
// this value only exists for completed backups.
38+
SizeGiB *float32
39+
40+
c *Client
41+
operation api.BackupOperation
42+
}
43+
44+
// IsCompleted returns true if the backup operation has completed, successfully or otherwise.
45+
// All backups returned from List are completed by definition.
46+
func (i *Info) IsCompleted() bool {
47+
return i.operation == completed ||
48+
i.Status == StatusSuccess ||
49+
i.Status == StatusFailed ||
50+
i.Status == StatusCanceled
51+
}
52+
53+
type (
54+
CompressionLevel api.BackupCompressionLevel
55+
Status api.BackupStatus
56+
RBACRestore api.RBACRestoreOption
57+
)
58+
59+
const (
60+
CompressionLevelDefault CompressionLevel = CompressionLevel(api.BackupCompressionLevelDefault)
61+
CompressionLevelBestSpeed CompressionLevel = CompressionLevel(api.BackupCompressionLevelBestSpeed)
62+
CompressionLevelBestCompression CompressionLevel = CompressionLevel(api.BackupCompressionLevelBestCompression)
63+
CompressionLevelZstdDefault CompressionLevel = CompressionLevel(api.BackupCompressionLevelZstdDefault)
64+
CompressionLevelZstdBestSpeed CompressionLevel = CompressionLevel(api.BackupCompressionLevelZstdBestSpeed)
65+
CompressionLevelZstdBestCompression CompressionLevel = CompressionLevel(api.BackupCompressionLevelZstdBestCompression)
66+
CompressionLevelNone CompressionLevel = CompressionLevel(api.BackupCompressionLevelNone)
67+
68+
StatusStarted Status = Status(api.BackupStatusStarted)
69+
StatusTransferring Status = Status(api.BackupStatusTransferring)
70+
StatusTransferred Status = Status(api.BackupStatusTransferred)
71+
StatusFinalizing Status = Status(api.BackupStatusFinalizing)
72+
StatusCanceling Status = Status(api.BackupStatusCanceling)
73+
StatusCanceled Status = Status(api.BackupStatusCanceled)
74+
StatusSuccess Status = Status(api.BackupStatusSuccess)
75+
StatusFailed Status = Status(api.BackupStatusFailed)
76+
77+
RBACRestoreAll RBACRestore = RBACRestore(api.RBACRestoreAll)
78+
RBACRestoreNone RBACRestore = RBACRestore(api.RBACRestoreNone)
79+
)
80+
81+
type Create struct {
82+
Backend string // Required: backend storage.
83+
ID string // Required: backup ID.
84+
Path string // Path to backup in the backend storage.
85+
Endpoint string // Name of the endpoint, e.g. s3.amazonaws.com
86+
Bucket string // Dedicated bucket name.
87+
IncludeCollections []string // Collections to be included in the backup.
88+
ExcludeCollections []string // Collections to be excluded from the backup.
89+
PrefixIncremental string // Backup ID prefix. Setting it enables incremental backups.
90+
MaxCPUPercentage int // Maximum %CPU utilization.
91+
ChunkSizeMiB int // Target chunk size in MiB.
92+
CompressionLevel CompressionLevel // Hint for selecting the optimal compression algorithm.
93+
}
94+
95+
/** Create a new backup.*/
96+
func (c *Client) Create(ctx context.Context, options Create) (*Info, error) {
97+
req := &api.CreateBackupRequest{
98+
Backend: options.Backend,
99+
ID: options.ID,
100+
Bucket: options.Bucket,
101+
BackupPath: options.Path,
102+
Endpoint: options.Endpoint,
103+
IncludeCollections: options.IncludeCollections,
104+
ExcludeCollections: options.ExcludeCollections,
105+
PrefixIncremental: options.PrefixIncremental,
106+
MaxCPUPercentage: options.MaxCPUPercentage,
107+
ChunkSizeMiB: options.ChunkSizeMiB,
108+
CompressionLevel: api.BackupCompressionLevel(options.CompressionLevel),
109+
}
110+
111+
var resp api.BackupInfo
112+
if err := c.transport.Do(ctx, req, &resp); err != nil {
113+
return nil, fmt.Errorf("create backup: %w", err)
114+
}
115+
116+
info := infoFromAPI(&resp, c, api.BackupOperationCreate)
117+
return &info, nil
118+
}
119+
120+
type Restore struct {
121+
Backend string // Required: backend storage.
122+
ID string // Required: backup ID.
123+
Path string // Path to backup in the backend storage.
124+
Endpoint string // Name of the endpoint, e.g. s3.amazonaws.com
125+
Bucket string // Dedicated bucket name.
126+
IncludeCollections []string // Collections to be included in the backup.
127+
ExcludeCollections []string // Collections to be excluded from the backup.
128+
MaxCPUPercentage int // Maximum %CPU utilization.
129+
OverwriteAlias bool // Allow overwriting aliases.
130+
RestoreUsers RBACRestore // Select strategy for restoring RBAC users.
131+
RestoreRoles RBACRestore // Select strategy for restoring RBAC roles.
132+
NodeMapping map[string]string // Remap node names stored in the backup.
133+
}
134+
135+
func (c *Client) Restore(ctx context.Context, options Restore) (*Info, error) {
136+
req := &api.RestoreBackupRequest{
137+
Backend: options.Backend,
138+
ID: options.ID,
139+
Bucket: options.Bucket,
140+
BackupPath: options.Path,
141+
Endpoint: options.Endpoint,
142+
IncludeCollections: options.IncludeCollections,
143+
ExcludeCollections: options.ExcludeCollections,
144+
MaxCPUPercentage: options.MaxCPUPercentage,
145+
OverwriteAlias: options.OverwriteAlias,
146+
RestoreUsers: api.RBACRestoreOption(options.RestoreUsers),
147+
RestoreRoles: api.RBACRestoreOption(options.RestoreRoles),
148+
NodeMapping: options.NodeMapping,
149+
}
150+
151+
var resp api.BackupInfo
152+
if err := c.transport.Do(ctx, req, &resp); err != nil {
153+
return nil, fmt.Errorf("restore backup: %w", err)
154+
}
155+
156+
info := infoFromAPI(&resp, c, api.BackupOperationRestore)
157+
return &info, nil
158+
}
159+
160+
type GetStatus struct {
161+
Backend string // Required: Backend storage.
162+
ID string // Required: Backup ID.
163+
}
164+
165+
func (c *Client) GetCreateStatus(ctx context.Context, options GetStatus) (*Info, error) {
166+
return c.getStatus(ctx, options, api.BackupOperationCreate)
167+
}
168+
169+
func (c *Client) GetRestoreStatus(ctx context.Context, options GetStatus) (*Info, error) {
170+
return c.getStatus(ctx, options, api.BackupOperationRestore)
171+
}
172+
173+
func (c *Client) getStatus(ctx context.Context, options GetStatus, operation api.BackupOperation) (*Info, error) {
174+
req := &api.BackupStatusRequest{
175+
Backend: options.Backend,
176+
ID: options.ID,
177+
Operation: operation,
178+
}
179+
180+
var resp api.BackupInfo
181+
if err := c.transport.Do(ctx, req, &resp); err != nil {
182+
return nil, fmt.Errorf("get backup status: %w", err)
183+
}
184+
185+
info := infoFromAPI(&resp, c, operation)
186+
return &info, nil
187+
}
188+
189+
type List struct {
190+
Backend string // Required: Backend storage.
191+
StartingTimeAsc bool // Set to true to order backups by their StartedAt time in ascending order.
192+
}
193+
194+
func (c *Client) List(ctx context.Context, options List) ([]Info, error) {
195+
req := &api.ListBackupsRequest{
196+
Backend: options.Backend,
197+
StartingTimeAsc: options.StartingTimeAsc,
198+
}
199+
200+
var resp []api.BackupInfo
201+
if err := c.transport.Do(ctx, req, &resp); err != nil {
202+
return nil, fmt.Errorf("list backups: %w", err)
203+
}
204+
205+
infos := make([]Info, len(resp))
206+
for i, bak := range resp {
207+
infos[i] = infoFromAPI(&bak, c, completed)
208+
}
209+
return infos, nil
210+
}
211+
212+
type Cancel struct {
213+
Backend string // Required: Backend storage.
214+
ID string // Required: Backup ID.
215+
}
216+
217+
// Cancel an in-progress backup creation.
218+
func (c *Client) CancelCreate(ctx context.Context, options Cancel) error {
219+
return c.cancel(ctx, options, api.BackupOperationCreate)
220+
}
221+
222+
// Cancel an in-progress backup restoration.
223+
func (c *Client) CancelRestore(ctx context.Context, options Cancel) error {
224+
return c.cancel(ctx, options, api.BackupOperationRestore)
225+
}
226+
227+
func (c *Client) cancel(ctx context.Context, options Cancel, op api.BackupOperation) error {
228+
req := api.CancelBackupRequest{
229+
Backend: options.Backend,
230+
ID: options.ID,
231+
Operation: op,
232+
}
233+
if err := c.transport.Do(ctx, &req, nil); err != nil {
234+
return fmt.Errorf("cancel backup: %w", err)
235+
}
236+
return nil
237+
}
238+
239+
// completed is a special flag for operations returned from List.
240+
// Those operations technically have api.CreateBackup origin, but
241+
// Info.operation is used to await backup completion (or any other status),
242+
// and, since they are already completed, we can give awaiters a hint.
243+
const completed api.BackupOperation = api.BackupOperation(api.BackupOperationCreate - 1)
244+
245+
func infoFromAPI(bak *api.BackupInfo, c *Client, op api.BackupOperation) Info {
246+
return Info{
247+
ID: bak.ID,
248+
Path: bak.Path,
249+
Backend: bak.Backend,
250+
Status: Status(bak.Status),
251+
Error: bak.Error,
252+
StartedAt: bak.StartedAt,
253+
CompletedAt: bak.CompletedAt,
254+
IncludesCollections: bak.IncludesCollections,
255+
SizeGiB: bak.SizeGiB,
256+
257+
operation: op,
258+
c: c,
259+
}
260+
}

0 commit comments

Comments
 (0)