open-vault/vendor/github.com/packethost/packngo/volumes.go

240 lines
7.3 KiB
Go

package packngo
import "fmt"
const (
volumeBasePath = "/storage"
attachmentsBasePath = "/attachments"
)
// VolumeService interface defines available Volume methods
type VolumeService interface {
List(string, *ListOptions) ([]Volume, *Response, error)
Get(string) (*Volume, *Response, error)
Update(string, *VolumeUpdateRequest) (*Volume, *Response, error)
Delete(string) (*Response, error)
Create(*VolumeCreateRequest, string) (*Volume, *Response, error)
Lock(string) (*Response, error)
Unlock(string) (*Response, error)
}
// VolumeAttachmentService defines attachment methdods
type VolumeAttachmentService interface {
Get(string) (*VolumeAttachment, *Response, error)
Create(string, string) (*VolumeAttachment, *Response, error)
Delete(string) (*Response, error)
}
type volumesRoot struct {
Volumes []Volume `json:"volumes"`
Meta meta `json:"meta"`
}
// Volume represents a volume
type Volume struct {
Attachments []*VolumeAttachment `json:"attachments,omitempty"`
BillingCycle string `json:"billing_cycle,omitempty"`
Created string `json:"created_at,omitempty"`
Description string `json:"description,omitempty"`
Facility *Facility `json:"facility,omitempty"`
Href string `json:"href,omitempty"`
ID string `json:"id"`
Locked bool `json:"locked,omitempty"`
Name string `json:"name,omitempty"`
Plan *Plan `json:"plan,omitempty"`
Project *Project `json:"project,omitempty"`
Size int `json:"size,omitempty"`
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
State string `json:"state,omitempty"`
Updated string `json:"updated_at,omitempty"`
}
// SnapshotPolicy used to execute actions on volume
type SnapshotPolicy struct {
ID string `json:"id"`
Href string `json:"href"`
SnapshotFrequency string `json:"snapshot_frequency,omitempty"`
SnapshotCount int `json:"snapshot_count,omitempty"`
}
func (v Volume) String() string {
return Stringify(v)
}
// VolumeCreateRequest type used to create a Packet volume
type VolumeCreateRequest struct {
BillingCycle string `json:"billing_cycle"`
Description string `json:"description,omitempty"`
Locked bool `json:"locked,omitempty"`
Size int `json:"size"`
PlanID string `json:"plan_id"`
FacilityID string `json:"facility_id"`
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
}
func (v VolumeCreateRequest) String() string {
return Stringify(v)
}
// VolumeUpdateRequest type used to update a Packet volume
type VolumeUpdateRequest struct {
Description *string `json:"description,omitempty"`
PlanID *string `json:"plan_id,omitempty"`
Size *int `json:"size,omitempty"`
BillingCycle *string `json:"billing_cycle,omitempty"`
}
// VolumeAttachment is a type from Packet API
type VolumeAttachment struct {
Href string `json:"href"`
ID string `json:"id"`
Volume Volume `json:"volume"`
Device Device `json:"device"`
}
func (v VolumeUpdateRequest) String() string {
return Stringify(v)
}
// VolumeAttachmentServiceOp implements VolumeService
type VolumeAttachmentServiceOp struct {
client *Client
}
// VolumeServiceOp implements VolumeService
type VolumeServiceOp struct {
client *Client
}
// List returns the volumes for a project
func (v *VolumeServiceOp) List(projectID string, listOpt *ListOptions) (volumes []Volume, resp *Response, err error) {
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
var params string
if listOpt != nil {
params = listOpt.createURL()
if params != "" {
url = fmt.Sprintf("%s?%s", url, params)
}
}
for {
subset := new(volumesRoot)
resp, err = v.client.DoRequest("GET", url, nil, subset)
if err != nil {
return nil, resp, err
}
volumes = append(volumes, subset.Volumes...)
if subset.Meta.Next != nil && (listOpt == nil || listOpt.Page == 0) {
url = subset.Meta.Next.Href
if params != "" {
url = fmt.Sprintf("%s&%s", url, params)
}
continue
}
return
}
}
// Get returns a volume by id
func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
path := fmt.Sprintf("%s/%s?include=facility,snapshot_policies,attachments.device", volumeBasePath, volumeID)
volume := new(Volume)
resp, err := v.client.DoRequest("GET", path, nil, volume)
if err != nil {
return nil, resp, err
}
return volume, resp, err
}
// Update updates a volume
func (v *VolumeServiceOp) Update(id string, updateRequest *VolumeUpdateRequest) (*Volume, *Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, id)
volume := new(Volume)
resp, err := v.client.DoRequest("PATCH", path, updateRequest, volume)
if err != nil {
return nil, resp, err
}
return volume, resp, err
}
// Delete deletes a volume
func (v *VolumeServiceOp) Delete(volumeID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, volumeID)
return v.client.DoRequest("DELETE", path, nil, nil)
}
// Create creates a new volume for a project
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest, projectID string) (*Volume, *Response, error) {
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
volume := new(Volume)
resp, err := v.client.DoRequest("POST", url, createRequest, volume)
if err != nil {
return nil, resp, err
}
return volume, resp, err
}
// Attachments
// Create Attachment, i.e. attach volume to a device
func (v *VolumeAttachmentServiceOp) Create(volumeID, deviceID string) (*VolumeAttachment, *Response, error) {
url := fmt.Sprintf("%s/%s%s", volumeBasePath, volumeID, attachmentsBasePath)
volAttachParam := map[string]string{
"device_id": deviceID,
}
volumeAttachment := new(VolumeAttachment)
resp, err := v.client.DoRequest("POST", url, volAttachParam, volumeAttachment)
if err != nil {
return nil, resp, err
}
return volumeAttachment, resp, nil
}
// Get gets attachment by id
func (v *VolumeAttachmentServiceOp) Get(attachmentID string) (*VolumeAttachment, *Response, error) {
path := fmt.Sprintf("%s%s/%s", volumeBasePath, attachmentsBasePath, attachmentID)
volumeAttachment := new(VolumeAttachment)
resp, err := v.client.DoRequest("GET", path, nil, volumeAttachment)
if err != nil {
return nil, resp, err
}
return volumeAttachment, resp, nil
}
// Delete deletes attachment by id
func (v *VolumeAttachmentServiceOp) Delete(attachmentID string) (*Response, error) {
path := fmt.Sprintf("%s%s/%s", volumeBasePath, attachmentsBasePath, attachmentID)
return v.client.DoRequest("DELETE", path, nil, nil)
}
// Lock sets a volume to "locked"
func (s *VolumeServiceOp) Lock(id string) (*Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, id)
action := lockType{Locked: true}
return s.client.DoRequest("PATCH", path, action, nil)
}
// Unlock sets a volume to "unlocked"
func (s *VolumeServiceOp) Unlock(id string) (*Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, id)
action := lockType{Locked: false}
return s.client.DoRequest("PATCH", path, action, nil)
}