1package godo 2 3import ( 4 "context" 5 "fmt" 6 "net/http" 7) 8 9const snapshotBasePath = "v2/snapshots" 10 11// SnapshotsService is an interface for interfacing with the snapshots 12// endpoints of the DigitalOcean API 13// See: https://developers.digitalocean.com/documentation/v2#snapshots 14type SnapshotsService interface { 15 List(context.Context, *ListOptions) ([]Snapshot, *Response, error) 16 ListVolume(context.Context, *ListOptions) ([]Snapshot, *Response, error) 17 ListDroplet(context.Context, *ListOptions) ([]Snapshot, *Response, error) 18 Get(context.Context, string) (*Snapshot, *Response, error) 19 Delete(context.Context, string) (*Response, error) 20} 21 22// SnapshotsServiceOp handles communication with the snapshot related methods of the 23// DigitalOcean API. 24type SnapshotsServiceOp struct { 25 client *Client 26} 27 28var _ SnapshotsService = &SnapshotsServiceOp{} 29 30// Snapshot represents a DigitalOcean Snapshot 31type Snapshot struct { 32 ID string `json:"id,omitempty"` 33 Name string `json:"name,omitempty"` 34 ResourceID string `json:"resource_id,omitempty"` 35 ResourceType string `json:"resource_type,omitempty"` 36 Regions []string `json:"regions,omitempty"` 37 MinDiskSize int `json:"min_disk_size,omitempty"` 38 SizeGigaBytes float64 `json:"size_gigabytes,omitempty"` 39 Created string `json:"created_at,omitempty"` 40} 41 42type snapshotRoot struct { 43 Snapshot *Snapshot `json:"snapshot"` 44} 45 46type snapshotsRoot struct { 47 Snapshots []Snapshot `json:"snapshots"` 48 Links *Links `json:"links,omitempty"` 49} 50 51type listSnapshotOptions struct { 52 ResourceType string `url:"resource_type,omitempty"` 53} 54 55func (s Snapshot) String() string { 56 return Stringify(s) 57} 58 59// List lists all the snapshots available. 60func (s *SnapshotsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { 61 return s.list(ctx, opt, nil) 62} 63 64// ListDroplet lists all the Droplet snapshots. 65func (s *SnapshotsServiceOp) ListDroplet(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { 66 listOpt := listSnapshotOptions{ResourceType: "droplet"} 67 return s.list(ctx, opt, &listOpt) 68} 69 70// ListVolume lists all the volume snapshots. 71func (s *SnapshotsServiceOp) ListVolume(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { 72 listOpt := listSnapshotOptions{ResourceType: "volume"} 73 return s.list(ctx, opt, &listOpt) 74} 75 76// Get retrieves an snapshot by id. 77func (s *SnapshotsServiceOp) Get(ctx context.Context, snapshotID string) (*Snapshot, *Response, error) { 78 return s.get(ctx, snapshotID) 79} 80 81// Delete an snapshot. 82func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Response, error) { 83 path := fmt.Sprintf("%s/%s", snapshotBasePath, snapshotID) 84 85 req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil) 86 if err != nil { 87 return nil, err 88 } 89 90 resp, err := s.client.Do(ctx, req, nil) 91 92 return resp, err 93} 94 95// Helper method for getting an individual snapshot 96func (s *SnapshotsServiceOp) get(ctx context.Context, ID string) (*Snapshot, *Response, error) { 97 path := fmt.Sprintf("%s/%s", snapshotBasePath, ID) 98 99 req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) 100 if err != nil { 101 return nil, nil, err 102 } 103 104 root := new(snapshotRoot) 105 resp, err := s.client.Do(ctx, req, root) 106 if err != nil { 107 return nil, resp, err 108 } 109 110 return root.Snapshot, resp, err 111} 112 113// Helper method for listing snapshots 114func (s *SnapshotsServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listSnapshotOptions) ([]Snapshot, *Response, error) { 115 path := snapshotBasePath 116 path, err := addOptions(path, opt) 117 if err != nil { 118 return nil, nil, err 119 } 120 path, err = addOptions(path, listOpt) 121 if err != nil { 122 return nil, nil, err 123 } 124 125 req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil) 126 if err != nil { 127 return nil, nil, err 128 } 129 130 root := new(snapshotsRoot) 131 resp, err := s.client.Do(ctx, req, root) 132 if err != nil { 133 return nil, resp, err 134 } 135 if l := root.Links; l != nil { 136 resp.Links = l 137 } 138 139 return root.Snapshots, resp, err 140} 141