add volume

This commit is contained in:
Ayu Demura 2016-07-21 15:57:49 -04:00
parent 3481d1bf6e
commit 3099fc7b1c
18 changed files with 802 additions and 72 deletions

View File

@ -21,6 +21,7 @@ func Provider() terraform.ResourceProvider {
"packet_device": resourcePacketDevice(), "packet_device": resourcePacketDevice(),
"packet_ssh_key": resourcePacketSSHKey(), "packet_ssh_key": resourcePacketSSHKey(),
"packet_project": resourcePacketProject(), "packet_project": resourcePacketProject(),
"packet_volume": resourcePacketVolume(),
}, },
ConfigureFunc: providerConfigure, ConfigureFunc: providerConfigure,

View File

@ -208,13 +208,13 @@ func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
network := map[string]interface{}{ network := map[string]interface{}{
"address": ip.Address, "address": ip.Address,
"gateway": ip.Gateway, "gateway": ip.Gateway,
"family": ip.Family, "family": ip.AddressFamily,
"cidr": ip.Cidr, "cidr": ip.Cidr,
"public": ip.Public, "public": ip.Public,
} }
networks = append(networks, network) networks = append(networks, network)
if ip.Family == 4 && ip.Public == true { if ip.AddressFamily == 4 && ip.Public == true {
host = ip.Address host = ip.Address
} }
} }

View File

@ -0,0 +1,225 @@
package packet
import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"github.com/packethost/packngo"
)
func resourcePacketVolume() *schema.Resource {
return &schema.Resource{
Create: resourcePacketVolumeCreate,
Read: resourcePacketVolumeRead,
Update: resourcePacketVolumeUpdate,
Delete: resourcePacketVolumeDelete,
Schema: map[string]*schema.Schema{
"project_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"description": &schema.Schema{
Type: schema.TypeString,
Required: false,
Optional: true,
},
"size": &schema.Schema{
Type: schema.TypeInt,
Required: false,
Optional: true,
Computed: true,
},
"facility": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"plan": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"billing_cycle": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"state": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"locked": &schema.Schema{
Type: schema.TypeBool,
Computed: true,
},
"snapshot_policies": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"snapshot_frequency": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"snapshot_count": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
},
},
},
"attachments": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"href": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
},
},
"created": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"updated": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourcePacketVolumeCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*packngo.Client)
createRequest := &packngo.VolumeCreateRequest{
PlanID: d.Get("plan").(string),
FacilityID: d.Get("facility").(string),
BillingCycle: d.Get("billing_cycle").(string),
ProjectID: d.Get("project_id").(string),
}
if attr, ok := d.GetOk("description"); ok {
createRequest.Description = attr.(string)
}
if attr, ok := d.GetOk("size"); ok {
createRequest.Size = attr.(int)
}
snapshot_policies := d.Get("snapshot_policies.#").(int)
if snapshot_policies > 0 {
createRequest.SnapshotPolicies = make([]*packngo.SnapshotPolicy, 0, snapshot_policies)
for i := 0; i < snapshot_policies; i++ {
key := fmt.Sprintf("snapshot_policies.%d", i)
createRequest.SnapshotPolicies = append(createRequest.SnapshotPolicies, d.Get(key).(*packngo.SnapshotPolicy))
}
}
newVolume, _, err := client.Volumes.Create(createRequest)
if err != nil {
return friendlyError(err)
}
d.SetId(newVolume.ID)
return resourcePacketVolumeRead(d, meta)
}
func resourcePacketVolumeRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*packngo.Client)
device, _, err := client.Volumes.Get(d.Id())
if err != nil {
err = friendlyError(err)
// If the volume somehow already destroyed, mark as succesfully gone.
if isNotFound(err) {
d.SetId("")
return nil
}
return err
}
d.Set("name", device.Name)
d.Set("description", device.Description)
d.Set("size", device.Size)
d.Set("plan", device.Plan.Slug)
d.Set("facility", device.Facility.Code)
d.Set("state", device.State)
d.Set("billing_cycle", device.BillingCycle)
d.Set("locked", device.Locked)
d.Set("created", device.Created)
d.Set("updated", device.Updated)
snapshot_policies := make([]*packngo.SnapshotPolicy, 0, len(device.SnapshotPolicies))
for _, snapshot_policy := range device.SnapshotPolicies {
snapshot_policies = append(snapshot_policies, snapshot_policy)
}
d.Set("snapshot_policies", snapshot_policies)
attachments := make([]*packngo.Attachment, 0, len(device.Attachments))
for _, attachment := range device.Attachments {
attachments = append(attachments, attachment)
}
d.Set("attachments", attachments)
return nil
}
func resourcePacketVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*packngo.Client)
updateRequest := &packngo.VolumeUpdateRequest{
ID: d.Get("id").(string),
}
if attr, ok := d.GetOk("description"); ok {
updateRequest.Description = attr.(string)
}
if attr, ok := d.GetOk("plan"); ok {
updateRequest.Plan = attr.(string)
}
_, _, err := client.Volumes.Update(updateRequest)
if err != nil {
return friendlyError(err)
}
return resourcePacketVolumeRead(d, meta)
}
func resourcePacketVolumeDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*packngo.Client)
if _, err := client.Volumes.Delete(d.Id()); err != nil {
return friendlyError(err)
}
return nil
}

View File

@ -0,0 +1,86 @@
package packet
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/packethost/packngo"
)
func TestAccPacketVolume_Basic(t *testing.T) {
var volume packngo.Volume
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPacketVolumeDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPacketVolumeConfig_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckPacketVolumeExists("packet_volume.foobar", &volume),
testAccCheckPacketVolumeAttributes(&volume),
resource.TestCheckResourceAttr(
"packet_volume.foobar", "name", "foobar"),
),
},
},
})
}
func testAccCheckPacketVolumeDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*packngo.Client)
for _, rs := range s.RootModule().Resources {
if rs.Type != "packet_volume" {
continue
}
if _, _, err := client.Volumes.Get(rs.Primary.ID); err == nil {
return fmt.Errorf("Volume cstill exists")
}
}
return nil
}
func testAccCheckPacketVolumeAttributes(volume *packngo.Volume) resource.TestCheckFunc {
return func(s *terraform.State) error {
if volume.Name != "foobar" {
return fmt.Errorf("Bad name: %s", volume.Name)
}
return nil
}
}
func testAccCheckPacketVolumeExists(n string, volume *packngo.Volume) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Record ID is set")
}
client := testAccProvider.Meta().(*packngo.Client)
foundVolume, _, err := client.Volumes.Get(rs.Primary.ID)
if err != nil {
return err
}
if foundVolume.ID != rs.Primary.ID {
return fmt.Errorf("Record not found: %v - %v", rs.Primary.ID, foundVolume)
}
*volume = *foundVolume
return nil
}
}
var testAccCheckPacketVolumeConfig_basic = fmt.Sprintf(`
resource "packet_volume" "foobar" {
name = "foobar"
}`)

9
vendor/github.com/packethost/packngo/README.md generated vendored Normal file
View File

@ -0,0 +1,9 @@
# packngo
Packet Go Api Client
![](https://www.packet.net/media/labs/images/1679091c5a880faf6fb5e6087eb1b2dc/ULY7-hero.png)
Committing
----------
Before committing, it's a good idea to run `gofmt -w *.go`. ([gofmt](https://golang.org/cmd/gofmt/))

View File

@ -69,19 +69,6 @@ func (d DeviceActionRequest) String() string {
return Stringify(d) return Stringify(d)
} }
// IPAddress used to execute actions on devices
type IPAddress struct {
Family int `json:"address_family"`
Cidr int `json:"cidr"`
Address string `json:"address"`
Gateway string `json:"gateway"`
Public bool `json:"public"`
}
func (n IPAddress) String() string {
return Stringify(n)
}
// DeviceServiceOp implements DeviceService // DeviceServiceOp implements DeviceService
type DeviceServiceOp struct { type DeviceServiceOp struct {
client *Client client *Client

View File

@ -9,11 +9,12 @@ type EmailService interface {
// Email represents a user's email address // Email represents a user's email address
type Email struct { type Email struct {
ID string `json:"id"` ID string `json:"id"`
Address string `json:"address"` Address string `json:"address"`
Default bool `json:"default,omitempty"` Default bool `json:"default,omitempty"`
URL string `json:"href,omitempty"` URL string `json:"href,omitempty"`
} }
func (e Email) String() string { func (e Email) String() string {
return Stringify(e) return Stringify(e)
} }
@ -23,7 +24,7 @@ type EmailServiceOp struct {
client *Client client *Client
} }
// Get retrieves an email by id // Get retrieves an email by id
func (s *EmailServiceOp) Get(emailID string) (*Email, *Response, error) { func (s *EmailServiceOp) Get(emailID string) (*Email, *Response, error) {
req, err := s.client.NewRequest("GET", emailBasePath, nil) req, err := s.client.NewRequest("GET", emailBasePath, nil)
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package packngo package packngo
const facilityBasePath = "/facilities" const facilityBasePath = "/facilities"
@ -13,13 +13,14 @@ type facilityRoot struct {
// Facility represents a Packet facility // Facility represents a Packet facility
type Facility struct { type Facility struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Code string `json:"code,omitempty"` Code string `json:"code,omitempty"`
Features []string `json:"features,omitempty"` Features []string `json:"features,omitempty"`
Address *Address `json:"address,omitempty"` Address *Address `json:"address,omitempty"`
URL string `json:"href,omitempty"` URL string `json:"href,omitempty"`
} }
func (f Facility) String() string { func (f Facility) String() string {
return Stringify(f) return Stringify(f)
} }
@ -28,11 +29,11 @@ func (f Facility) String() string {
type Address struct { type Address struct {
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
} }
func (a Address) String() string { func (a Address) String() string {
return Stringify(a) return Stringify(a)
} }
// FacilityServiceOp implements FacilityService // FacilityServiceOp implements FacilityService
type FacilityServiceOp struct { type FacilityServiceOp struct {
client *Client client *Client

198
vendor/github.com/packethost/packngo/ip.go generated vendored Normal file
View File

@ -0,0 +1,198 @@
package packngo
import "fmt"
const ipBasePath = "/ips"
// IPService interface defines available IP methods
type IPService interface {
Assign(deviceID string, assignRequest *IPAddressAssignRequest) (*IPAddress, *Response, error)
Unassign(ipAddressID string) (*Response, error)
Get(ipAddressID string) (*IPAddress, *Response, error)
}
// IPAddress represents a ip address
type IPAddress struct {
ID string `json:"id"`
Address string `json:"address"`
Gateway string `json:"gateway"`
Network string `json:"network"`
AddressFamily int `json:"address_family"`
Netmask string `json:"netmask"`
Public bool `json:"public"`
Cidr int `json:"cidr"`
AssignedTo map[string]string `json:"assigned_to"`
Href string `json:"href"`
}
// IPAddressAssignRequest represents the body if a ip assign request
type IPAddressAssignRequest struct {
Address string `json:"address"`
}
func (i IPAddress) String() string {
return Stringify(i)
}
// IPServiceOp implements IPService
type IPServiceOp struct {
client *Client
}
// Get returns IpAddress by ID
func (i *IPServiceOp) Get(ipAddressID string) (*IPAddress, *Response, error) {
path := fmt.Sprintf("%s/%s", ipBasePath, ipAddressID)
req, err := i.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}
ip := new(IPAddress)
resp, err := i.client.Do(req, ip)
if err != nil {
return nil, resp, err
}
return ip, resp, err
}
// Unassign unassigns an IP address record. This will remove the relationship between an IP
// and the device and will make the IP address available to be assigned to another device.
func (i *IPServiceOp) Unassign(ipAddressID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", ipBasePath, ipAddressID)
req, err := i.client.NewRequest("DELETE", path, nil)
if err != nil {
return nil, err
}
resp, err := i.client.Do(req, nil)
return resp, err
}
// Assign assigns an IP address to a device. The IP address must be in one of the IP ranges assigned to the devices project.
func (i *IPServiceOp) Assign(deviceID string, assignRequest *IPAddressAssignRequest) (*IPAddress, *Response, error) {
path := fmt.Sprintf("%s/%s%s", deviceBasePath, deviceID, ipBasePath)
req, err := i.client.NewRequest("POST", path, assignRequest)
ip := new(IPAddress)
resp, err := i.client.Do(req, ip)
if err != nil {
return nil, resp, err
}
return ip, resp, err
}
// IP RESERVATIONS API
// IPReservationService interface defines available IPReservation methods
type IPReservationService interface {
List(projectID string) ([]IPReservation, *Response, error)
RequestMore(projectID string, ipReservationReq *IPReservationRequest) (*Response, error)
Get(ipReservationID string) (*IPReservation, *Response, error)
Remove(ipReservationID string) (*Response, error)
}
// IPReservationServiceOp implements the IPReservationService interface
type IPReservationServiceOp struct {
client *Client
}
// IPReservationRequest represents the body of a reservation request
type IPReservationRequest struct {
Type string `json:"type"`
Quantity int `json:"quantity"`
Comments string `json:"comments"`
}
// IPReservation represent an IP reservation for a single project
type IPReservation struct {
ID string `json:"id"`
Network string `json:"network"`
Address string `json:"address"`
AddressFamily int `json:"address_family"`
Netmask string `json:"netmask"`
Public bool `json:"public"`
Cidr int `json:"cidr"`
Management bool `json:"management"`
Manageable bool `json:"manageable"`
Addon bool `json:"addon"`
Bill bool `json:"bill"`
Assignments []map[string]string `json:"assignments"`
Href string `json:"href"`
}
type ipReservationRoot struct {
IPReservations []IPReservation `json:"ip_addresses"`
}
// List provides a list of IP resevations for a single project.
func (i *IPReservationServiceOp) List(projectID string) ([]IPReservation, *Response, error) {
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
req, err := i.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}
reservations := new(ipReservationRoot)
resp, err := i.client.Do(req, reservations)
if err != nil {
return nil, resp, err
}
return reservations.IPReservations, resp, err
}
// RequestMore requests more IP space for a project in order to have additional IP addresses to assign to devices
func (i *IPReservationServiceOp) RequestMore(projectID string, ipReservationReq *IPReservationRequest) (*Response, error) {
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
req, err := i.client.NewRequest("POST", path, &ipReservationReq)
if err != nil {
return nil, err
}
resp, err := i.client.Do(req, nil)
if err != nil {
return nil, err
}
return resp, err
}
// Get returns a single IP reservation object
func (i *IPReservationServiceOp) Get(ipReservationID string) (*IPReservation, *Response, error) {
path := fmt.Sprintf("%s/%s", ipBasePath, ipReservationID)
req, err := i.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}
reservation := new(IPReservation)
resp, err := i.client.Do(req, reservation)
if err != nil {
return nil, nil, err
}
return reservation, resp, err
}
// Remove removes an IP reservation from the project.
func (i *IPReservationServiceOp) Remove(ipReservationID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", ipBasePath, ipReservationID)
req, err := i.client.NewRequest("DELETE", path, nil)
if err != nil {
return nil, err
}
resp, err := i.client.Do(req, nil)
if err != nil {
return nil, err
}
return resp, err
}

View File

@ -18,16 +18,17 @@ type OS struct {
Distro string `json:"distro"` Distro string `json:"distro"`
Version string `json:"version"` Version string `json:"version"`
} }
func (o OS) String() string { func (o OS) String() string {
return Stringify(o) return Stringify(o)
} }
// OSServiceOp implements OSService // OSServiceOp implements OSService
type OSServiceOp struct { type OSServiceOp struct {
client *Client client *Client
} }
// List returns all available operating systems // List returns all available operating systems
func (s *OSServiceOp) List() ([]OS, *Response, error) { func (s *OSServiceOp) List() ([]OS, *Response, error) {
req, err := s.client.NewRequest("GET", osBasePath, nil) req, err := s.client.NewRequest("GET", osBasePath, nil)
if err != nil { if err != nil {

View File

@ -89,6 +89,9 @@ type Client struct {
Projects ProjectService Projects ProjectService
Facilities FacilityService Facilities FacilityService
OperatingSystems OSService OperatingSystems OSService
Ips IPService
IpReservations IPReservationService
Volumes VolumeService
} }
// NewRequest inits a new http request with the proper headers // NewRequest inits a new http request with the proper headers
@ -165,6 +168,10 @@ func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
// an older version of Go, pass in a custom http.Client with a custom TLS configuration // an older version of Go, pass in a custom http.Client with a custom TLS configuration
// that sets "InsecureSkipVerify" to "true" // that sets "InsecureSkipVerify" to "true"
func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Client { func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Client {
client, _ := NewClientWithBaseURL(consumerToken, apiKey, httpClient, baseURL)
return client
}
func NewClientWithBaseURL(consumerToken string, apiKey string, httpClient *http.Client, apiBaseURL string) (*Client, error) {
if httpClient == nil { if httpClient == nil {
// Don't fall back on http.DefaultClient as it's not nice to adjust state // Don't fall back on http.DefaultClient as it's not nice to adjust state
// implicitly. If the client wants to use http.DefaultClient, they can // implicitly. If the client wants to use http.DefaultClient, they can
@ -172,9 +179,12 @@ func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Cl
httpClient = &http.Client{} httpClient = &http.Client{}
} }
BaseURL, _ := url.Parse(baseURL) u, err := url.Parse(apiBaseURL)
if err != nil {
return nil, err
}
c := &Client{client: httpClient, BaseURL: BaseURL, UserAgent: userAgent, ConsumerToken: consumerToken, APIKey: apiKey} c := &Client{client: httpClient, BaseURL: u, UserAgent: userAgent, ConsumerToken: consumerToken, APIKey: apiKey}
c.Plans = &PlanServiceOp{client: c} c.Plans = &PlanServiceOp{client: c}
c.Users = &UserServiceOp{client: c} c.Users = &UserServiceOp{client: c}
c.Emails = &EmailServiceOp{client: c} c.Emails = &EmailServiceOp{client: c}
@ -183,8 +193,11 @@ func NewClient(consumerToken string, apiKey string, httpClient *http.Client) *Cl
c.Projects = &ProjectServiceOp{client: c} c.Projects = &ProjectServiceOp{client: c}
c.Facilities = &FacilityServiceOp{client: c} c.Facilities = &FacilityServiceOp{client: c}
c.OperatingSystems = &OSServiceOp{client: c} c.OperatingSystems = &OSServiceOp{client: c}
c.Ips = &IPServiceOp{client: c}
c.IpReservations = &IPReservationServiceOp{client: c}
c.Volumes = &VolumeServiceOp{client: c}
return c return c, nil
} }
func checkResponse(r *http.Response) error { func checkResponse(r *http.Response) error {

View File

@ -1,4 +1,4 @@
package packngo package packngo
const planBasePath = "/plans" const planBasePath = "/plans"
@ -21,18 +21,20 @@ type Plan struct {
Specs *Specs `json:"specs,omitempty"` Specs *Specs `json:"specs,omitempty"`
Pricing *Pricing `json:"pricing,omitempty"` Pricing *Pricing `json:"pricing,omitempty"`
} }
func (p Plan) String() string { func (p Plan) String() string {
return Stringify(p) return Stringify(p)
} }
// Specs - the server specs for a plan // Specs - the server specs for a plan
type Specs struct { type Specs struct {
Cpus []*Cpus `json:"cpus,omitempty"` Cpus []*Cpus `json:"cpus,omitempty"`
Memory *Memory `json:"memory,omitempty"` Memory *Memory `json:"memory,omitempty"`
Drives []*Drives `json:"drives,omitempty"` Drives []*Drives `json:"drives,omitempty"`
Nics []*Nics `json:"nics,omitempty"` Nics []*Nics `json:"nics,omitempty"`
Features *Features `json:"features,omitempty"` Features *Features `json:"features,omitempty"`
} }
func (s Specs) String() string { func (s Specs) String() string {
return Stringify(s) return Stringify(s)
} }
@ -42,6 +44,7 @@ type Cpus struct {
Count int `json:"count,omitempty"` Count int `json:"count,omitempty"`
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
} }
func (c Cpus) String() string { func (c Cpus) String() string {
return Stringify(c) return Stringify(c)
} }
@ -50,6 +53,7 @@ func (c Cpus) String() string {
type Memory struct { type Memory struct {
Total string `json:"total,omitempty"` Total string `json:"total,omitempty"`
} }
func (m Memory) String() string { func (m Memory) String() string {
return Stringify(m) return Stringify(m)
} }
@ -60,6 +64,7 @@ type Drives struct {
Size string `json:"size,omitempty"` Size string `json:"size,omitempty"`
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
} }
func (d Drives) String() string { func (d Drives) String() string {
return Stringify(d) return Stringify(d)
} }
@ -69,6 +74,7 @@ type Nics struct {
Count int `json:"count,omitempty"` Count int `json:"count,omitempty"`
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
} }
func (n Nics) String() string { func (n Nics) String() string {
return Stringify(n) return Stringify(n)
} }
@ -78,6 +84,7 @@ type Features struct {
Raid bool `json:"raid,omitempty"` Raid bool `json:"raid,omitempty"`
Txt bool `json:"txt,omitempty"` Txt bool `json:"txt,omitempty"`
} }
func (f Features) String() string { func (f Features) String() string {
return Stringify(f) return Stringify(f)
} }
@ -87,6 +94,7 @@ type Pricing struct {
Hourly float32 `json:"hourly,omitempty"` Hourly float32 `json:"hourly,omitempty"`
Monthly float32 `json:"monthly,omitempty"` Monthly float32 `json:"monthly,omitempty"`
} }
func (p Pricing) String() string { func (p Pricing) String() string {
return Stringify(p) return Stringify(p)
} }

View File

@ -11,11 +11,22 @@ type ProjectService interface {
Create(*ProjectCreateRequest) (*Project, *Response, error) Create(*ProjectCreateRequest) (*Project, *Response, error)
Update(*ProjectUpdateRequest) (*Project, *Response, error) Update(*ProjectUpdateRequest) (*Project, *Response, error)
Delete(string) (*Response, error) Delete(string) (*Response, error)
ListIPAddresses(string) ([]IPAddress, *Response, error)
ListVolumes(string) ([]Volume, *Response, error)
}
type ipsRoot struct {
IPAddresses []IPAddress `json:"ip_addresses"`
}
type volumesRoot struct {
Volumes []Volume `json:"volumes"`
} }
type projectsRoot struct { type projectsRoot struct {
Projects []Project `json:"projects"` Projects []Project `json:"projects"`
} }
// Project represents a Packet project // Project represents a Packet project
type Project struct { type Project struct {
ID string `json:"id"` ID string `json:"id"`
@ -27,6 +38,7 @@ type Project struct {
SSHKeys []SSHKey `json:"ssh_keys,omitempty"` SSHKeys []SSHKey `json:"ssh_keys,omitempty"`
URL string `json:"href,omitempty"` URL string `json:"href,omitempty"`
} }
func (p Project) String() string { func (p Project) String() string {
return Stringify(p) return Stringify(p)
} }
@ -36,6 +48,7 @@ type ProjectCreateRequest struct {
Name string `json:"name"` Name string `json:"name"`
PaymentMethod string `json:"payment_method,omitempty"` PaymentMethod string `json:"payment_method,omitempty"`
} }
func (p ProjectCreateRequest) String() string { func (p ProjectCreateRequest) String() string {
return Stringify(p) return Stringify(p)
} }
@ -46,6 +59,7 @@ type ProjectUpdateRequest struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
PaymentMethod string `json:"payment_method,omitempty"` PaymentMethod string `json:"payment_method,omitempty"`
} }
func (p ProjectUpdateRequest) String() string { func (p ProjectUpdateRequest) String() string {
return Stringify(p) return Stringify(p)
} }
@ -55,6 +69,22 @@ type ProjectServiceOp struct {
client *Client client *Client
} }
func (s *ProjectServiceOp) ListIPAddresses(projectID string) ([]IPAddress, *Response, error) {
url := fmt.Sprintf("%s/%s/ips", projectBasePath, projectID)
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
root := new(ipsRoot)
resp, err := s.client.Do(req, root)
if err != nil {
return nil, resp, err
}
return root.IPAddresses, resp, err
}
// List returns the user's projects // List returns the user's projects
func (s *ProjectServiceOp) List() ([]Project, *Response, error) { func (s *ProjectServiceOp) List() ([]Project, *Response, error) {
req, err := s.client.NewRequest("GET", projectBasePath, nil) req, err := s.client.NewRequest("GET", projectBasePath, nil)
@ -134,3 +164,20 @@ func (s *ProjectServiceOp) Delete(projectID string) (*Response, error) {
return resp, err return resp, err
} }
// List returns Volumes for a project
func (s *ProjectServiceOp) ListVolumes(projectID string) ([]Volume, *Response, error) {
url := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, volumeBasePath)
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
root := new(volumesRoot)
resp, err := s.client.Do(req, root)
if err != nil {
return nil, resp, err
}
return root.Volumes, resp, err
}

View File

@ -2,10 +2,11 @@ package packngo
// Rate provides the API request rate limit details // Rate provides the API request rate limit details
type Rate struct { type Rate struct {
RequestLimit int `json:"request_limit"` RequestLimit int `json:"request_limit"`
RequestsRemaining int `json:"requests_remaining"` RequestsRemaining int `json:"requests_remaining"`
Reset Timestamp `json:"rate_reset"` Reset Timestamp `json:"rate_reset"`
} }
func (r Rate) String() string { func (r Rate) String() string {
return Stringify(r) return Stringify(r)
} }

View File

@ -19,34 +19,37 @@ type sshKeyRoot struct {
// SSHKey represents a user's ssh key // SSHKey represents a user's ssh key
type SSHKey struct { type SSHKey struct {
ID string `json:"id"` ID string `json:"id"`
Label string `json:"label"` Label string `json:"label"`
Key string `json:"key"` Key string `json:"key"`
FingerPrint string `json:"fingerprint"` FingerPrint string `json:"fingerprint"`
Created string `json:"created_at"` Created string `json:"created_at"`
Updated string `json:"updated_at"` Updated string `json:"updated_at"`
User User `json:"user,omitempty"` User User `json:"user,omitempty"`
URL string `json:"href,omitempty"` URL string `json:"href,omitempty"`
} }
func (s SSHKey) String() string { func (s SSHKey) String() string {
return Stringify(s) return Stringify(s)
} }
// SSHKeyCreateRequest type used to create an ssh key // SSHKeyCreateRequest type used to create an ssh key
type SSHKeyCreateRequest struct { type SSHKeyCreateRequest struct {
Label string `json:"label"` Label string `json:"label"`
Key string `json:"key"` Key string `json:"key"`
} }
func (s SSHKeyCreateRequest) String() string { func (s SSHKeyCreateRequest) String() string {
return Stringify(s) return Stringify(s)
} }
// SSHKeyUpdateRequest type used to update an ssh key // SSHKeyUpdateRequest type used to update an ssh key
type SSHKeyUpdateRequest struct { type SSHKeyUpdateRequest struct {
ID string `json:"id"` ID string `json:"id"`
Label string `json:"label"` Label string `json:"label"`
Key string `json:"key"` Key string `json:"key"`
} }
func (s SSHKeyUpdateRequest) String() string { func (s SSHKeyUpdateRequest) String() string {
return Stringify(s) return Stringify(s)
} }

View File

@ -9,23 +9,24 @@ type UserService interface {
// User represents a Packet user // User represents a Packet user
type User struct { type User struct {
ID string `json:"id"` ID string `json:"id"`
FirstName string `json:"first_name,omitempty"` FirstName string `json:"first_name,omitempty"`
LastName string `json:"last_name,omitempty"` LastName string `json:"last_name,omitempty"`
FullName string `json:"full_name,omitempty"` FullName string `json:"full_name,omitempty"`
Email string `json:"email,omitempty"` Email string `json:"email,omitempty"`
TwoFactor string `json:"two_factor_auth,omitempty"` TwoFactor string `json:"two_factor_auth,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"` AvatarURL string `json:"avatar_url,omitempty"`
Facebook string `json:"twitter,omitempty"` Facebook string `json:"twitter,omitempty"`
Twitter string `json:"facebook,omitempty"` Twitter string `json:"facebook,omitempty"`
LinkedIn string `json:"linkedin,omitempty"` LinkedIn string `json:"linkedin,omitempty"`
Created string `json:"created_at,omitempty"` Created string `json:"created_at,omitempty"`
Updated string `json:"updated_at,omitempty"` Updated string `json:"updated_at,omitempty"`
TimeZone string `json:"timezone,omitempty"` TimeZone string `json:"timezone,omitempty"`
Emails []Email `json:"email,omitempty"` Emails []Email `json:"email,omitempty"`
PhoneNumber string `json:"phone_number,omitempty"` PhoneNumber string `json:"phone_number,omitempty"`
URL string `json:"href,omitempty"` URL string `json:"href,omitempty"`
} }
func (u User) String() string { func (u User) String() string {
return Stringify(u) return Stringify(u)
} }

146
vendor/github.com/packethost/packngo/volumes.go generated vendored Normal file
View File

@ -0,0 +1,146 @@
package packngo
import "fmt"
const volumeBasePath = "/storage"
// VolumeService interface defines available Volume methods
type VolumeService interface {
Get(string) (*Volume, *Response, error)
Update(*VolumeUpdateRequest) (*Volume, *Response, error)
Delete(string) (*Response, error)
Create(*VolumeCreateRequest) (*Volume, *Response, error)
}
// Volume represents a volume
type Volume struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Size int `json:"size,omitempty"`
State string `json:"state,omitempty"`
Locked bool `json:"locked,omitempty"`
BillingCycle string `json:"billing_cycle,omitempty"`
Created string `json:"created_at,omitempty"`
Updated string `json:"updated_at,omitempty"`
Href string `json:"href,omitempty"`
SnapshotPolicies []*SnapshotPolicy `json:"snapshot_policies,omitempty"`
Attachments []*Attachment `json:"attachments,omitempty"`
Plan *Plan `json:"plan,omitempty"`
Facility *Facility `json:"facility,omitempty"`
Project *Project `json:"project,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"`
snapshot_count int `json:"snapshot_count,omitempty"`
}
// Attachment used to execute actions on volume
type Attachment struct {
ID string `json:"id"`
Href string `json:"href"`
}
func (v Volume) String() string {
return Stringify(v)
}
// VolumeCreateRequest type used to create a Packet volume
type VolumeCreateRequest struct {
Size int `json:"size"`
BillingCycle string `json:"billing_cycle"`
ProjectID string `json:"project_id"`
PlanID string `json:"plan_id"`
FacilityID string `json:"facility_id"`
Description string `json:"Description,omitempty"`
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 {
ID string `json:"id"`
Description string `json:"description,omitempty"`
Plan string `json:"plan,omitempty"`
}
func (v VolumeUpdateRequest) String() string {
return Stringify(v)
}
// VolumeServiceOp implements VolumeService
type VolumeServiceOp struct {
client *Client
}
// Get returns a volume by id
func (v *VolumeServiceOp) Get(volumeID string) (*Volume, *Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, volumeID)
req, err := v.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}
volume := new(Volume)
resp, err := v.client.Do(req, volume)
if err != nil {
return nil, resp, err
}
return volume, resp, err
}
// Update updates a volume
func (v *VolumeServiceOp) Update(updateRequest *VolumeUpdateRequest) (*Volume, *Response, error) {
path := fmt.Sprintf("%s/%s", volumeBasePath, updateRequest.ID)
req, err := v.client.NewRequest("PATCH", path, updateRequest)
if err != nil {
return nil, nil, err
}
volume := new(Volume)
resp, err := v.client.Do(req, 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)
req, err := v.client.NewRequest("DELETE", path, nil)
if err != nil {
return nil, err
}
resp, err := v.client.Do(req, nil)
return resp, err
}
// Create creates a new volume for a project
func (v *VolumeServiceOp) Create(createRequest *VolumeCreateRequest) (*Volume, *Response, error) {
url := fmt.Sprintf("%s/%s%s", projectBasePath, createRequest.ProjectID, volumeBasePath)
req, err := v.client.NewRequest("POST", url, createRequest)
if err != nil {
return nil, nil, err
}
volume := new(Volume)
resp, err := v.client.Do(req, volume)
if err != nil {
return nil, resp, err
}
return volume, resp, err
}

4
vendor/vendor.json vendored
View File

@ -1464,8 +1464,10 @@
"revision": "3d184cea22ee1c41ec1697e0d830ff0c78f7ea97" "revision": "3d184cea22ee1c41ec1697e0d830ff0c78f7ea97"
}, },
{ {
"checksumSHA1": "yHIFvxXMD3q3ZvQZFLw+EJBhTq8=",
"path": "github.com/packethost/packngo", "path": "github.com/packethost/packngo",
"revision": "f03d7dc788a8b57b62d301ccb98c950c325756f8" "revision": "a596b01fbf1afdf90188ec02aa61fe7cc9703945",
"revisionTime": "2016-07-21T21:43:59Z"
}, },
{ {
"path": "github.com/pborman/uuid", "path": "github.com/pborman/uuid",