Add missing APIs to Images service.
The following were added: * Images.ListDistribution() for GET /v2/images?type=distribution * Images.ListApplication() for GET /v2/images?type=application * Images.ListUser() for GET /v2/images?private=true * Images.GetByID() for GET /v2/images/12345 * Images.GetBySlug() for GET /v2/images/ubuntu * Images.Update() for PUT /v2/images/12345 * Images.Delete() for DELETE /v2/images/12345
This commit is contained in:
parent
8dc1f54d1a
commit
fc8ecd5bc6
|
@ -218,10 +218,12 @@ func TestDroplet_String(t *testing.T) {
|
|||
image := &Image{
|
||||
ID: 1,
|
||||
Name: "Image",
|
||||
Type: "snapshot",
|
||||
Distribution: "Ubuntu",
|
||||
Slug: "image",
|
||||
Public: true,
|
||||
Regions: []string{"one", "two"},
|
||||
MinDiskSize: 20,
|
||||
}
|
||||
|
||||
size := &Size{
|
||||
|
@ -257,7 +259,7 @@ func TestDroplet_String(t *testing.T) {
|
|||
}
|
||||
|
||||
stringified := droplet.String()
|
||||
expected := `godo.Droplet{ID:1, Name:"droplet", Memory:123, Vcpus:456, Disk:789, Region:godo.Region{Slug:"region", Name:"Region", Sizes:["1" "2"], Available:true}, Image:godo.Image{ID:1, Name:"Image", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"]}, Size:godo.Size{Slug:"size", Memory:0, Vcpus:0, Disk:0, PriceMonthly:123, PriceHourly:456, Regions:["1" "2"]}, BackupIDs:[1], SnapshotIDs:[1], Locked:false, Status:"active", Networks:godo.Networks{V4:[godo.NetworkV4{IPAddress:"192.168.1.2", Netmask:"255.255.255.0", Gateway:"192.168.1.1", Type:""}]}, ActionIDs:[1], Created:""}`
|
||||
expected := `godo.Droplet{ID:1, Name:"droplet", Memory:123, Vcpus:456, Disk:789, Region:godo.Region{Slug:"region", Name:"Region", Sizes:["1" "2"], Available:true}, Image:godo.Image{ID:1, Name:"Image", Type:"snapshot", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"], MinDiskSize:20}, Size:godo.Size{Slug:"size", Memory:0, Vcpus:0, Disk:0, PriceMonthly:123, PriceHourly:456, Regions:["1" "2"]}, BackupIDs:[1], SnapshotIDs:[1], Locked:false, Status:"active", Networks:godo.Networks{V4:[godo.NetworkV4{IPAddress:"192.168.1.2", Netmask:"255.255.255.0", Gateway:"192.168.1.1", Type:""}]}, ActionIDs:[1], Created:""}`
|
||||
if expected != stringified {
|
||||
t.Errorf("Droplet.String returned %+v, expected %+v", stringified, expected)
|
||||
}
|
||||
|
|
113
images.go
113
images.go
|
@ -1,10 +1,21 @@
|
|||
package godo
|
||||
|
||||
import "fmt"
|
||||
|
||||
const imageBasePath = "v2/images"
|
||||
|
||||
// ImagesService is an interface for interfacing with the images
|
||||
// endpoints of the Digital Ocean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#images
|
||||
type ImagesService interface {
|
||||
List(*ListOptions) ([]Image, *Response, error)
|
||||
ListDistribution(opt *ListOptions) ([]Image, *Response, error)
|
||||
ListApplication(opt *ListOptions) ([]Image, *Response, error)
|
||||
ListUser(opt *ListOptions) ([]Image, *Response, error)
|
||||
GetByID(int) (*Image, *Response, error)
|
||||
GetBySlug(string) (*Image, *Response, error)
|
||||
Update(int, *ImageUpdateRequest) (*Image, *Response, error)
|
||||
Delete(int) (*Response, error)
|
||||
}
|
||||
|
||||
// ImagesServiceOp handles communication with the image related methods of the
|
||||
|
@ -19,10 +30,17 @@ var _ ImagesService = &ImagesServiceOp{}
|
|||
type Image struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Distribution string `json:"distribution,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Public bool `json:"public,omitempty"`
|
||||
Regions []string `json:"regions,omitempty"`
|
||||
MinDiskSize int `json:"min_disk_size,omitempty"`
|
||||
}
|
||||
|
||||
// ImageUpdateRequest represents a request to update an image.
|
||||
type ImageUpdateRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type imageRoot struct {
|
||||
|
@ -34,17 +52,108 @@ type imagesRoot struct {
|
|||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type listImageOptions struct {
|
||||
Private bool `url:"private,omitempty"`
|
||||
Type string `url:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (i Image) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// List all sizes
|
||||
// List all images
|
||||
func (s *ImagesServiceOp) List(opt *ListOptions) ([]Image, *Response, error) {
|
||||
path := "v2/images"
|
||||
return s.list(opt, nil)
|
||||
}
|
||||
|
||||
// List distribution images
|
||||
func (s *ImagesServiceOp) ListDistribution(opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Type: "distribution"}
|
||||
return s.list(opt, &listOpt)
|
||||
}
|
||||
|
||||
// List application images
|
||||
func (s *ImagesServiceOp) ListApplication(opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Type: "application"}
|
||||
return s.list(opt, &listOpt)
|
||||
}
|
||||
|
||||
// List user images
|
||||
func (s *ImagesServiceOp) ListUser(opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Private: true}
|
||||
return s.list(opt, &listOpt)
|
||||
}
|
||||
|
||||
// Get individual image by id
|
||||
func (s *ImagesServiceOp) GetByID(imageID int) (*Image, *Response, error) {
|
||||
return s.get(interface{}(imageID))
|
||||
}
|
||||
|
||||
// Get individual image by slug
|
||||
func (s *ImagesServiceOp) GetBySlug(slug string) (*Image, *Response, error) {
|
||||
return s.get(interface{}(slug))
|
||||
}
|
||||
|
||||
// Update an image name
|
||||
func (s *ImagesServiceOp) Update(imageID int, updateRequest *ImageUpdateRequest) (*Image, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%d", imageBasePath, imageID)
|
||||
req, err := s.client.NewRequest("PUT", path, updateRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(imageRoot)
|
||||
resp, err := s.client.Do(req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &root.Image, resp, err
|
||||
}
|
||||
|
||||
// Delete image
|
||||
func (s *ImagesServiceOp) Delete(imageID int) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%d", imageBasePath, imageID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Helper method for getting an individual image
|
||||
func (s *ImagesServiceOp) get(ID interface{}) (*Image, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%v", imageBasePath, ID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(imageRoot)
|
||||
resp, err := s.client.Do(req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &root.Image, resp, err
|
||||
}
|
||||
|
||||
// Helper method for listing images
|
||||
func (s *ImagesServiceOp) list(opt *ListOptions, listOpt *listImageOptions) ([]Image, *Response, error) {
|
||||
path := imageBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
path, err = addOptions(path, listOpt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
|
|
171
images_test.go
171
images_test.go
|
@ -1,6 +1,7 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
@ -27,6 +28,82 @@ func TestImages_List(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestImages_ListDistribution(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "GET")
|
||||
expected := "distribution"
|
||||
actual := r.URL.Query().Get("type")
|
||||
if actual != expected {
|
||||
t.Errorf("'type' query = %v, expected %v", actual, expected)
|
||||
}
|
||||
fmt.Fprint(w, `{"images":[{"id":1},{"id":2}]}`)
|
||||
})
|
||||
|
||||
images, _, err := client.Images.ListDistribution(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Images.ListDistribution returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := []Image{{ID: 1}, {ID: 2}}
|
||||
if !reflect.DeepEqual(images, expected) {
|
||||
t.Errorf("Images.ListDistribution returned %+v, expected %+v", images, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_ListApplication(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "GET")
|
||||
expected := "application"
|
||||
actual := r.URL.Query().Get("type")
|
||||
if actual != expected {
|
||||
t.Errorf("'type' query = %v, expected %v", actual, expected)
|
||||
}
|
||||
fmt.Fprint(w, `{"images":[{"id":1},{"id":2}]}`)
|
||||
})
|
||||
|
||||
images, _, err := client.Images.ListApplication(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Images.ListApplication returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := []Image{{ID: 1}, {ID: 2}}
|
||||
if !reflect.DeepEqual(images, expected) {
|
||||
t.Errorf("Images.ListApplication returned %+v, expected %+v", images, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_ListUser(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "GET")
|
||||
expected := "true"
|
||||
actual := r.URL.Query().Get("private")
|
||||
if actual != expected {
|
||||
t.Errorf("'private' query = %v, expected %v", actual, expected)
|
||||
}
|
||||
|
||||
fmt.Fprint(w, `{"images":[{"id":1},{"id":2}]}`)
|
||||
})
|
||||
|
||||
images, _, err := client.Images.ListUser(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Images.ListUser returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := []Image{{ID: 1}, {ID: 2}}
|
||||
if !reflect.DeepEqual(images, expected) {
|
||||
t.Errorf("Images.ListUser returned %+v, expected %+v", images, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_ListImagesMultiplePages(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
@ -74,18 +151,110 @@ func TestImages_RetrievePageByNumber(t *testing.T) {
|
|||
checkCurrentPage(t, resp, 2)
|
||||
}
|
||||
|
||||
func TestImages_GetImageByID(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images/12345", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "GET")
|
||||
fmt.Fprint(w, `{"image":{"id":12345}}`)
|
||||
})
|
||||
|
||||
images, _, err := client.Images.GetByID(12345)
|
||||
if err != nil {
|
||||
t.Errorf("Image.GetByID returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := &Image{ID: 12345}
|
||||
if !reflect.DeepEqual(images, expected) {
|
||||
t.Errorf("Images.GetByID returned %+v, expected %+v", images, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_GetImageBySlug(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images/ubuntu", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "GET")
|
||||
fmt.Fprint(w, `{"image":{"id":12345}}`)
|
||||
})
|
||||
|
||||
images, _, err := client.Images.GetBySlug("ubuntu")
|
||||
if err != nil {
|
||||
t.Errorf("Image.GetBySlug returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := &Image{ID: 12345}
|
||||
if !reflect.DeepEqual(images, expected) {
|
||||
t.Errorf("Images.Get returned %+v, expected %+v", images, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_Update(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
updateRequest := &ImageUpdateRequest{
|
||||
Name: "name",
|
||||
}
|
||||
|
||||
mux.HandleFunc("/v2/images/12345", func(w http.ResponseWriter, r *http.Request) {
|
||||
expected := map[string]interface{}{
|
||||
"name": "name",
|
||||
}
|
||||
|
||||
var v map[string]interface{}
|
||||
err := json.NewDecoder(r.Body).Decode(&v)
|
||||
if err != nil {
|
||||
t.Fatalf("decode json: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(v, expected) {
|
||||
t.Errorf("Request body = %#v, expected %#v", v, expected)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, `{"image":{"id":1}}`)
|
||||
})
|
||||
|
||||
image, _, err := client.Images.Update(12345, updateRequest)
|
||||
if err != nil {
|
||||
t.Errorf("Images.Update returned error: %v", err)
|
||||
} else {
|
||||
if id := image.ID; id != 1 {
|
||||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestImages_Destroy(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
mux.HandleFunc("/v2/images/12345", func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, "DELETE")
|
||||
})
|
||||
|
||||
_, err := client.Images.Delete(12345)
|
||||
if err != nil {
|
||||
t.Errorf("Image.Delete returned error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImage_String(t *testing.T) {
|
||||
image := &Image{
|
||||
ID: 1,
|
||||
Name: "Image",
|
||||
Type: "snapshot",
|
||||
Distribution: "Ubuntu",
|
||||
Slug: "image",
|
||||
Public: true,
|
||||
Regions: []string{"one", "two"},
|
||||
MinDiskSize: 20,
|
||||
}
|
||||
|
||||
stringified := image.String()
|
||||
expected := `godo.Image{ID:1, Name:"Image", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"]}`
|
||||
expected := `godo.Image{ID:1, Name:"Image", Type:"snapshot", Distribution:"Ubuntu", Slug:"image", Public:true, Regions:["one" "two"], MinDiskSize:20}`
|
||||
if expected != stringified {
|
||||
t.Errorf("Image.String returned %+v, expected %+v", stringified, expected)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue