open-nomad/vendor/github.com/packethost/packngo/devices.go
Seth Hoenig 435c0d9fc8 deps: Switch to Go modules for dependency management
This PR switches the Nomad repository from using govendor to Go modules
for managing dependencies. Aspects of the Nomad workflow remain pretty
much the same. The usual Makefile targets should continue to work as
they always did. The API submodule simply defers to the parent Nomad
version on the repository, keeping the semantics of API versioning that
currently exists.
2020-06-02 14:30:36 -05:00

258 lines
9.2 KiB
Go

package packngo
import (
"fmt"
"strings"
)
const deviceBasePath = "/devices"
// DeviceService interface defines available device methods
type DeviceService interface {
List(ProjectID string, listOpt *ListOptions) ([]Device, *Response, error)
Get(string) (*Device, *Response, error)
GetExtra(deviceID string, includes, excludes []string) (*Device, *Response, error)
Create(*DeviceCreateRequest) (*Device, *Response, error)
Update(string, *DeviceUpdateRequest) (*Device, *Response, error)
Delete(string) (*Response, error)
Reboot(string) (*Response, error)
PowerOff(string) (*Response, error)
PowerOn(string) (*Response, error)
Lock(string) (*Response, error)
Unlock(string) (*Response, error)
}
type devicesRoot struct {
Devices []Device `json:"devices"`
Meta meta `json:"meta"`
}
// Device represents a Packet device
type Device struct {
ID string `json:"id"`
Href string `json:"href,omitempty"`
Hostname string `json:"hostname,omitempty"`
State string `json:"state,omitempty"`
Created string `json:"created_at,omitempty"`
Updated string `json:"updated_at,omitempty"`
Locked bool `json:"locked,omitempty"`
BillingCycle string `json:"billing_cycle,omitempty"`
Storage map[string]interface{} `json:"storage,omitempty"`
Tags []string `json:"tags,omitempty"`
Network []*IPAddressAssignment `json:"ip_addresses"`
Volumes []*Volume `json:"volumes"`
OS *OS `json:"operating_system,omitempty"`
Plan *Plan `json:"plan,omitempty"`
Facility *Facility `json:"facility,omitempty"`
Project *Project `json:"project,omitempty"`
ProvisionEvents []*ProvisionEvent `json:"provisioning_events,omitempty"`
ProvisionPer float32 `json:"provisioning_percentage,omitempty"`
UserData string `json:"userdata,omitempty"`
RootPassword string `json:"root_password,omitempty"`
IPXEScriptURL string `json:"ipxe_script_url,omitempty"`
AlwaysPXE bool `json:"always_pxe,omitempty"`
HardwareReservation Href `json:"hardware_reservation,omitempty"`
SpotInstance bool `json:"spot_instance,omitempty"`
SpotPriceMax float64 `json:"spot_price_max,omitempty"`
TerminationTime *Timestamp `json:"termination_time,omitempty"`
NetworkPorts []Port `json:"network_ports,omitempty"`
CustomData map[string]interface{} `json:"customdata,omitempty"`
}
type ProvisionEvent struct {
ID string `json:"id"`
Body string `json:"body"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Href string `json:"href"`
Interpolated string `json:"interpolated"`
Relationships []Href `json:"relationships"`
State string `json:"state"`
Type string `json:"type"`
}
func (d Device) String() string {
return Stringify(d)
}
// DeviceCreateRequest type used to create a Packet device
type DeviceCreateRequest struct {
Hostname string `json:"hostname"`
Plan string `json:"plan"`
Facility string `json:"facility"`
OS string `json:"operating_system"`
BillingCycle string `json:"billing_cycle"`
ProjectID string `json:"project_id"`
UserData string `json:"userdata"`
Storage string `json:"storage,omitempty"`
Tags []string `json:"tags"`
IPXEScriptURL string `json:"ipxe_script_url,omitempty"`
PublicIPv4SubnetSize int `json:"public_ipv4_subnet_size,omitempty"`
AlwaysPXE bool `json:"always_pxe,omitempty"`
HardwareReservationID string `json:"hardware_reservation_id,omitempty"`
SpotInstance bool `json:"spot_instance,omitempty"`
SpotPriceMax float64 `json:"spot_price_max,omitempty,string"`
TerminationTime *Timestamp `json:"termination_time,omitempty"`
CustomData string `json:"customdata,omitempty"`
}
// DeviceUpdateRequest type used to update a Packet device
type DeviceUpdateRequest struct {
Hostname *string `json:"hostname,omitempty"`
Description *string `json:"description,omitempty"`
UserData *string `json:"userdata,omitempty"`
Locked *bool `json:"locked,omitempty"`
Tags *[]string `json:"tags,omitempty"`
AlwaysPXE *bool `json:"always_pxe,omitempty"`
IPXEScriptURL *string `json:"ipxe_script_url,omitempty"`
CustomData *string `json:"customdata,omitempty"`
}
func (d DeviceCreateRequest) String() string {
return Stringify(d)
}
// DeviceActionRequest type used to execute actions on devices
type DeviceActionRequest struct {
Type string `json:"type"`
}
func (d DeviceActionRequest) String() string {
return Stringify(d)
}
// DeviceServiceOp implements DeviceService
type DeviceServiceOp struct {
client *Client
}
// List returns devices on a project
func (s *DeviceServiceOp) List(projectID string, listOpt *ListOptions) (devices []Device, resp *Response, err error) {
params := "include=facility"
if listOpt != nil {
params = listOpt.createURL()
}
path := fmt.Sprintf("%s/%s%s?%s", projectBasePath, projectID, deviceBasePath, params)
for {
subset := new(devicesRoot)
resp, err = s.client.DoRequest("GET", path, nil, subset)
if err != nil {
return nil, resp, err
}
devices = append(devices, subset.Devices...)
if subset.Meta.Next != nil && (listOpt == nil || listOpt.Page == 0) {
path = subset.Meta.Next.Href
if params != "" {
path = fmt.Sprintf("%s&%s", path, params)
}
continue
}
return
}
}
// Get returns a device by id
func (s *DeviceServiceOp) Get(deviceID string) (*Device, *Response, error) {
return s.GetExtra(deviceID, []string{"facility"}, nil)
}
// GetExtra returns a device by id. Specifying either includes/excludes provides more or less desired
// detailed information about resources which would otherwise be represented with an href link
func (s *DeviceServiceOp) GetExtra(deviceID string, includes, excludes []string) (*Device, *Response, error) {
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
if includes != nil {
path += fmt.Sprintf("?include=%s", strings.Join(includes, ","))
} else if excludes != nil {
path += fmt.Sprintf("?exclude=%s", strings.Join(excludes, ","))
}
device := new(Device)
resp, err := s.client.DoRequest("GET", path, nil, device)
if err != nil {
return nil, resp, err
}
return device, resp, err
}
// Create creates a new device
func (s *DeviceServiceOp) Create(createRequest *DeviceCreateRequest) (*Device, *Response, error) {
path := fmt.Sprintf("%s/%s%s", projectBasePath, createRequest.ProjectID, deviceBasePath)
device := new(Device)
resp, err := s.client.DoRequest("POST", path, createRequest, device)
if err != nil {
return nil, resp, err
}
return device, resp, err
}
// Update updates an existing device
func (s *DeviceServiceOp) Update(deviceID string, updateRequest *DeviceUpdateRequest) (*Device, *Response, error) {
path := fmt.Sprintf("%s/%s?include=facility", deviceBasePath, deviceID)
device := new(Device)
resp, err := s.client.DoRequest("PUT", path, updateRequest, device)
if err != nil {
return nil, resp, err
}
return device, resp, err
}
// Delete deletes a device
func (s *DeviceServiceOp) Delete(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
return s.client.DoRequest("DELETE", path, nil, nil)
}
// Reboot reboots on a device
func (s *DeviceServiceOp) Reboot(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
action := &DeviceActionRequest{Type: "reboot"}
return s.client.DoRequest("POST", path, action, nil)
}
// PowerOff powers on a device
func (s *DeviceServiceOp) PowerOff(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
action := &DeviceActionRequest{Type: "power_off"}
return s.client.DoRequest("POST", path, action, nil)
}
// PowerOn powers on a device
func (s *DeviceServiceOp) PowerOn(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s/actions", deviceBasePath, deviceID)
action := &DeviceActionRequest{Type: "power_on"}
return s.client.DoRequest("POST", path, action, nil)
}
type lockType struct {
Locked bool `json:"locked"`
}
// Lock sets a device to "locked"
func (s *DeviceServiceOp) Lock(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
action := lockType{Locked: true}
return s.client.DoRequest("PATCH", path, action, nil)
}
// Unlock sets a device to "unlocked"
func (s *DeviceServiceOp) Unlock(deviceID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", deviceBasePath, deviceID)
action := lockType{Locked: false}
return s.client.DoRequest("PATCH", path, action, nil)
}