From cd0f7879862db418cffc6ac247592581f172bc54 Mon Sep 17 00:00:00 2001 From: Alejandro JNM Date: Thu, 8 Apr 2021 18:35:11 -0400 Subject: [PATCH] Added new methods for DiskImage Signed-off-by: Alejandro JNM --- disk_image.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++ disk_image_test.go | 71 +++++++++++++++++++++++++++++++++++++++ fake_client.go | 73 ++++++++++++++++++++++++++++++++++++++++ instance.go | 4 +++ 4 files changed, 231 insertions(+) create mode 100644 disk_image.go create mode 100644 disk_image_test.go diff --git a/disk_image.go b/disk_image.go new file mode 100644 index 0000000..285140c --- /dev/null +++ b/disk_image.go @@ -0,0 +1,83 @@ +package civogo + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" +) + +// DiskImage represents a DiskImage for launching instances from +type DiskImage struct { + ID string `json:"id"` + Name string `json:"name"` + Version string `json:"version"` + State string `json:"state"` + Distribution string `json:"distribution"` + Description string `json:"description"` + Label string `json:"label"` +} + +// ListDiskImages return all disk image in system +func (c *Client) ListDiskImages() ([]DiskImage, error) { + resp, err := c.SendGetRequest("/v2/disk_images") + if err != nil { + return nil, decodeERROR(err) + } + + diskImages := make([]DiskImage, 0) + if err := json.NewDecoder(bytes.NewReader(resp)).Decode(&diskImages); err != nil { + return nil, err + } + + return diskImages, nil +} + +// GetDiskImage get one disk image using the id +func (c *Client) GetDiskImage(id string) (*DiskImage, error) { + resp, err := c.SendGetRequest(fmt.Sprintf("/v2/disk_images/%s", id)) + if err != nil { + return nil, decodeERROR(err) + } + + diskImage := &DiskImage{} + if err := json.NewDecoder(bytes.NewReader(resp)).Decode(&diskImage); err != nil { + return nil, err + } + + return diskImage, nil +} + +// FindDiskImage finds a disk image by either part of the ID or part of the name +func (c *Client) FindDiskImage(search string) (*DiskImage, error) { + templateList, err := c.ListDiskImages() + if err != nil { + return nil, decodeERROR(err) + } + + exactMatch := false + partialMatchesCount := 0 + result := DiskImage{} + + for _, value := range templateList { + if value.Name == search || value.ID == search { + exactMatch = true + result = value + } else if strings.Contains(value.Name, search) || strings.Contains(value.ID, search) { + if !exactMatch { + result = value + partialMatchesCount++ + } + } + } + + if exactMatch || partialMatchesCount == 1 { + return &result, nil + } else if partialMatchesCount > 1 { + err := fmt.Errorf("unable to find %s because there were multiple matches", search) + return nil, MultipleMatchesError.wrap(err) + } else { + err := fmt.Errorf("unable to find %s, zero matches", search) + return nil, ZeroMatchesError.wrap(err) + } +} diff --git a/disk_image_test.go b/disk_image_test.go new file mode 100644 index 0000000..0c92d4a --- /dev/null +++ b/disk_image_test.go @@ -0,0 +1,71 @@ +package civogo + +import ( + "testing" +) + +func TestClienterDiskImage(t *testing.T) { + var c Clienter + + c, _ = NewClient("foo", "NYC1") + c, _ = NewFakeClient() + _, _ = c.ListDiskImages() +} + +func TestListDiskImages(t *testing.T) { + client, _ := NewFakeClient() + + results, err := client.ListDiskImages() + if err != nil { + t.Errorf("Request returned an error: %s", err) + return + } + + if len(results) != 4 { + t.Errorf("Expected %+v, got %+v", 4, len(results)) + return + } + +} + +func TestGetDiskImage(t *testing.T) { + client, _ := NewFakeClient() + + results, err := client.GetDiskImage("b82168fe-66f6-4b38-a3b8-5283542d5475") + if err != nil { + t.Errorf("Request returned an error: %s", err) + return + } + + if results.ID != "b82168fe-66f6-4b38-a3b8-5283542d5475" { + t.Errorf("Expected %+v, got %+v", "b82168fe-66f6-4b38-a3b8-5283542d5475", results.ID) + return + } + + if results.Name != "centos-7" { + t.Errorf("Expected %+v, got %+v", "centos-7", results.Name) + return + } + +} + +func TestFindDiskImage(t *testing.T) { + client, _ := NewFakeClient() + + results, err := client.FindDiskImage("debian-10") + if err != nil { + t.Errorf("Request returned an error: %s", err) + return + } + + if results.ID != "b82168fe-66f6-4b38-a3b8-52835428965" { + t.Errorf("Expected %+v, got %+v", "b82168fe-66f6-4b38-a3b8-52835428965", results.ID) + return + } + + if results.Name != "debian-10" { + t.Errorf("Expected %+v, got %+v", "debian-10", results.Name) + return + } + +} diff --git a/fake_client.go b/fake_client.go index 9e27c6c..efe4a9f 100644 --- a/fake_client.go +++ b/fake_client.go @@ -26,6 +26,7 @@ type FakeClient struct { SSHKeys []SSHKey Webhooks []Webhook Templates []Template + DiskImage []DiskImage Quota Quota } @@ -135,6 +136,11 @@ type Clienter interface { FindTemplate(search string) (*Template, error) DeleteTemplate(id string) (*SimpleResponse, error) + // DiskImages + ListDiskImages() ([]DiskImage, error) + GetDiskImage(id string) (*DiskImage, error) + FindDiskImage(search string) (*DiskImage, error) + // Volumes ListVolumes() ([]Volume, error) FindVolume(search string) (*Volume, error) @@ -190,6 +196,44 @@ func NewFakeClient() (*FakeClient, error) { DiskGigabytes: 40, }, }, + DiskImage: []DiskImage{ + { + ID: "b82168fe-66f6-4b38-a3b8-5283542d5475", + Name: "centos-7", + Version: "7", + State: "available", + Distribution: "centos", + Description: "", + Label: "", + }, + { + ID: "b82168fe-66f6-4b38-a3b8-52835425895", + Name: "debian-9", + Version: "9", + State: "available", + Distribution: "debian", + Description: "", + Label: "", + }, + { + ID: "b82168fe-66f6-4b38-a3b8-52835428965", + Name: "debian-10", + Version: "10", + State: "available", + Distribution: "debian", + Description: "", + Label: "", + }, + { + ID: "b82168fe-66f6-4b38-a3b8-528354282548", + Name: "ubuntu-20-4", + Version: "20.4", + State: "available", + Distribution: "ubuntu", + Description: "", + Label: "", + }, + }, }, nil } @@ -1032,6 +1076,35 @@ func (c *FakeClient) DeleteTemplate(id string) (*SimpleResponse, error) { return &SimpleResponse{Result: "failed"}, nil } +// ListDiskImages implemented in a fake way for automated tests +func (c *FakeClient) ListDiskImages() ([]DiskImage, error) { + return c.DiskImage, nil +} + +// GetDiskImage implemented in a fake way for automated tests +func (c *FakeClient) GetDiskImage(id string) (*DiskImage, error) { + for k, v := range c.DiskImage { + if v.ID == id { + return &c.DiskImage[k], nil + } + } + + err := fmt.Errorf("unable to find disk image %s, zero matches", id) + return nil, ZeroMatchesError.wrap(err) +} + +// GetDiskImage implemented in a fake way for automated tests +func (c *FakeClient) FindDiskImage(search string) (*DiskImage, error) { + for _, diskimage := range c.DiskImage { + if strings.Contains(diskimage.Name, search) || strings.Contains(diskimage.ID, search) { + return &diskimage, nil + } + } + + err := fmt.Errorf("unable to find volume %s, zero matches", search) + return nil, ZeroMatchesError.wrap(err) +} + // ListVolumes implemented in a fake way for automated tests func (c *FakeClient) ListVolumes() ([]Volume, error) { return c.Volumes, nil diff --git a/instance.go b/instance.go index 2215ea2..9deb516 100644 --- a/instance.go +++ b/instance.go @@ -23,6 +23,8 @@ type Instance struct { PublicIP string `json:"public_ip"` PseudoIP string `json:"pseudo_ip"` TemplateID string `json:"template_id"` + SourceType string `json:"source_type"` + SourceID string `json:"source_id"` SnapshotID string `json:"snapshot_id"` InitialUser string `json:"initial_user"` InitialPassword string `json:"initial_password"` @@ -72,6 +74,8 @@ type InstanceConfig struct { PublicIPRequired string `json:"public_ip"` NetworkID string `json:"network_id"` TemplateID string `json:"template_id"` + SourceType string `json:"source_type"` + SourceID string `json:"source_id"` SnapshotID string `json:"snapshot_id"` InitialUser string `json:"initial_user"` SSHKeyID string `json:"ssh_key_id"`