189 lines
5.6 KiB
Go
189 lines
5.6 KiB
Go
|
package linodego
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// InstanceBackupsResponse response struct for backup snapshot
|
||
|
type InstanceBackupsResponse struct {
|
||
|
Automatic []*InstanceSnapshot `json:"automatic"`
|
||
|
Snapshot *InstanceBackupSnapshotResponse `json:"snapshot"`
|
||
|
}
|
||
|
|
||
|
// InstanceBackupSnapshotResponse fields are those representing Instance Backup Snapshots
|
||
|
type InstanceBackupSnapshotResponse struct {
|
||
|
Current *InstanceSnapshot `json:"current"`
|
||
|
InProgress *InstanceSnapshot `json:"in_progress"`
|
||
|
}
|
||
|
|
||
|
// RestoreInstanceOptions fields are those accepted by InstanceRestore
|
||
|
type RestoreInstanceOptions struct {
|
||
|
LinodeID int `json:"linode_id"`
|
||
|
Overwrite bool `json:"overwrite"`
|
||
|
}
|
||
|
|
||
|
// InstanceSnapshot represents a linode backup snapshot
|
||
|
type InstanceSnapshot struct {
|
||
|
CreatedStr string `json:"created"`
|
||
|
UpdatedStr string `json:"updated"`
|
||
|
FinishedStr string `json:"finished"`
|
||
|
|
||
|
ID int `json:"id"`
|
||
|
Label string `json:"label"`
|
||
|
Status InstanceSnapshotStatus `json:"status"`
|
||
|
Type string `json:"type"`
|
||
|
Created *time.Time `json:"-"`
|
||
|
Updated *time.Time `json:"-"`
|
||
|
Finished *time.Time `json:"-"`
|
||
|
Configs []string `json:"configs"`
|
||
|
Disks []*InstanceSnapshotDisk `json:"disks"`
|
||
|
}
|
||
|
|
||
|
// InstanceSnapshotDisk fields represent the source disk of a Snapshot
|
||
|
type InstanceSnapshotDisk struct {
|
||
|
Label string `json:"label"`
|
||
|
Size int `json:"size"`
|
||
|
Filesystem string `json:"filesystem"`
|
||
|
}
|
||
|
|
||
|
// InstanceSnapshotStatus constants start with Snapshot and include Linode API Instance Backup Snapshot status values
|
||
|
type InstanceSnapshotStatus string
|
||
|
|
||
|
// InstanceSnapshotStatus constants reflect the current status of an Instance Snapshot
|
||
|
var (
|
||
|
SnapshotPaused InstanceSnapshotStatus = "paused"
|
||
|
SnapshotPending InstanceSnapshotStatus = "pending"
|
||
|
SnapshotRunning InstanceSnapshotStatus = "running"
|
||
|
SnapshotNeedsPostProcessing InstanceSnapshotStatus = "needsPostProcessing"
|
||
|
SnapshotSuccessful InstanceSnapshotStatus = "successful"
|
||
|
SnapshotFailed InstanceSnapshotStatus = "failed"
|
||
|
SnapshotUserAborted InstanceSnapshotStatus = "userAborted"
|
||
|
)
|
||
|
|
||
|
func (l *InstanceSnapshot) fixDates() *InstanceSnapshot {
|
||
|
l.Created, _ = parseDates(l.CreatedStr)
|
||
|
l.Updated, _ = parseDates(l.UpdatedStr)
|
||
|
l.Finished, _ = parseDates(l.FinishedStr)
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
// GetInstanceSnapshot gets the snapshot with the provided ID
|
||
|
func (c *Client) GetInstanceSnapshot(ctx context.Context, linodeID int, snapshotID int) (*InstanceSnapshot, error) {
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
e = fmt.Sprintf("%s/%d", e, snapshotID)
|
||
|
r, err := coupleAPIErrors(c.R(ctx).SetResult(&InstanceSnapshot{}).Get(e))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return r.Result().(*InstanceSnapshot).fixDates(), nil
|
||
|
}
|
||
|
|
||
|
// CreateInstanceSnapshot Creates or Replaces the snapshot Backup of a Linode. If a previous snapshot exists for this Linode, it will be deleted.
|
||
|
func (c *Client) CreateInstanceSnapshot(ctx context.Context, linodeID int, label string) (*InstanceSnapshot, error) {
|
||
|
o, err := json.Marshal(map[string]string{"label": label})
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
body := string(o)
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
r, err := coupleAPIErrors(c.R(ctx).
|
||
|
SetBody(body).
|
||
|
SetResult(&InstanceSnapshot{}).
|
||
|
Post(e))
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return r.Result().(*InstanceSnapshot).fixDates(), nil
|
||
|
}
|
||
|
|
||
|
// GetInstanceBackups gets the Instance's available Backups.
|
||
|
// This is not called ListInstanceBackups because a single object is returned, matching the API response.
|
||
|
func (c *Client) GetInstanceBackups(ctx context.Context, linodeID int) (*InstanceBackupsResponse, error) {
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
r, err := coupleAPIErrors(c.R(ctx).
|
||
|
SetResult(&InstanceBackupsResponse{}).
|
||
|
Get(e))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return r.Result().(*InstanceBackupsResponse).fixDates(), nil
|
||
|
}
|
||
|
|
||
|
// EnableInstanceBackups Enables backups for the specified Linode.
|
||
|
func (c *Client) EnableInstanceBackups(ctx context.Context, linodeID int) error {
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
e = fmt.Sprintf("%s/enable", e)
|
||
|
|
||
|
_, err = coupleAPIErrors(c.R(ctx).Post(e))
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// CancelInstanceBackups Cancels backups for the specified Linode.
|
||
|
func (c *Client) CancelInstanceBackups(ctx context.Context, linodeID int) error {
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
e = fmt.Sprintf("%s/cancel", e)
|
||
|
|
||
|
_, err = coupleAPIErrors(c.R(ctx).Post(e))
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// RestoreInstanceBackup Restores a Linode's Backup to the specified Linode.
|
||
|
func (c *Client) RestoreInstanceBackup(ctx context.Context, linodeID int, backupID int, opts RestoreInstanceOptions) error {
|
||
|
o, err := json.Marshal(opts)
|
||
|
if err != nil {
|
||
|
return NewError(err)
|
||
|
}
|
||
|
body := string(o)
|
||
|
e, err := c.InstanceSnapshots.endpointWithID(linodeID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
e = fmt.Sprintf("%s/%d/restore", e, backupID)
|
||
|
|
||
|
_, err = coupleAPIErrors(c.R(ctx).SetBody(body).Post(e))
|
||
|
|
||
|
return err
|
||
|
|
||
|
}
|
||
|
|
||
|
func (l *InstanceBackupSnapshotResponse) fixDates() *InstanceBackupSnapshotResponse {
|
||
|
if l.Current != nil {
|
||
|
l.Current.fixDates()
|
||
|
}
|
||
|
if l.InProgress != nil {
|
||
|
l.InProgress.fixDates()
|
||
|
}
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func (l *InstanceBackupsResponse) fixDates() *InstanceBackupsResponse {
|
||
|
for i := range l.Automatic {
|
||
|
l.Automatic[i].fixDates()
|
||
|
}
|
||
|
if l.Snapshot != nil {
|
||
|
l.Snapshot.fixDates()
|
||
|
}
|
||
|
return l
|
||
|
}
|