2019-04-15 20:42:02 -04:00
|
|
|
package linodego
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
2020-06-12 05:36:54 -04:00
|
|
|
|
|
|
|
"github.com/linode/linodego/internal/parseabletime"
|
2019-04-15 20:42:02 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2020-06-12 05:36:54 -04:00
|
|
|
// UnmarshalJSON implements the json.Unmarshaler interface
|
|
|
|
func (i *InstanceSnapshot) UnmarshalJSON(b []byte) error {
|
|
|
|
type Mask InstanceSnapshot
|
|
|
|
|
|
|
|
p := struct {
|
|
|
|
*Mask
|
|
|
|
Created *parseabletime.ParseableTime `json:"created"`
|
|
|
|
Updated *parseabletime.ParseableTime `json:"updated"`
|
|
|
|
Finished *parseabletime.ParseableTime `json:"finished"`
|
|
|
|
}{
|
|
|
|
Mask: (*Mask)(i),
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := json.Unmarshal(b, &p); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
i.Created = (*time.Time)(p.Created)
|
|
|
|
i.Updated = (*time.Time)(p.Updated)
|
|
|
|
i.Finished = (*time.Time)(p.Finished)
|
|
|
|
|
|
|
|
return nil
|
2019-04-15 20:42:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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))
|
2020-06-12 05:36:54 -04:00
|
|
|
|
2019-04-15 20:42:02 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-06-12 05:36:54 -04:00
|
|
|
return r.Result().(*InstanceSnapshot), nil
|
2019-04-15 20:42:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
2020-06-12 05:36:54 -04:00
|
|
|
|
2019-04-15 20:42:02 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
r, err := coupleAPIErrors(c.R(ctx).
|
|
|
|
SetBody(body).
|
|
|
|
SetResult(&InstanceSnapshot{}).
|
|
|
|
Post(e))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-06-12 05:36:54 -04:00
|
|
|
return r.Result().(*InstanceSnapshot), nil
|
2019-04-15 20:42:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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))
|
2020-06-12 05:36:54 -04:00
|
|
|
|
2019-04-15 20:42:02 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-06-12 05:36:54 -04:00
|
|
|
return r.Result().(*InstanceBackupsResponse), nil
|
2019-04-15 20:42:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|