From 6681a86211666fef6a4b0daf1ca741ac6b3b01b6 Mon Sep 17 00:00:00 2001 From: Caio Filipini Date: Mon, 15 May 2017 15:54:16 +0200 Subject: [PATCH 1/6] provider/digitalocean: Update godo for Certificates support There are three "deeper" changes included with this update: 1) The `Detach` function got removed from the `StorageActionsService` in favor of `DetachByDropletID` (which is now used in `resource_digitalocean_volume.go`). 2) The `Update` function got removed from `TagsService` (renaming a tag has been deprecated in the API). 3) Every function in godo now takes a `context.Context` as first argument, so I've changed all calls to send in a `context.Background()`. --- builtin/providers/digitalocean/config.go | 3 +- .../datasource_digitalocean_image.go | 3 +- .../datasource_digitalocean_image_test.go | 7 +- .../providers/digitalocean/loadbalancer.go | 3 +- builtin/providers/digitalocean/provider.go | 1 + .../resource_digitalocean_domain.go | 7 +- .../resource_digitalocean_domain_test.go | 5 +- .../resource_digitalocean_droplet.go | 27 +-- .../resource_digitalocean_droplet_test.go | 5 +- .../resource_digitalocean_floating_ip.go | 17 +- .../resource_digitalocean_floating_ip_test.go | 5 +- .../resource_digitalocean_loadbalancer.go | 9 +- ...resource_digitalocean_loadbalancer_test.go | 5 +- .../resource_digitalocean_record.go | 9 +- .../resource_digitalocean_record_test.go | 5 +- .../resource_digitalocean_ssh_key.go | 9 +- .../resource_digitalocean_ssh_key_test.go | 5 +- .../digitalocean/resource_digitalocean_tag.go | 32 +-- .../resource_digitalocean_tag_test.go | 5 +- .../resource_digitalocean_volume.go | 9 +- .../resource_digitalocean_volume_test.go | 5 +- builtin/providers/digitalocean/tags.go | 5 +- .../github.com/digitalocean/godo/CHANGELOG.md | 10 + vendor/github.com/digitalocean/godo/README.md | 8 +- .../github.com/digitalocean/godo/account.go | 11 +- vendor/github.com/digitalocean/godo/action.go | 22 +- .../digitalocean/godo/certificates.go | 121 +++++++++++ .../digitalocean/godo/context/context.go | 98 +++++++++ .../digitalocean/godo/context/context_go17.go | 39 ++++ .../godo/context/context_pre_go17.go | 41 ++++ .../github.com/digitalocean/godo/domains.go | 80 ++++---- .../digitalocean/godo/droplet_actions.go | 194 +++++++++--------- .../github.com/digitalocean/godo/droplets.go | 114 +++++----- .../digitalocean/godo/floating_ips.go | 38 ++-- .../digitalocean/godo/floating_ips_actions.go | 48 +++-- vendor/github.com/digitalocean/godo/godo.go | 12 +- .../digitalocean/godo/image_actions.go | 49 ++++- vendor/github.com/digitalocean/godo/images.go | 70 ++++--- vendor/github.com/digitalocean/godo/keys.go | 74 +++---- vendor/github.com/digitalocean/godo/links.go | 6 +- .../digitalocean/godo/load_balancers.go | 74 +++---- .../github.com/digitalocean/godo/regions.go | 10 +- vendor/github.com/digitalocean/godo/sizes.go | 10 +- .../github.com/digitalocean/godo/snapshots.go | 52 ++--- .../github.com/digitalocean/godo/storage.go | 90 ++++---- .../digitalocean/godo/storage_actions.go | 63 +++--- vendor/github.com/digitalocean/godo/tags.go | 81 +++----- vendor/vendor.json | 12 +- 48 files changed, 998 insertions(+), 610 deletions(-) create mode 100644 vendor/github.com/digitalocean/godo/CHANGELOG.md create mode 100644 vendor/github.com/digitalocean/godo/certificates.go create mode 100644 vendor/github.com/digitalocean/godo/context/context.go create mode 100644 vendor/github.com/digitalocean/godo/context/context_go17.go create mode 100644 vendor/github.com/digitalocean/godo/context/context_pre_go17.go mode change 100755 => 100644 vendor/github.com/digitalocean/godo/load_balancers.go diff --git a/builtin/providers/digitalocean/config.go b/builtin/providers/digitalocean/config.go index b32be5938..9c9e4cd20 100644 --- a/builtin/providers/digitalocean/config.go +++ b/builtin/providers/digitalocean/config.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "log" "net/http" "net/http/httputil" @@ -55,7 +56,7 @@ func waitForAction(client *godo.Client, action *godo.Action) error { pending = "in-progress" target = "completed" refreshfn = func() (result interface{}, state string, err error) { - a, _, err := client.Actions.Get(action.ID) + a, _, err := client.Actions.Get(context.Background(), action.ID) if err != nil { return nil, "", err } diff --git a/builtin/providers/digitalocean/datasource_digitalocean_image.go b/builtin/providers/digitalocean/datasource_digitalocean_image.go index d4023daf8..e47e422bf 100644 --- a/builtin/providers/digitalocean/datasource_digitalocean_image.go +++ b/builtin/providers/digitalocean/datasource_digitalocean_image.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "strconv" @@ -54,7 +55,7 @@ func dataSourceDigitalOceanImageRead(d *schema.ResourceData, meta interface{}) e opts := &godo.ListOptions{} - images, _, err := client.Images.ListUser(opts) + images, _, err := client.Images.ListUser(context.Background(), opts) if err != nil { d.SetId("") return err diff --git a/builtin/providers/digitalocean/datasource_digitalocean_image_test.go b/builtin/providers/digitalocean/datasource_digitalocean_image_test.go index ab77c75ae..18a1e0865 100644 --- a/builtin/providers/digitalocean/datasource_digitalocean_image_test.go +++ b/builtin/providers/digitalocean/datasource_digitalocean_image_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "regexp" @@ -70,7 +71,7 @@ func takeSnapshotsOfDroplet(rInt int, droplet *godo.Droplet, snapshotsId *[]int) return err } } - retrieveDroplet, _, err := client.Droplets.Get((*droplet).ID) + retrieveDroplet, _, err := client.Droplets.Get(context.Background(), (*droplet).ID) if err != nil { return err } @@ -81,7 +82,7 @@ func takeSnapshotsOfDroplet(rInt int, droplet *godo.Droplet, snapshotsId *[]int) func takeSnapshotOfDroplet(rInt, sInt int, droplet *godo.Droplet) error { client := testAccProvider.Meta().(*godo.Client) - action, _, err := client.DropletActions.Snapshot((*droplet).ID, fmt.Sprintf("snap-%d-%d", rInt, sInt)) + action, _, err := client.DropletActions.Snapshot(context.Background(), (*droplet).ID, fmt.Sprintf("snap-%d-%d", rInt, sInt)) if err != nil { return err } @@ -96,7 +97,7 @@ func deleteSnapshots(snapshotsId *[]int) resource.TestCheckFunc { snapshots := *snapshotsId for _, value := range snapshots { log.Printf("XXX Deleting %d", value) - _, err := client.Images.Delete(value) + _, err := client.Images.Delete(context.Background(), value) if err != nil { return err } diff --git a/builtin/providers/digitalocean/loadbalancer.go b/builtin/providers/digitalocean/loadbalancer.go index abf868055..efacf7ae5 100644 --- a/builtin/providers/digitalocean/loadbalancer.go +++ b/builtin/providers/digitalocean/loadbalancer.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "github.com/digitalocean/godo" @@ -9,7 +10,7 @@ import ( func loadbalancerStateRefreshFunc(client *godo.Client, loadbalancerId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - lb, _, err := client.LoadBalancers.Get(loadbalancerId) + lb, _, err := client.LoadBalancers.Get(context.Background(), loadbalancerId) if err != nil { return nil, "", fmt.Errorf("Error issuing read request in LoadbalancerStateRefreshFunc to DigitalOcean for Load Balancer '%s': %s", loadbalancerId, err) } diff --git a/builtin/providers/digitalocean/provider.go b/builtin/providers/digitalocean/provider.go index e885e0823..9d0b9af1b 100644 --- a/builtin/providers/digitalocean/provider.go +++ b/builtin/providers/digitalocean/provider.go @@ -22,6 +22,7 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ + "digitalocean_certificate": resourceDigitalOceanCertificate(), "digitalocean_domain": resourceDigitalOceanDomain(), "digitalocean_droplet": resourceDigitalOceanDroplet(), "digitalocean_floating_ip": resourceDigitalOceanFloatingIp(), diff --git a/builtin/providers/digitalocean/resource_digitalocean_domain.go b/builtin/providers/digitalocean/resource_digitalocean_domain.go index a093ad546..a60f1269f 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_domain.go +++ b/builtin/providers/digitalocean/resource_digitalocean_domain.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" @@ -44,7 +45,7 @@ func resourceDigitalOceanDomainCreate(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] Domain create configuration: %#v", opts) - domain, _, err := client.Domains.Create(opts) + domain, _, err := client.Domains.Create(context.Background(), opts) if err != nil { return fmt.Errorf("Error creating Domain: %s", err) } @@ -58,7 +59,7 @@ func resourceDigitalOceanDomainCreate(d *schema.ResourceData, meta interface{}) func resourceDigitalOceanDomainRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*godo.Client) - domain, resp, err := client.Domains.Get(d.Id()) + domain, resp, err := client.Domains.Get(context.Background(), d.Id()) if err != nil { // If the domain is somehow already destroyed, mark as // successfully gone @@ -79,7 +80,7 @@ func resourceDigitalOceanDomainDelete(d *schema.ResourceData, meta interface{}) client := meta.(*godo.Client) log.Printf("[INFO] Deleting Domain: %s", d.Id()) - _, err := client.Domains.Delete(d.Id()) + _, err := client.Domains.Delete(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error deleting Domain: %s", err) } diff --git a/builtin/providers/digitalocean/resource_digitalocean_domain_test.go b/builtin/providers/digitalocean/resource_digitalocean_domain_test.go index df2779627..66e9ce09e 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_domain_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_domain_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "testing" @@ -43,7 +44,7 @@ func testAccCheckDigitalOceanDomainDestroy(s *terraform.State) error { } // Try to find the domain - _, _, err := client.Domains.Get(rs.Primary.ID) + _, _, err := client.Domains.Get(context.Background(), rs.Primary.ID) if err == nil { return fmt.Errorf("Domain still exists") @@ -78,7 +79,7 @@ func testAccCheckDigitalOceanDomainExists(n string, domain *godo.Domain) resourc client := testAccProvider.Meta().(*godo.Client) - foundDomain, _, err := client.Domains.Get(rs.Primary.ID) + foundDomain, _, err := client.Domains.Get(context.Background(), rs.Primary.ID) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet.go b/builtin/providers/digitalocean/resource_digitalocean_droplet.go index fdae4dd03..d0a8674c3 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "strconv" @@ -213,7 +214,7 @@ func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{}) log.Printf("[DEBUG] Droplet create configuration: %#v", opts) - droplet, _, err := client.Droplets.Create(opts) + droplet, _, err := client.Droplets.Create(context.Background(), opts) if err != nil { return fmt.Errorf("Error creating droplet: %s", err) @@ -248,7 +249,7 @@ func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) e } // Retrieve the droplet properties for updating the state - droplet, resp, err := client.Droplets.Get(id) + droplet, resp, err := client.Droplets.Get(context.Background(), id) if err != nil { // check if the droplet no longer exists. if resp != nil && resp.StatusCode == 404 { @@ -341,7 +342,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) if d.HasChange("size") || d.HasChange("resize_disk") && resize_disk { newSize := d.Get("size") - _, _, err = client.DropletActions.PowerOff(id) + _, _, err = client.DropletActions.PowerOff(context.Background(), id) if err != nil && !strings.Contains(err.Error(), "Droplet is already powered off") { return fmt.Errorf( "Error powering off droplet (%s): %s", d.Id(), err) @@ -355,7 +356,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) } // Resize the droplet - action, _, err := client.DropletActions.Resize(id, newSize.(string), resize_disk) + action, _, err := client.DropletActions.Resize(context.Background(), id, newSize.(string), resize_disk) if err != nil { newErr := powerOnAndWait(d, meta) if newErr != nil { @@ -377,7 +378,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) "Error waiting for resize droplet (%s) to finish: %s", d.Id(), err) } - _, _, err = client.DropletActions.PowerOn(id) + _, _, err = client.DropletActions.PowerOn(context.Background(), id) if err != nil { return fmt.Errorf( @@ -395,7 +396,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) oldName, newName := d.GetChange("name") // Rename the droplet - _, _, err = client.DropletActions.Rename(id, newName.(string)) + _, _, err = client.DropletActions.Rename(context.Background(), id, newName.(string)) if err != nil { return fmt.Errorf( @@ -415,7 +416,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) // As there is no way to disable private networking, // we only check if it needs to be enabled if d.HasChange("private_networking") && d.Get("private_networking").(bool) { - _, _, err = client.DropletActions.EnablePrivateNetworking(id) + _, _, err = client.DropletActions.EnablePrivateNetworking(context.Background(), id) if err != nil { return fmt.Errorf( @@ -432,7 +433,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) // As there is no way to disable IPv6, we only check if it needs to be enabled if d.HasChange("ipv6") && d.Get("ipv6").(bool) { - _, _, err = client.DropletActions.EnableIPv6(id) + _, _, err = client.DropletActions.EnableIPv6(context.Background(), id) if err != nil { return fmt.Errorf( @@ -478,7 +479,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) oldIDSet := newSet(oldIDs.([]interface{})) newIDSet := newSet(newIDs.([]interface{})) for volumeID := range leftDiff(newIDSet, oldIDSet) { - action, _, err := client.StorageActions.Attach(volumeID, id) + action, _, err := client.StorageActions.Attach(context.Background(), volumeID, id) if err != nil { return fmt.Errorf("Error attaching volume %q to droplet (%s): %s", volumeID, d.Id(), err) } @@ -488,7 +489,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) } } for volumeID := range leftDiff(oldIDSet, newIDSet) { - action, _, err := client.StorageActions.Detach(volumeID) + action, _, err := client.StorageActions.DetachByDropletID(context.Background(), volumeID, id) if err != nil { return fmt.Errorf("Error detaching volume %q from droplet (%s): %s", volumeID, d.Id(), err) } @@ -521,7 +522,7 @@ func resourceDigitalOceanDropletDelete(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Deleting droplet: %s", d.Id()) // Destroy the droplet - _, err = client.Droplets.Delete(id) + _, err = client.Droplets.Delete(context.Background(), id) // Handle remotely destroyed droplets if err != nil && strings.Contains(err.Error(), "404 Not Found") { @@ -587,7 +588,7 @@ func newDropletStateRefreshFunc( // See if we can access our attribute if attr, ok := d.GetOk(attribute); ok { // Retrieve the droplet properties - droplet, _, err := client.Droplets.Get(id) + droplet, _, err := client.Droplets.Get(context.Background(), id) if err != nil { return nil, "", fmt.Errorf("Error retrieving droplet: %s", err) } @@ -607,7 +608,7 @@ func powerOnAndWait(d *schema.ResourceData, meta interface{}) error { } client := meta.(*godo.Client) - _, _, err = client.DropletActions.PowerOn(id) + _, _, err = client.DropletActions.PowerOn(context.Background(), id) if err != nil { return err } diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go index 1d6f78042..73290400c 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "strconv" "strings" @@ -332,7 +333,7 @@ func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error { } // Try to find the Droplet - _, _, err = client.Droplets.Get(id) + _, _, err = client.Droplets.Get(context.Background(), id) // Wait @@ -482,7 +483,7 @@ func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) reso } // Try to find the Droplet - retrieveDroplet, _, err := client.Droplets.Get(id) + retrieveDroplet, _, err := client.Droplets.Get(context.Background(), id) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_floating_ip.go b/builtin/providers/digitalocean/resource_digitalocean_floating_ip.go index 206c5702a..0f4a8d346 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_floating_ip.go +++ b/builtin/providers/digitalocean/resource_digitalocean_floating_ip.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "time" @@ -50,7 +51,7 @@ func resourceDigitalOceanFloatingIpCreate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] FloatingIP Create: %#v", regionOpts) - floatingIp, _, err := client.FloatingIPs.Create(regionOpts) + floatingIp, _, err := client.FloatingIPs.Create(context.Background(), regionOpts) if err != nil { return fmt.Errorf("Error creating FloatingIP: %s", err) } @@ -60,7 +61,7 @@ func resourceDigitalOceanFloatingIpCreate(d *schema.ResourceData, meta interface if v, ok := d.GetOk("droplet_id"); ok { log.Printf("[INFO] Assigning the Floating IP to the Droplet %d", v.(int)) - action, _, err := client.FloatingIPActions.Assign(d.Id(), v.(int)) + action, _, err := client.FloatingIPActions.Assign(context.Background(), d.Id(), v.(int)) if err != nil { return fmt.Errorf( "Error Assigning FloatingIP (%s) to the droplet: %s", d.Id(), err) @@ -82,7 +83,7 @@ func resourceDigitalOceanFloatingIpUpdate(d *schema.ResourceData, meta interface if d.HasChange("droplet_id") { if v, ok := d.GetOk("droplet_id"); ok { log.Printf("[INFO] Assigning the Floating IP %s to the Droplet %d", d.Id(), v.(int)) - action, _, err := client.FloatingIPActions.Assign(d.Id(), v.(int)) + action, _, err := client.FloatingIPActions.Assign(context.Background(), d.Id(), v.(int)) if err != nil { return fmt.Errorf( "Error Assigning FloatingIP (%s) to the droplet: %s", d.Id(), err) @@ -95,7 +96,7 @@ func resourceDigitalOceanFloatingIpUpdate(d *schema.ResourceData, meta interface } } else { log.Printf("[INFO] Unassigning the Floating IP %s", d.Id()) - action, _, err := client.FloatingIPActions.Unassign(d.Id()) + action, _, err := client.FloatingIPActions.Unassign(context.Background(), d.Id()) if err != nil { return fmt.Errorf( "Error Unassigning FloatingIP (%s): %s", d.Id(), err) @@ -116,7 +117,7 @@ func resourceDigitalOceanFloatingIpRead(d *schema.ResourceData, meta interface{} client := meta.(*godo.Client) log.Printf("[INFO] Reading the details of the FloatingIP %s", d.Id()) - floatingIp, _, err := client.FloatingIPs.Get(d.Id()) + floatingIp, _, err := client.FloatingIPs.Get(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error retrieving FloatingIP: %s", err) } @@ -140,7 +141,7 @@ func resourceDigitalOceanFloatingIpDelete(d *schema.ResourceData, meta interface if _, ok := d.GetOk("droplet_id"); ok { log.Printf("[INFO] Unassigning the Floating IP from the Droplet") - action, _, err := client.FloatingIPActions.Unassign(d.Id()) + action, _, err := client.FloatingIPActions.Unassign(context.Background(), d.Id()) if err != nil { return fmt.Errorf( "Error Unassigning FloatingIP (%s) from the droplet: %s", d.Id(), err) @@ -154,7 +155,7 @@ func resourceDigitalOceanFloatingIpDelete(d *schema.ResourceData, meta interface } log.Printf("[INFO] Deleting FloatingIP: %s", d.Id()) - _, err := client.FloatingIPs.Delete(d.Id()) + _, err := client.FloatingIPs.Delete(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error deleting FloatingIP: %s", err) } @@ -189,7 +190,7 @@ func newFloatingIPStateRefreshFunc( return func() (interface{}, string, error) { log.Printf("[INFO] Assigning the Floating IP to the Droplet") - action, _, err := client.FloatingIPActions.Get(d.Id(), actionId) + action, _, err := client.FloatingIPActions.Get(context.Background(), d.Id(), actionId) if err != nil { return nil, "", fmt.Errorf("Error retrieving FloatingIP (%s) ActionId (%d): %s", d.Id(), actionId, err) } diff --git a/builtin/providers/digitalocean/resource_digitalocean_floating_ip_test.go b/builtin/providers/digitalocean/resource_digitalocean_floating_ip_test.go index dce57b5fb..cd05aae55 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_floating_ip_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_floating_ip_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "testing" @@ -60,7 +61,7 @@ func testAccCheckDigitalOceanFloatingIPDestroy(s *terraform.State) error { } // Try to find the key - _, _, err := client.FloatingIPs.Get(rs.Primary.ID) + _, _, err := client.FloatingIPs.Get(context.Background(), rs.Primary.ID) if err == nil { return fmt.Errorf("Floating IP still exists") @@ -85,7 +86,7 @@ func testAccCheckDigitalOceanFloatingIPExists(n string, floatingIP *godo.Floatin client := testAccProvider.Meta().(*godo.Client) // Try to find the FloatingIP - foundFloatingIP, _, err := client.FloatingIPs.Get(rs.Primary.ID) + foundFloatingIP, _, err := client.FloatingIPs.Get(context.Background(), rs.Primary.ID) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_loadbalancer.go b/builtin/providers/digitalocean/resource_digitalocean_loadbalancer.go index 73aee03bc..b24556f40 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_loadbalancer.go +++ b/builtin/providers/digitalocean/resource_digitalocean_loadbalancer.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "strconv" @@ -210,7 +211,7 @@ func resourceDigitalOceanLoadbalancerCreate(d *schema.ResourceData, meta interfa } log.Printf("[DEBUG] Loadbalancer Create: %#v", lbOpts) - loadbalancer, _, err := client.LoadBalancers.Create(lbOpts) + loadbalancer, _, err := client.LoadBalancers.Create(context.Background(), lbOpts) if err != nil { return fmt.Errorf("Error creating Load Balancer: %s", err) } @@ -236,7 +237,7 @@ func resourceDigitalOceanLoadbalancerRead(d *schema.ResourceData, meta interface client := meta.(*godo.Client) log.Printf("[INFO] Reading the details of the Loadbalancer %s", d.Id()) - loadbalancer, _, err := client.LoadBalancers.Get(d.Id()) + loadbalancer, _, err := client.LoadBalancers.Get(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error retrieving Loadbalancer: %s", err) } @@ -274,7 +275,7 @@ func resourceDigitalOceanLoadbalancerUpdate(d *schema.ResourceData, meta interfa } log.Printf("[DEBUG] Load Balancer Update: %#v", lbOpts) - _, _, err = client.LoadBalancers.Update(d.Id(), lbOpts) + _, _, err = client.LoadBalancers.Update(context.Background(), d.Id(), lbOpts) if err != nil { return fmt.Errorf("Error updating Load Balancer: %s", err) } @@ -286,7 +287,7 @@ func resourceDigitalOceanLoadbalancerDelete(d *schema.ResourceData, meta interfa client := meta.(*godo.Client) log.Printf("[INFO] Deleting Load Balancer: %s", d.Id()) - _, err := client.LoadBalancers.Delete(d.Id()) + _, err := client.LoadBalancers.Delete(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error deleting Load Balancer: %s", err) } diff --git a/builtin/providers/digitalocean/resource_digitalocean_loadbalancer_test.go b/builtin/providers/digitalocean/resource_digitalocean_loadbalancer_test.go index 7dc5626f2..b4955d720 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_loadbalancer_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_loadbalancer_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "strings" "testing" @@ -170,7 +171,7 @@ func testAccCheckDigitalOceanLoadbalancerDestroy(s *terraform.State) error { continue } - _, _, err := client.LoadBalancers.Get(rs.Primary.ID) + _, _, err := client.LoadBalancers.Get(context.Background(), rs.Primary.ID) if err != nil && !strings.Contains(err.Error(), "404") { return fmt.Errorf( @@ -195,7 +196,7 @@ func testAccCheckDigitalOceanLoadbalancerExists(n string, loadbalancer *godo.Loa client := testAccProvider.Meta().(*godo.Client) - lb, _, err := client.LoadBalancers.Get(rs.Primary.ID) + lb, _, err := client.LoadBalancers.Get(context.Background(), rs.Primary.ID) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_record.go b/builtin/providers/digitalocean/resource_digitalocean_record.go index 794787eae..c22da8bb2 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_record.go +++ b/builtin/providers/digitalocean/resource_digitalocean_record.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "strconv" @@ -101,7 +102,7 @@ func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] record create configuration: %#v", newRecord) - rec, _, err := client.Domains.CreateRecord(d.Get("domain").(string), &newRecord) + rec, _, err := client.Domains.CreateRecord(context.Background(), d.Get("domain").(string), &newRecord) if err != nil { return fmt.Errorf("Failed to create record: %s", err) } @@ -120,7 +121,7 @@ func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("invalid record ID: %v", err) } - rec, resp, err := client.Domains.Record(domain, id) + rec, resp, err := client.Domains.Record(context.Background(), domain, id) if err != nil { // If the record is somehow already destroyed, mark as // successfully gone @@ -168,7 +169,7 @@ func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] record update configuration: %#v", editRecord) - _, _, err = client.Domains.EditRecord(domain, id, &editRecord) + _, _, err = client.Domains.EditRecord(context.Background(), domain, id, &editRecord) if err != nil { return fmt.Errorf("Failed to update record: %s", err) } @@ -187,7 +188,7 @@ func resourceDigitalOceanRecordDelete(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Deleting record: %s, %d", domain, id) - resp, delErr := client.Domains.DeleteRecord(domain, id) + resp, delErr := client.Domains.DeleteRecord(context.Background(), domain, id) if delErr != nil { // If the record is somehow already destroyed, mark as // successfully gone diff --git a/builtin/providers/digitalocean/resource_digitalocean_record_test.go b/builtin/providers/digitalocean/resource_digitalocean_record_test.go index bb62db240..72f588a4a 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_record_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_record_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "strconv" "testing" @@ -235,7 +236,7 @@ func testAccCheckDigitalOceanRecordDestroy(s *terraform.State) error { return err } - _, _, err = client.Domains.Record(domain, id) + _, _, err = client.Domains.Record(context.Background(), domain, id) if err == nil { return fmt.Errorf("Record still exists") @@ -287,7 +288,7 @@ func testAccCheckDigitalOceanRecordExists(n string, record *godo.DomainRecord) r return err } - foundRecord, _, err := client.Domains.Record(domain, id) + foundRecord, _, err := client.Domains.Record(context.Background(), domain, id) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_ssh_key.go b/builtin/providers/digitalocean/resource_digitalocean_ssh_key.go index ba09206de..65d7743df 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_ssh_key.go +++ b/builtin/providers/digitalocean/resource_digitalocean_ssh_key.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" "strconv" @@ -60,7 +61,7 @@ func resourceDigitalOceanSSHKeyCreate(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] SSH Key create configuration: %#v", opts) - key, _, err := client.Keys.Create(opts) + key, _, err := client.Keys.Create(context.Background(), opts) if err != nil { return fmt.Errorf("Error creating SSH Key: %s", err) } @@ -79,7 +80,7 @@ func resourceDigitalOceanSSHKeyRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("invalid SSH key id: %v", err) } - key, resp, err := client.Keys.GetByID(id) + key, resp, err := client.Keys.GetByID(context.Background(), id) if err != nil { // If the key is somehow already destroyed, mark as // successfully gone @@ -115,7 +116,7 @@ func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{}) opts := &godo.KeyUpdateRequest{ Name: newName, } - _, _, err = client.Keys.UpdateByID(id, opts) + _, _, err = client.Keys.UpdateByID(context.Background(), id, opts) if err != nil { return fmt.Errorf("Failed to update SSH key: %s", err) } @@ -132,7 +133,7 @@ func resourceDigitalOceanSSHKeyDelete(d *schema.ResourceData, meta interface{}) } log.Printf("[INFO] Deleting SSH key: %d", id) - _, err = client.Keys.DeleteByID(id) + _, err = client.Keys.DeleteByID(context.Background(), id) if err != nil { return fmt.Errorf("Error deleting SSH key: %s", err) } diff --git a/builtin/providers/digitalocean/resource_digitalocean_ssh_key_test.go b/builtin/providers/digitalocean/resource_digitalocean_ssh_key_test.go index 043f667b7..3b518670d 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_ssh_key_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_ssh_key_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "strconv" "testing" @@ -52,7 +53,7 @@ func testAccCheckDigitalOceanSSHKeyDestroy(s *terraform.State) error { } // Try to find the key - _, _, err = client.Keys.GetByID(id) + _, _, err = client.Keys.GetByID(context.Background(), id) if err == nil { return fmt.Errorf("SSH key still exists") @@ -82,7 +83,7 @@ func testAccCheckDigitalOceanSSHKeyExists(n string, key *godo.Key) resource.Test } // Try to find the key - foundKey, _, err := client.Keys.GetByID(id) + foundKey, _, err := client.Keys.GetByID(context.Background(), id) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_tag.go b/builtin/providers/digitalocean/resource_digitalocean_tag.go index a1e0d7428..d82550af7 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_tag.go +++ b/builtin/providers/digitalocean/resource_digitalocean_tag.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" @@ -12,7 +13,6 @@ func resourceDigitalOceanTag() *schema.Resource { return &schema.Resource{ Create: resourceDigitalOceanTagCreate, Read: resourceDigitalOceanTagRead, - Update: resourceDigitalOceanTagUpdate, Delete: resourceDigitalOceanTagDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -22,6 +22,7 @@ func resourceDigitalOceanTag() *schema.Resource { "name": { Type: schema.TypeString, Required: true, + ForceNew: true, }, }, } @@ -36,7 +37,7 @@ func resourceDigitalOceanTagCreate(d *schema.ResourceData, meta interface{}) err } log.Printf("[DEBUG] Tag create configuration: %#v", opts) - tag, _, err := client.Tags.Create(opts) + tag, _, err := client.Tags.Create(context.Background(), opts) if err != nil { return fmt.Errorf("Error creating tag: %s", err) } @@ -50,7 +51,7 @@ func resourceDigitalOceanTagCreate(d *schema.ResourceData, meta interface{}) err func resourceDigitalOceanTagRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*godo.Client) - tag, resp, err := client.Tags.Get(d.Id()) + tag, resp, err := client.Tags.Get(context.Background(), d.Id()) if err != nil { // If the tag is somehow already destroyed, mark as // successfully gone @@ -67,34 +68,11 @@ func resourceDigitalOceanTagRead(d *schema.ResourceData, meta interface{}) error return nil } -func resourceDigitalOceanTagUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*godo.Client) - - var newName string - if v, ok := d.GetOk("name"); ok { - newName = v.(string) - } - - log.Printf("[DEBUG] tag update name: %#v", newName) - opts := &godo.TagUpdateRequest{ - Name: newName, - } - - _, err := client.Tags.Update(d.Id(), opts) - if err != nil { - return fmt.Errorf("Failed to update tag: %s", err) - } - - d.Set("name", newName) - - return resourceDigitalOceanTagRead(d, meta) -} - func resourceDigitalOceanTagDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*godo.Client) log.Printf("[INFO] Deleting tag: %s", d.Id()) - _, err := client.Tags.Delete(d.Id()) + _, err := client.Tags.Delete(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error deleting tag: %s", err) } diff --git a/builtin/providers/digitalocean/resource_digitalocean_tag_test.go b/builtin/providers/digitalocean/resource_digitalocean_tag_test.go index 673840377..bf2ee7eb1 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_tag_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_tag_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "testing" @@ -39,7 +40,7 @@ func testAccCheckDigitalOceanTagDestroy(s *terraform.State) error { } // Try to find the key - _, _, err := client.Tags.Get(rs.Primary.ID) + _, _, err := client.Tags.Get(context.Background(), rs.Primary.ID) if err == nil { return fmt.Errorf("Tag still exists") @@ -75,7 +76,7 @@ func testAccCheckDigitalOceanTagExists(n string, tag *godo.Tag) resource.TestChe client := testAccProvider.Meta().(*godo.Client) // Try to find the tag - foundTag, _, err := client.Tags.Get(rs.Primary.ID) + foundTag, _, err := client.Tags.Get(context.Background(), rs.Primary.ID) if err != nil { return err diff --git a/builtin/providers/digitalocean/resource_digitalocean_volume.go b/builtin/providers/digitalocean/resource_digitalocean_volume.go index 198eb72a1..1040fe9ca 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_volume.go +++ b/builtin/providers/digitalocean/resource_digitalocean_volume.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "log" @@ -67,7 +68,7 @@ func resourceDigitalOceanVolumeCreate(d *schema.ResourceData, meta interface{}) } log.Printf("[DEBUG] Volume create configuration: %#v", opts) - volume, _, err := client.Storage.CreateVolume(opts) + volume, _, err := client.Storage.CreateVolume(context.Background(), opts) if err != nil { return fmt.Errorf("Error creating Volume: %s", err) } @@ -81,7 +82,7 @@ func resourceDigitalOceanVolumeCreate(d *schema.ResourceData, meta interface{}) func resourceDigitalOceanVolumeRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*godo.Client) - volume, resp, err := client.Storage.GetVolume(d.Id()) + volume, resp, err := client.Storage.GetVolume(context.Background(), d.Id()) if err != nil { // If the volume is somehow already destroyed, mark as // successfully gone @@ -111,7 +112,7 @@ func resourceDigitalOceanVolumeDelete(d *schema.ResourceData, meta interface{}) client := meta.(*godo.Client) log.Printf("[INFO] Deleting volume: %s", d.Id()) - _, err := client.Storage.DeleteVolume(d.Id()) + _, err := client.Storage.DeleteVolume(context.Background(), d.Id()) if err != nil { return fmt.Errorf("Error deleting volume: %s", err) } @@ -122,7 +123,7 @@ func resourceDigitalOceanVolumeDelete(d *schema.ResourceData, meta interface{}) func resourceDigitalOceanVolumeImport(rs *schema.ResourceData, v interface{}) ([]*schema.ResourceData, error) { client := v.(*godo.Client) - volume, _, err := client.Storage.GetVolume(rs.Id()) + volume, _, err := client.Storage.GetVolume(context.Background(), rs.Id()) if err != nil { return nil, err } diff --git a/builtin/providers/digitalocean/resource_digitalocean_volume_test.go b/builtin/providers/digitalocean/resource_digitalocean_volume_test.go index 4a27d75bf..be876ab93 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_volume_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_volume_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "testing" @@ -60,7 +61,7 @@ func testAccCheckDigitalOceanVolumeExists(rn string, volume *godo.Volume) resour client := testAccProvider.Meta().(*godo.Client) - got, _, err := client.Storage.GetVolume(rs.Primary.ID) + got, _, err := client.Storage.GetVolume(context.Background(), rs.Primary.ID) if err != nil { return err } @@ -82,7 +83,7 @@ func testAccCheckDigitalOceanVolumeDestroy(s *terraform.State) error { } // Try to find the volume - _, _, err := client.Storage.GetVolume(rs.Primary.ID) + _, _, err := client.Storage.GetVolume(context.Background(), rs.Primary.ID) if err == nil { return fmt.Errorf("Volume still exists") diff --git a/builtin/providers/digitalocean/tags.go b/builtin/providers/digitalocean/tags.go index e2f37d21e..e3a990e79 100644 --- a/builtin/providers/digitalocean/tags.go +++ b/builtin/providers/digitalocean/tags.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "log" "github.com/digitalocean/godo" @@ -15,7 +16,7 @@ func setTags(conn *godo.Client, d *schema.ResourceData) error { log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id()) for _, tag := range remove { - _, err := conn.Tags.UntagResources(tag, &godo.UntagResourcesRequest{ + _, err := conn.Tags.UntagResources(context.Background(), tag, &godo.UntagResourcesRequest{ Resources: []godo.Resource{ { ID: d.Id(), @@ -30,7 +31,7 @@ func setTags(conn *godo.Client, d *schema.ResourceData) error { log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) for _, tag := range create { - _, err := conn.Tags.TagResources(tag, &godo.TagResourcesRequest{ + _, err := conn.Tags.TagResources(context.Background(), tag, &godo.TagResourcesRequest{ Resources: []godo.Resource{ { ID: d.Id(), diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md new file mode 100644 index 000000000..71886a354 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +## [v1.0.0] - 2017-03-10 + +### Added +- #130 Add Convert to ImageActionsService. - @xmudrii +- #126 Add CertificatesService for managing certificates with the DigitalOcean API. - @viola +- #125 Add LoadBalancersService for managing load balancers with the DigitalOcean API. - @viola +- #122 Add GetVolumeByName to StorageService. - @protochron +- #113 Add context.Context to all calls. - @aybabtme diff --git a/vendor/github.com/digitalocean/godo/README.md b/vendor/github.com/digitalocean/godo/README.md index 03d0c0768..4d5cdf83e 100644 --- a/vendor/github.com/digitalocean/godo/README.md +++ b/vendor/github.com/digitalocean/godo/README.md @@ -65,7 +65,9 @@ createRequest := &godo.DropletCreateRequest{ }, } -newDroplet, _, err := client.Droplets.Create(createRequest) +ctx := context.TODO() + +newDroplet, _, err := client.Droplets.Create(ctx, createRequest) if err != nil { fmt.Printf("Something bad happened: %s\n\n", err) @@ -78,14 +80,14 @@ if err != nil { If a list of items is paginated by the API, you must request pages individually. For example, to fetch all Droplets: ```go -func DropletList(client *godo.Client) ([]godo.Droplet, error) { +func DropletList(ctx context.Context, client *godo.Client) ([]godo.Droplet, error) { // create a list to hold our droplets list := []godo.Droplet{} // create options. initially, these will be blank opt := &godo.ListOptions{} for { - droplets, resp, err := client.Droplets.List(opt) + droplets, resp, err := client.Droplets.List(ctx, opt) if err != nil { return nil, err } diff --git a/vendor/github.com/digitalocean/godo/account.go b/vendor/github.com/digitalocean/godo/account.go index 3c2a1c3af..b68ff52dc 100644 --- a/vendor/github.com/digitalocean/godo/account.go +++ b/vendor/github.com/digitalocean/godo/account.go @@ -1,10 +1,12 @@ package godo +import "github.com/digitalocean/godo/context" + // AccountService is an interface for interfacing with the Account // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2/#account type AccountService interface { - Get() (*Account, *Response, error) + Get(context.Context) (*Account, *Response, error) } // AccountServiceOp handles communication with the Account related methods of @@ -35,16 +37,17 @@ func (r Account) String() string { } // Get DigitalOcean account info -func (s *AccountServiceOp) Get() (*Account, *Response, error) { +func (s *AccountServiceOp) Get(ctx context.Context) (*Account, *Response, error) { + path := "v2/account" - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(accountRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/action.go b/vendor/github.com/digitalocean/godo/action.go index 1ca5904e6..05cd97c16 100644 --- a/vendor/github.com/digitalocean/godo/action.go +++ b/vendor/github.com/digitalocean/godo/action.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const ( actionsBasePath = "v2/actions" @@ -15,8 +19,8 @@ const ( // ActionsService handles communction with action related methods of the // DigitalOcean API: https://developers.digitalocean.com/documentation/v2#actions type ActionsService interface { - List(*ListOptions) ([]Action, *Response, error) - Get(int) (*Action, *Response, error) + List(context.Context, *ListOptions) ([]Action, *Response, error) + Get(context.Context, int) (*Action, *Response, error) } // ActionsServiceOp handles communition with the image action related methods of the @@ -50,20 +54,20 @@ type Action struct { } // List all actions -func (s *ActionsServiceOp) List(opt *ListOptions) ([]Action, *Response, error) { +func (s *ActionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Action, *Response, error) { path := actionsBasePath path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -75,19 +79,19 @@ func (s *ActionsServiceOp) List(opt *ListOptions) ([]Action, *Response, error) { } // Get an action by ID. -func (s *ActionsServiceOp) Get(id int) (*Action, *Response, error) { +func (s *ActionsServiceOp) Get(ctx context.Context, id int) (*Action, *Response, error) { if id < 1 { return nil, nil, NewArgError("id", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", actionsBasePath, id) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/certificates.go b/vendor/github.com/digitalocean/godo/certificates.go new file mode 100644 index 000000000..f7d8c06c5 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/certificates.go @@ -0,0 +1,121 @@ +package godo + +import ( + "path" + + "github.com/digitalocean/godo/context" +) + +const certificatesBasePath = "/v2/certificates" + +// CertificatesService is an interface for managing certificates with the DigitalOcean API. +// See: https://developers.digitalocean.com/documentation/v2/#certificates +type CertificatesService interface { + Get(context.Context, string) (*Certificate, *Response, error) + List(context.Context, *ListOptions) ([]Certificate, *Response, error) + Create(context.Context, *CertificateRequest) (*Certificate, *Response, error) + Delete(context.Context, string) (*Response, error) +} + +// Certificate represents a DigitalOcean certificate configuration. +type Certificate struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + NotAfter string `json:"not_after,omitempty"` + SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"` + Created string `json:"created_at,omitempty"` +} + +// CertificateRequest represents configuration for a new certificate. +type CertificateRequest struct { + Name string `json:"name,omitempty"` + PrivateKey string `json:"private_key,omitempty"` + LeafCertificate string `json:"leaf_certificate,omitempty"` + CertificateChain string `json:"certificate_chain,omitempty"` +} + +type certificateRoot struct { + Certificate *Certificate `json:"certificate"` +} + +type certificatesRoot struct { + Certificates []Certificate `json:"certificates"` + Links *Links `json:"links"` +} + +// CertificatesServiceOp handles communication with certificates methods of the DigitalOcean API. +type CertificatesServiceOp struct { + client *Client +} + +var _ CertificatesService = &CertificatesServiceOp{} + +// Get an existing certificate by its identifier. +func (c *CertificatesServiceOp) Get(ctx context.Context, cID string) (*Certificate, *Response, error) { + urlStr := path.Join(certificatesBasePath, cID) + + req, err := c.client.NewRequest(ctx, "GET", urlStr, nil) + if err != nil { + return nil, nil, err + } + + root := new(certificateRoot) + resp, err := c.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Certificate, resp, nil +} + +// List all certificates. +func (c *CertificatesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Certificate, *Response, error) { + urlStr, err := addOptions(certificatesBasePath, opt) + if err != nil { + return nil, nil, err + } + + req, err := c.client.NewRequest(ctx, "GET", urlStr, nil) + if err != nil { + return nil, nil, err + } + + root := new(certificatesRoot) + resp, err := c.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Certificates, resp, nil +} + +// Create a new certificate with provided configuration. +func (c *CertificatesServiceOp) Create(ctx context.Context, cr *CertificateRequest) (*Certificate, *Response, error) { + req, err := c.client.NewRequest(ctx, "POST", certificatesBasePath, cr) + if err != nil { + return nil, nil, err + } + + root := new(certificateRoot) + resp, err := c.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Certificate, resp, nil +} + +// Delete a certificate by its identifier. +func (c *CertificatesServiceOp) Delete(ctx context.Context, cID string) (*Response, error) { + urlStr := path.Join(certificatesBasePath, cID) + + req, err := c.client.NewRequest(ctx, "DELETE", urlStr, nil) + if err != nil { + return nil, err + } + + return c.client.Do(ctx, req, nil) +} diff --git a/vendor/github.com/digitalocean/godo/context/context.go b/vendor/github.com/digitalocean/godo/context/context.go new file mode 100644 index 000000000..fe49b8dfc --- /dev/null +++ b/vendor/github.com/digitalocean/godo/context/context.go @@ -0,0 +1,98 @@ +package context + +import "time" + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + // + // WithCancel arranges for Done to be closed when cancel is called; + // WithDeadline arranges for Done to be closed when the deadline + // expires; WithTimeout arranges for Done to be closed when the timeout + // elapses. + // + // Done is provided for use in select statements:s + // + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out chan<- Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } + // + // See http://blog.golang.org/pipelines for more examples of how to use + // a Done channel for cancelation. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + // + // A key identifies a specific value in a Context. Functions that wish + // to store values in Context typically allocate a key in a global + // variable then use that key as the argument to context.WithValue and + // Context.Value. A key can be any type that supports equality; + // packages should define keys as an unexported type to avoid + // collisions. + // + // Packages that define a Context key should provide type-safe accessors + // for the values stores using that key: + // + // // Package user defines a User type that's stored in Contexts. + // package user + // + // import "golang.org/x/net/context" + // + // // User is the type of value stored in the Contexts. + // type User struct {...} + // + // // key is an unexported type for keys defined in this package. + // // This prevents collisions with keys defined in other packages. + // type key int + // + // // userKey is the key for user.User values in Contexts. It is + // // unexported; clients use user.NewContext and user.FromContext + // // instead of using this key directly. + // var userKey key = 0 + // + // // NewContext returns a new Context that carries value u. + // func NewContext(ctx context.Context, u *User) context.Context { + // return context.WithValue(ctx, userKey, u) + // } + // + // // FromContext returns the User value stored in ctx, if any. + // func FromContext(ctx context.Context) (*User, bool) { + // u, ok := ctx.Value(userKey).(*User) + // return u, ok + // } + Value(key interface{}) interface{} +} diff --git a/vendor/github.com/digitalocean/godo/context/context_go17.go b/vendor/github.com/digitalocean/godo/context/context_go17.go new file mode 100644 index 000000000..d5359dedb --- /dev/null +++ b/vendor/github.com/digitalocean/godo/context/context_go17.go @@ -0,0 +1,39 @@ +// +build go1.7 + +package context + +import ( + "context" + "net/http" +) + +// DoRequest submits an HTTP request. +func DoRequest(ctx Context, req *http.Request) (*http.Response, error) { + return DoRequestWithClient(ctx, http.DefaultClient, req) +} + +// DoRequestWithClient submits an HTTP request using the specified client. +func DoRequestWithClient( + ctx Context, + client *http.Client, + req *http.Request) (*http.Response, error) { + req = req.WithContext(ctx) + return client.Do(req) +} + +// TODO returns a non-nil, empty Context. Code should use context.TODO when +// it's unclear which Context to use or it is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). TODO is recognized by static analysis tools that determine +// whether Contexts are propagated correctly in a program. +func TODO() Context { + return context.TODO() +} + +// Background returns a non-nil, empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +func Background() Context { + return context.Background() +} diff --git a/vendor/github.com/digitalocean/godo/context/context_pre_go17.go b/vendor/github.com/digitalocean/godo/context/context_pre_go17.go new file mode 100644 index 000000000..e30adb0cb --- /dev/null +++ b/vendor/github.com/digitalocean/godo/context/context_pre_go17.go @@ -0,0 +1,41 @@ +// +build !go1.7 + +package context + +import ( + "net/http" + + "golang.org/x/net/context" + "golang.org/x/net/context/ctxhttp" +) + +// DoRequest submits an HTTP request. +func DoRequest(ctx Context, req *http.Request) (*http.Response, error) { + return DoRequestWithClient(ctx, http.DefaultClient, req) +} + +// DoRequestWithClient submits an HTTP request using the specified client. +func DoRequestWithClient( + ctx Context, + client *http.Client, + req *http.Request) (*http.Response, error) { + + return ctxhttp.Do(ctx, client, req) +} + +// TODO returns a non-nil, empty Context. Code should use context.TODO when +// it's unclear which Context to use or it is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). TODO is recognized by static analysis tools that determine +// whether Contexts are propagated correctly in a program. +func TODO() Context { + return context.TODO() +} + +// Background returns a non-nil, empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +func Background() Context { + return context.Background() +} diff --git a/vendor/github.com/digitalocean/godo/domains.go b/vendor/github.com/digitalocean/godo/domains.go index 31de17868..542a27b20 100644 --- a/vendor/github.com/digitalocean/godo/domains.go +++ b/vendor/github.com/digitalocean/godo/domains.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const domainsBasePath = "v2/domains" @@ -8,16 +12,16 @@ const domainsBasePath = "v2/domains" // See: https://developers.digitalocean.com/documentation/v2#domains and // https://developers.digitalocean.com/documentation/v2#domain-records type DomainsService interface { - List(*ListOptions) ([]Domain, *Response, error) - Get(string) (*Domain, *Response, error) - Create(*DomainCreateRequest) (*Domain, *Response, error) - Delete(string) (*Response, error) + List(context.Context, *ListOptions) ([]Domain, *Response, error) + Get(context.Context, string) (*Domain, *Response, error) + Create(context.Context, *DomainCreateRequest) (*Domain, *Response, error) + Delete(context.Context, string) (*Response, error) - Records(string, *ListOptions) ([]DomainRecord, *Response, error) - Record(string, int) (*DomainRecord, *Response, error) - DeleteRecord(string, int) (*Response, error) - EditRecord(string, int, *DomainRecordEditRequest) (*DomainRecord, *Response, error) - CreateRecord(string, *DomainRecordEditRequest) (*DomainRecord, *Response, error) + Records(context.Context, string, *ListOptions) ([]DomainRecord, *Response, error) + Record(context.Context, string, int) (*DomainRecord, *Response, error) + DeleteRecord(context.Context, string, int) (*Response, error) + EditRecord(context.Context, string, int, *DomainRecordEditRequest) (*DomainRecord, *Response, error) + CreateRecord(context.Context, string, *DomainRecordEditRequest) (*DomainRecord, *Response, error) } // DomainsServiceOp handles communication with the domain related methods of the @@ -70,6 +74,7 @@ type DomainRecord struct { Data string `json:"data,omitempty"` Priority int `json:"priority,omitempty"` Port int `json:"port,omitempty"` + TTL int `json:"ttl,omitempty"` Weight int `json:"weight,omitempty"` } @@ -80,6 +85,7 @@ type DomainRecordEditRequest struct { Data string `json:"data,omitempty"` Priority int `json:"priority,omitempty"` Port int `json:"port,omitempty"` + TTL int `json:"ttl,omitempty"` Weight int `json:"weight,omitempty"` } @@ -88,20 +94,20 @@ func (d Domain) String() string { } // List all domains. -func (s DomainsServiceOp) List(opt *ListOptions) ([]Domain, *Response, error) { +func (s DomainsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Domain, *Response, error) { path := domainsBasePath path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(domainsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -113,20 +119,20 @@ func (s DomainsServiceOp) List(opt *ListOptions) ([]Domain, *Response, error) { } // Get individual domain. It requires a non-empty domain name. -func (s *DomainsServiceOp) Get(name string) (*Domain, *Response, error) { +func (s *DomainsServiceOp) Get(ctx context.Context, name string) (*Domain, *Response, error) { if len(name) < 1 { return nil, nil, NewArgError("name", "cannot be an empty string") } path := fmt.Sprintf("%s/%s", domainsBasePath, name) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(domainRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -135,20 +141,20 @@ func (s *DomainsServiceOp) Get(name string) (*Domain, *Response, error) { } // Create a new domain -func (s *DomainsServiceOp) Create(createRequest *DomainCreateRequest) (*Domain, *Response, error) { +func (s *DomainsServiceOp) Create(ctx context.Context, createRequest *DomainCreateRequest) (*Domain, *Response, error) { if createRequest == nil { return nil, nil, NewArgError("createRequest", "cannot be nil") } path := domainsBasePath - req, err := s.client.NewRequest("POST", path, createRequest) + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(domainRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -156,19 +162,19 @@ func (s *DomainsServiceOp) Create(createRequest *DomainCreateRequest) (*Domain, } // Delete domain -func (s *DomainsServiceOp) Delete(name string) (*Response, error) { +func (s *DomainsServiceOp) Delete(ctx context.Context, name string) (*Response, error) { if len(name) < 1 { return nil, NewArgError("name", "cannot be an empty string") } path := fmt.Sprintf("%s/%s", domainsBasePath, name) - req, err := s.client.NewRequest("DELETE", path, nil) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } @@ -184,7 +190,7 @@ func (d DomainRecordEditRequest) String() string { } // Records returns a slice of DomainRecords for a domain -func (s *DomainsServiceOp) Records(domain string, opt *ListOptions) ([]DomainRecord, *Response, error) { +func (s *DomainsServiceOp) Records(ctx context.Context, domain string, opt *ListOptions) ([]DomainRecord, *Response, error) { if len(domain) < 1 { return nil, nil, NewArgError("domain", "cannot be an empty string") } @@ -195,13 +201,13 @@ func (s *DomainsServiceOp) Records(domain string, opt *ListOptions) ([]DomainRec return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(domainRecordsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -213,7 +219,7 @@ func (s *DomainsServiceOp) Records(domain string, opt *ListOptions) ([]DomainRec } // Record returns the record id from a domain -func (s *DomainsServiceOp) Record(domain string, id int) (*DomainRecord, *Response, error) { +func (s *DomainsServiceOp) Record(ctx context.Context, domain string, id int) (*DomainRecord, *Response, error) { if len(domain) < 1 { return nil, nil, NewArgError("domain", "cannot be an empty string") } @@ -224,13 +230,13 @@ func (s *DomainsServiceOp) Record(domain string, id int) (*DomainRecord, *Respon path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } record := new(domainRecordRoot) - resp, err := s.client.Do(req, record) + resp, err := s.client.Do(ctx, req, record) if err != nil { return nil, resp, err } @@ -239,7 +245,7 @@ func (s *DomainsServiceOp) Record(domain string, id int) (*DomainRecord, *Respon } // DeleteRecord deletes a record from a domain identified by id -func (s *DomainsServiceOp) DeleteRecord(domain string, id int) (*Response, error) { +func (s *DomainsServiceOp) DeleteRecord(ctx context.Context, domain string, id int) (*Response, error) { if len(domain) < 1 { return nil, NewArgError("domain", "cannot be an empty string") } @@ -250,18 +256,18 @@ func (s *DomainsServiceOp) DeleteRecord(domain string, id int) (*Response, error path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - req, err := s.client.NewRequest("DELETE", path, nil) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // EditRecord edits a record using a DomainRecordEditRequest -func (s *DomainsServiceOp) EditRecord( +func (s *DomainsServiceOp) EditRecord(ctx context.Context, domain string, id int, editRequest *DomainRecordEditRequest, @@ -280,13 +286,13 @@ func (s *DomainsServiceOp) EditRecord( path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id) - req, err := s.client.NewRequest("PUT", path, editRequest) + req, err := s.client.NewRequest(ctx, "PUT", path, editRequest) if err != nil { return nil, nil, err } d := new(DomainRecord) - resp, err := s.client.Do(req, d) + resp, err := s.client.Do(ctx, req, d) if err != nil { return nil, resp, err } @@ -295,7 +301,7 @@ func (s *DomainsServiceOp) EditRecord( } // CreateRecord creates a record using a DomainRecordEditRequest -func (s *DomainsServiceOp) CreateRecord( +func (s *DomainsServiceOp) CreateRecord(ctx context.Context, domain string, createRequest *DomainRecordEditRequest) (*DomainRecord, *Response, error) { if len(domain) < 1 { @@ -307,14 +313,14 @@ func (s *DomainsServiceOp) CreateRecord( } path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain) - req, err := s.client.NewRequest("POST", path, createRequest) + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } d := new(domainRecordRoot) - resp, err := s.client.Do(req, d) + resp, err := s.client.Do(ctx, req, d) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/droplet_actions.go b/vendor/github.com/digitalocean/godo/droplet_actions.go index eebcf7afc..7cc0d0852 100644 --- a/vendor/github.com/digitalocean/godo/droplet_actions.go +++ b/vendor/github.com/digitalocean/godo/droplet_actions.go @@ -3,6 +3,8 @@ package godo import ( "fmt" "net/url" + + "github.com/digitalocean/godo/context" ) // ActionRequest reprents DigitalOcean Action Request @@ -12,35 +14,35 @@ type ActionRequest map[string]interface{} // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#droplet-actions type DropletActionsService interface { - Shutdown(int) (*Action, *Response, error) - ShutdownByTag(string) (*Action, *Response, error) - PowerOff(int) (*Action, *Response, error) - PowerOffByTag(string) (*Action, *Response, error) - PowerOn(int) (*Action, *Response, error) - PowerOnByTag(string) (*Action, *Response, error) - PowerCycle(int) (*Action, *Response, error) - PowerCycleByTag(string) (*Action, *Response, error) - Reboot(int) (*Action, *Response, error) - Restore(int, int) (*Action, *Response, error) - Resize(int, string, bool) (*Action, *Response, error) - Rename(int, string) (*Action, *Response, error) - Snapshot(int, string) (*Action, *Response, error) - SnapshotByTag(string, string) (*Action, *Response, error) - EnableBackups(int) (*Action, *Response, error) - EnableBackupsByTag(string) (*Action, *Response, error) - DisableBackups(int) (*Action, *Response, error) - DisableBackupsByTag(string) (*Action, *Response, error) - PasswordReset(int) (*Action, *Response, error) - RebuildByImageID(int, int) (*Action, *Response, error) - RebuildByImageSlug(int, string) (*Action, *Response, error) - ChangeKernel(int, int) (*Action, *Response, error) - EnableIPv6(int) (*Action, *Response, error) - EnableIPv6ByTag(string) (*Action, *Response, error) - EnablePrivateNetworking(int) (*Action, *Response, error) - EnablePrivateNetworkingByTag(string) (*Action, *Response, error) - Upgrade(int) (*Action, *Response, error) - Get(int, int) (*Action, *Response, error) - GetByURI(string) (*Action, *Response, error) + Shutdown(context.Context, int) (*Action, *Response, error) + ShutdownByTag(context.Context, string) (*Action, *Response, error) + PowerOff(context.Context, int) (*Action, *Response, error) + PowerOffByTag(context.Context, string) (*Action, *Response, error) + PowerOn(context.Context, int) (*Action, *Response, error) + PowerOnByTag(context.Context, string) (*Action, *Response, error) + PowerCycle(context.Context, int) (*Action, *Response, error) + PowerCycleByTag(context.Context, string) (*Action, *Response, error) + Reboot(context.Context, int) (*Action, *Response, error) + Restore(context.Context, int, int) (*Action, *Response, error) + Resize(context.Context, int, string, bool) (*Action, *Response, error) + Rename(context.Context, int, string) (*Action, *Response, error) + Snapshot(context.Context, int, string) (*Action, *Response, error) + SnapshotByTag(context.Context, string, string) (*Action, *Response, error) + EnableBackups(context.Context, int) (*Action, *Response, error) + EnableBackupsByTag(context.Context, string) (*Action, *Response, error) + DisableBackups(context.Context, int) (*Action, *Response, error) + DisableBackupsByTag(context.Context, string) (*Action, *Response, error) + PasswordReset(context.Context, int) (*Action, *Response, error) + RebuildByImageID(context.Context, int, int) (*Action, *Response, error) + RebuildByImageSlug(context.Context, int, string) (*Action, *Response, error) + ChangeKernel(context.Context, int, int) (*Action, *Response, error) + EnableIPv6(context.Context, int) (*Action, *Response, error) + EnableIPv6ByTag(context.Context, string) (*Action, *Response, error) + EnablePrivateNetworking(context.Context, int) (*Action, *Response, error) + EnablePrivateNetworkingByTag(context.Context, string) (*Action, *Response, error) + Upgrade(context.Context, int) (*Action, *Response, error) + Get(context.Context, int, int) (*Action, *Response, error) + GetByURI(context.Context, string) (*Action, *Response, error) } // DropletActionsServiceOp handles communication with the Droplet action related @@ -52,189 +54,189 @@ type DropletActionsServiceOp struct { var _ DropletActionsService = &DropletActionsServiceOp{} // Shutdown a Droplet -func (s *DropletActionsServiceOp) Shutdown(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Shutdown(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "shutdown"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // ShutdownByTag shuts down Droplets matched by a Tag. -func (s *DropletActionsServiceOp) ShutdownByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) ShutdownByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "shutdown"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // PowerOff a Droplet -func (s *DropletActionsServiceOp) PowerOff(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerOff(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "power_off"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // PowerOffByTag powers off Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerOffByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerOffByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "power_off"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // PowerOn a Droplet -func (s *DropletActionsServiceOp) PowerOn(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerOn(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "power_on"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // PowerOnByTag powers on Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerOnByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerOnByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "power_on"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // PowerCycle a Droplet -func (s *DropletActionsServiceOp) PowerCycle(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerCycle(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "power_cycle"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // PowerCycleByTag power cycles Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerCycleByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PowerCycleByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "power_cycle"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // Reboot a Droplet -func (s *DropletActionsServiceOp) Reboot(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Reboot(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "reboot"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // Restore an image to a Droplet -func (s *DropletActionsServiceOp) Restore(id, imageID int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Restore(ctx context.Context, id, imageID int) (*Action, *Response, error) { requestType := "restore" request := &ActionRequest{ "type": requestType, "image": float64(imageID), } - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // Resize a Droplet -func (s *DropletActionsServiceOp) Resize(id int, sizeSlug string, resizeDisk bool) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Resize(ctx context.Context, id int, sizeSlug string, resizeDisk bool) (*Action, *Response, error) { requestType := "resize" request := &ActionRequest{ "type": requestType, "size": sizeSlug, "disk": resizeDisk, } - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // Rename a Droplet -func (s *DropletActionsServiceOp) Rename(id int, name string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Rename(ctx context.Context, id int, name string) (*Action, *Response, error) { requestType := "rename" request := &ActionRequest{ "type": requestType, "name": name, } - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // Snapshot a Droplet. -func (s *DropletActionsServiceOp) Snapshot(id int, name string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Snapshot(ctx context.Context, id int, name string) (*Action, *Response, error) { requestType := "snapshot" request := &ActionRequest{ "type": requestType, "name": name, } - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // SnapshotByTag snapshots Droplets matched by a Tag. -func (s *DropletActionsServiceOp) SnapshotByTag(tag string, name string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) SnapshotByTag(ctx context.Context, tag string, name string) (*Action, *Response, error) { requestType := "snapshot" request := &ActionRequest{ "type": requestType, "name": name, } - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // EnableBackups enables backups for a Droplet. -func (s *DropletActionsServiceOp) EnableBackups(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnableBackups(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_backups"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // EnableBackupsByTag enables backups for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnableBackupsByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnableBackupsByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_backups"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // DisableBackups disables backups for a Droplet. -func (s *DropletActionsServiceOp) DisableBackups(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) DisableBackups(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "disable_backups"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // DisableBackupsByTag disables backups for Droplet matched by a Tag. -func (s *DropletActionsServiceOp) DisableBackupsByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) DisableBackupsByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "disable_backups"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // PasswordReset resets the password for a Droplet. -func (s *DropletActionsServiceOp) PasswordReset(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) PasswordReset(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "password_reset"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // RebuildByImageID rebuilds a Droplet from an image with a given id. -func (s *DropletActionsServiceOp) RebuildByImageID(id, imageID int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) RebuildByImageID(ctx context.Context, id, imageID int) (*Action, *Response, error) { request := &ActionRequest{"type": "rebuild", "image": imageID} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // RebuildByImageSlug rebuilds a Droplet from an Image matched by a given Slug. -func (s *DropletActionsServiceOp) RebuildByImageSlug(id int, slug string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) RebuildByImageSlug(ctx context.Context, id int, slug string) (*Action, *Response, error) { request := &ActionRequest{"type": "rebuild", "image": slug} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // ChangeKernel changes the kernel for a Droplet. -func (s *DropletActionsServiceOp) ChangeKernel(id, kernelID int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) ChangeKernel(ctx context.Context, id, kernelID int) (*Action, *Response, error) { request := &ActionRequest{"type": "change_kernel", "kernel": kernelID} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // EnableIPv6 enables IPv6 for a Droplet. -func (s *DropletActionsServiceOp) EnableIPv6(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnableIPv6(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_ipv6"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // EnableIPv6ByTag enables IPv6 for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnableIPv6ByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnableIPv6ByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_ipv6"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // EnablePrivateNetworking enables private networking for a Droplet. -func (s *DropletActionsServiceOp) EnablePrivateNetworking(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnablePrivateNetworking(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_private_networking"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } // EnablePrivateNetworkingByTag enables private networking for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnablePrivateNetworkingByTag(tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) EnablePrivateNetworkingByTag(ctx context.Context, tag string) (*Action, *Response, error) { request := &ActionRequest{"type": "enable_private_networking"} - return s.doActionByTag(tag, request) + return s.doActionByTag(ctx, tag, request) } // Upgrade a Droplet. -func (s *DropletActionsServiceOp) Upgrade(id int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Upgrade(ctx context.Context, id int) (*Action, *Response, error) { request := &ActionRequest{"type": "upgrade"} - return s.doAction(id, request) + return s.doAction(ctx, id, request) } -func (s *DropletActionsServiceOp) doAction(id int, request *ActionRequest) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) doAction(ctx context.Context, id int, request *ActionRequest) (*Action, *Response, error) { if id < 1 { return nil, nil, NewArgError("id", "cannot be less than 1") } @@ -245,13 +247,13 @@ func (s *DropletActionsServiceOp) doAction(id int, request *ActionRequest) (*Act path := dropletActionPath(id) - req, err := s.client.NewRequest("POST", path, request) + req, err := s.client.NewRequest(ctx, "POST", path, request) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -259,7 +261,7 @@ func (s *DropletActionsServiceOp) doAction(id int, request *ActionRequest) (*Act return root.Event, resp, err } -func (s *DropletActionsServiceOp) doActionByTag(tag string, request *ActionRequest) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, tag string, request *ActionRequest) (*Action, *Response, error) { if tag == "" { return nil, nil, NewArgError("tag", "cannot be empty") } @@ -270,13 +272,13 @@ func (s *DropletActionsServiceOp) doActionByTag(tag string, request *ActionReque path := dropletActionPathByTag(tag) - req, err := s.client.NewRequest("POST", path, request) + req, err := s.client.NewRequest(ctx, "POST", path, request) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -285,7 +287,7 @@ func (s *DropletActionsServiceOp) doActionByTag(tag string, request *ActionReque } // Get an action for a particular Droplet by id. -func (s *DropletActionsServiceOp) Get(dropletID, actionID int) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) Get(ctx context.Context, dropletID, actionID int) (*Action, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } @@ -295,28 +297,28 @@ func (s *DropletActionsServiceOp) Get(dropletID, actionID int) (*Action, *Respon } path := fmt.Sprintf("%s/%d", dropletActionPath(dropletID), actionID) - return s.get(path) + return s.get(ctx, path) } // GetByURI gets an action for a particular Droplet by id. -func (s *DropletActionsServiceOp) GetByURI(rawurl string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (*Action, *Response, error) { u, err := url.Parse(rawurl) if err != nil { return nil, nil, err } - return s.get(u.Path) + return s.get(ctx, u.Path) } -func (s *DropletActionsServiceOp) get(path string) (*Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *DropletActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/droplets.go b/vendor/github.com/digitalocean/godo/droplets.go index 15bb12609..443d5dbb1 100644 --- a/vendor/github.com/digitalocean/godo/droplets.go +++ b/vendor/github.com/digitalocean/godo/droplets.go @@ -4,6 +4,8 @@ import ( "encoding/json" "errors" "fmt" + + "github.com/digitalocean/godo/context" ) const dropletBasePath = "v2/droplets" @@ -14,18 +16,18 @@ var errNoNetworks = errors.New("no networks have been defined") // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#droplets type DropletsService interface { - List(*ListOptions) ([]Droplet, *Response, error) - ListByTag(string, *ListOptions) ([]Droplet, *Response, error) - Get(int) (*Droplet, *Response, error) - Create(*DropletCreateRequest) (*Droplet, *Response, error) - CreateMultiple(*DropletMultiCreateRequest) ([]Droplet, *Response, error) - Delete(int) (*Response, error) - DeleteByTag(string) (*Response, error) - Kernels(int, *ListOptions) ([]Kernel, *Response, error) - Snapshots(int, *ListOptions) ([]Image, *Response, error) - Backups(int, *ListOptions) ([]Image, *Response, error) - Actions(int, *ListOptions) ([]Action, *Response, error) - Neighbors(int) ([]Droplet, *Response, error) + List(context.Context, *ListOptions) ([]Droplet, *Response, error) + ListByTag(context.Context, string, *ListOptions) ([]Droplet, *Response, error) + Get(context.Context, int) (*Droplet, *Response, error) + Create(context.Context, *DropletCreateRequest) (*Droplet, *Response, error) + CreateMultiple(context.Context, *DropletMultiCreateRequest) ([]Droplet, *Response, error) + Delete(context.Context, int) (*Response, error) + DeleteByTag(context.Context, string) (*Response, error) + Kernels(context.Context, int, *ListOptions) ([]Kernel, *Response, error) + Snapshots(context.Context, int, *ListOptions) ([]Image, *Response, error) + Backups(context.Context, int, *ListOptions) ([]Image, *Response, error) + Actions(context.Context, int, *ListOptions) ([]Action, *Response, error) + Neighbors(context.Context, int) ([]Droplet, *Response, error) } // DropletsServiceOp handles communication with the Droplet related methods of the @@ -90,15 +92,15 @@ func (d *Droplet) PrivateIPv4() (string, error) { return "", nil } -// PublicIPv6 returns the private IPv6 address for the Droplet. +// PublicIPv6 returns the public IPv6 address for the Droplet. func (d *Droplet) PublicIPv6() (string, error) { if d.Networks == nil { return "", errNoNetworks } - for _, v4 := range d.Networks.V6 { - if v4.Type == "public" { - return v4.IPAddress, nil + for _, v6 := range d.Networks.V6 { + if v6.Type == "public" { + return v6.IPAddress, nil } } @@ -272,14 +274,14 @@ func (n NetworkV6) String() string { } // Performs a list request given a path. -func (s *DropletsServiceOp) list(path string) ([]Droplet, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *DropletsServiceOp) list(ctx context.Context, path string) ([]Droplet, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(dropletsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -291,42 +293,42 @@ func (s *DropletsServiceOp) list(path string) ([]Droplet, *Response, error) { } // List all Droplets. -func (s *DropletsServiceOp) List(opt *ListOptions) ([]Droplet, *Response, error) { +func (s *DropletsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Droplet, *Response, error) { path := dropletBasePath path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - return s.list(path) + return s.list(ctx, path) } // ListByTag lists all Droplets matched by a Tag. -func (s *DropletsServiceOp) ListByTag(tag string, opt *ListOptions) ([]Droplet, *Response, error) { +func (s *DropletsServiceOp) ListByTag(ctx context.Context, tag string, opt *ListOptions) ([]Droplet, *Response, error) { path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag) path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - return s.list(path) + return s.list(ctx, path) } // Get individual Droplet. -func (s *DropletsServiceOp) Get(dropletID int) (*Droplet, *Response, error) { +func (s *DropletsServiceOp) Get(ctx context.Context, dropletID int) (*Droplet, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(dropletRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -335,20 +337,20 @@ func (s *DropletsServiceOp) Get(dropletID int) (*Droplet, *Response, error) { } // Create Droplet -func (s *DropletsServiceOp) Create(createRequest *DropletCreateRequest) (*Droplet, *Response, error) { +func (s *DropletsServiceOp) Create(ctx context.Context, createRequest *DropletCreateRequest) (*Droplet, *Response, error) { if createRequest == nil { return nil, nil, NewArgError("createRequest", "cannot be nil") } path := dropletBasePath - req, err := s.client.NewRequest("POST", path, createRequest) + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(dropletRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -360,20 +362,20 @@ func (s *DropletsServiceOp) Create(createRequest *DropletCreateRequest) (*Drople } // CreateMultiple creates multiple Droplets. -func (s *DropletsServiceOp) CreateMultiple(createRequest *DropletMultiCreateRequest) ([]Droplet, *Response, error) { +func (s *DropletsServiceOp) CreateMultiple(ctx context.Context, createRequest *DropletMultiCreateRequest) ([]Droplet, *Response, error) { if createRequest == nil { return nil, nil, NewArgError("createRequest", "cannot be nil") } path := dropletBasePath - req, err := s.client.NewRequest("POST", path, createRequest) + req, err := s.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(dropletsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -385,41 +387,41 @@ func (s *DropletsServiceOp) CreateMultiple(createRequest *DropletMultiCreateRequ } // Performs a delete request given a path -func (s *DropletsServiceOp) delete(path string) (*Response, error) { - req, err := s.client.NewRequest("DELETE", path, nil) +func (s *DropletsServiceOp) delete(ctx context.Context, path string) (*Response, error) { + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // Delete Droplet. -func (s *DropletsServiceOp) Delete(dropletID int) (*Response, error) { +func (s *DropletsServiceOp) Delete(ctx context.Context, dropletID int) (*Response, error) { if dropletID < 1 { return nil, NewArgError("dropletID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID) - return s.delete(path) + return s.delete(ctx, path) } // DeleteByTag deletes Droplets matched by a Tag. -func (s *DropletsServiceOp) DeleteByTag(tag string) (*Response, error) { +func (s *DropletsServiceOp) DeleteByTag(ctx context.Context, tag string) (*Response, error) { if tag == "" { return nil, NewArgError("tag", "cannot be empty") } path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag) - return s.delete(path) + return s.delete(ctx, path) } // Kernels lists kernels available for a Droplet. -func (s *DropletsServiceOp) Kernels(dropletID int, opt *ListOptions) ([]Kernel, *Response, error) { +func (s *DropletsServiceOp) Kernels(ctx context.Context, dropletID int, opt *ListOptions) ([]Kernel, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } @@ -430,13 +432,13 @@ func (s *DropletsServiceOp) Kernels(dropletID int, opt *ListOptions) ([]Kernel, return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(kernelsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if l := root.Links; l != nil { resp.Links = l } @@ -445,7 +447,7 @@ func (s *DropletsServiceOp) Kernels(dropletID int, opt *ListOptions) ([]Kernel, } // Actions lists the actions for a Droplet. -func (s *DropletsServiceOp) Actions(dropletID int, opt *ListOptions) ([]Action, *Response, error) { +func (s *DropletsServiceOp) Actions(ctx context.Context, dropletID int, opt *ListOptions) ([]Action, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } @@ -456,13 +458,13 @@ func (s *DropletsServiceOp) Actions(dropletID int, opt *ListOptions) ([]Action, return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -474,7 +476,7 @@ func (s *DropletsServiceOp) Actions(dropletID int, opt *ListOptions) ([]Action, } // Backups lists the backups for a Droplet. -func (s *DropletsServiceOp) Backups(dropletID int, opt *ListOptions) ([]Image, *Response, error) { +func (s *DropletsServiceOp) Backups(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } @@ -485,13 +487,13 @@ func (s *DropletsServiceOp) Backups(dropletID int, opt *ListOptions) ([]Image, * return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(backupsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -503,7 +505,7 @@ func (s *DropletsServiceOp) Backups(dropletID int, opt *ListOptions) ([]Image, * } // Snapshots lists the snapshots available for a Droplet. -func (s *DropletsServiceOp) Snapshots(dropletID int, opt *ListOptions) ([]Image, *Response, error) { +func (s *DropletsServiceOp) Snapshots(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } @@ -514,13 +516,13 @@ func (s *DropletsServiceOp) Snapshots(dropletID int, opt *ListOptions) ([]Image, return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(dropletSnapshotsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -532,20 +534,20 @@ func (s *DropletsServiceOp) Snapshots(dropletID int, opt *ListOptions) ([]Image, } // Neighbors lists the neighbors for a Droplet. -func (s *DropletsServiceOp) Neighbors(dropletID int) ([]Droplet, *Response, error) { +func (s *DropletsServiceOp) Neighbors(ctx context.Context, dropletID int) ([]Droplet, *Response, error) { if dropletID < 1 { return nil, nil, NewArgError("dropletID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d/neighbors", dropletBasePath, dropletID) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(dropletsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -553,8 +555,8 @@ func (s *DropletsServiceOp) Neighbors(dropletID int) ([]Droplet, *Response, erro return root.Droplets, resp, err } -func (s *DropletsServiceOp) dropletActionStatus(uri string) (string, error) { - action, _, err := s.client.DropletActions.GetByURI(uri) +func (s *DropletsServiceOp) dropletActionStatus(ctx context.Context, uri string) (string, error) { + action, _, err := s.client.DropletActions.GetByURI(ctx, uri) if err != nil { return "", err diff --git a/vendor/github.com/digitalocean/godo/floating_ips.go b/vendor/github.com/digitalocean/godo/floating_ips.go index bad04b96c..032d7e98a 100644 --- a/vendor/github.com/digitalocean/godo/floating_ips.go +++ b/vendor/github.com/digitalocean/godo/floating_ips.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const floatingBasePath = "v2/floating_ips" @@ -8,10 +12,10 @@ const floatingBasePath = "v2/floating_ips" // endpoints of the Digital Ocean API. // See: https://developers.digitalocean.com/documentation/v2#floating-ips type FloatingIPsService interface { - List(*ListOptions) ([]FloatingIP, *Response, error) - Get(string) (*FloatingIP, *Response, error) - Create(*FloatingIPCreateRequest) (*FloatingIP, *Response, error) - Delete(string) (*Response, error) + List(context.Context, *ListOptions) ([]FloatingIP, *Response, error) + Get(context.Context, string) (*FloatingIP, *Response, error) + Create(context.Context, *FloatingIPCreateRequest) (*FloatingIP, *Response, error) + Delete(context.Context, string) (*Response, error) } // FloatingIPsServiceOp handles communication with the floating IPs related methods of the @@ -52,20 +56,20 @@ type FloatingIPCreateRequest struct { } // List all floating IPs. -func (f *FloatingIPsServiceOp) List(opt *ListOptions) ([]FloatingIP, *Response, error) { +func (f *FloatingIPsServiceOp) List(ctx context.Context, opt *ListOptions) ([]FloatingIP, *Response, error) { path := floatingBasePath path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := f.client.NewRequest("GET", path, nil) + req, err := f.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(floatingIPsRoot) - resp, err := f.client.Do(req, root) + resp, err := f.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -77,16 +81,16 @@ func (f *FloatingIPsServiceOp) List(opt *ListOptions) ([]FloatingIP, *Response, } // Get an individual floating IP. -func (f *FloatingIPsServiceOp) Get(ip string) (*FloatingIP, *Response, error) { +func (f *FloatingIPsServiceOp) Get(ctx context.Context, ip string) (*FloatingIP, *Response, error) { path := fmt.Sprintf("%s/%s", floatingBasePath, ip) - req, err := f.client.NewRequest("GET", path, nil) + req, err := f.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(floatingIPRoot) - resp, err := f.client.Do(req, root) + resp, err := f.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -96,16 +100,16 @@ func (f *FloatingIPsServiceOp) Get(ip string) (*FloatingIP, *Response, error) { // Create a floating IP. If the DropletID field of the request is not empty, // the floating IP will also be assigned to the droplet. -func (f *FloatingIPsServiceOp) Create(createRequest *FloatingIPCreateRequest) (*FloatingIP, *Response, error) { +func (f *FloatingIPsServiceOp) Create(ctx context.Context, createRequest *FloatingIPCreateRequest) (*FloatingIP, *Response, error) { path := floatingBasePath - req, err := f.client.NewRequest("POST", path, createRequest) + req, err := f.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(floatingIPRoot) - resp, err := f.client.Do(req, root) + resp, err := f.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -117,15 +121,15 @@ func (f *FloatingIPsServiceOp) Create(createRequest *FloatingIPCreateRequest) (* } // Delete a floating IP. -func (f *FloatingIPsServiceOp) Delete(ip string) (*Response, error) { +func (f *FloatingIPsServiceOp) Delete(ctx context.Context, ip string) (*Response, error) { path := fmt.Sprintf("%s/%s", floatingBasePath, ip) - req, err := f.client.NewRequest("DELETE", path, nil) + req, err := f.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := f.client.Do(req, nil) + resp, err := f.client.Do(ctx, req, nil) return resp, err } diff --git a/vendor/github.com/digitalocean/godo/floating_ips_actions.go b/vendor/github.com/digitalocean/godo/floating_ips_actions.go index bd6fce208..b0ad2165b 100644 --- a/vendor/github.com/digitalocean/godo/floating_ips_actions.go +++ b/vendor/github.com/digitalocean/godo/floating_ips_actions.go @@ -1,15 +1,19 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) // FloatingIPActionsService is an interface for interfacing with the // floating IPs actions endpoints of the Digital Ocean API. // See: https://developers.digitalocean.com/documentation/v2#floating-ips-action type FloatingIPActionsService interface { - Assign(ip string, dropletID int) (*Action, *Response, error) - Unassign(ip string) (*Action, *Response, error) - Get(ip string, actionID int) (*Action, *Response, error) - List(ip string, opt *ListOptions) ([]Action, *Response, error) + Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) + Unassign(ctx context.Context, ip string) (*Action, *Response, error) + Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error) + List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error) } // FloatingIPActionsServiceOp handles communication with the floating IPs @@ -19,47 +23,47 @@ type FloatingIPActionsServiceOp struct { } // Assign a floating IP to a droplet. -func (s *FloatingIPActionsServiceOp) Assign(ip string, dropletID int) (*Action, *Response, error) { +func (s *FloatingIPActionsServiceOp) Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) { request := &ActionRequest{ "type": "assign", "droplet_id": dropletID, } - return s.doAction(ip, request) + return s.doAction(ctx, ip, request) } // Unassign a floating IP from the droplet it is currently assigned to. -func (s *FloatingIPActionsServiceOp) Unassign(ip string) (*Action, *Response, error) { +func (s *FloatingIPActionsServiceOp) Unassign(ctx context.Context, ip string) (*Action, *Response, error) { request := &ActionRequest{"type": "unassign"} - return s.doAction(ip, request) + return s.doAction(ctx, ip, request) } // Get an action for a particular floating IP by id. -func (s *FloatingIPActionsServiceOp) Get(ip string, actionID int) (*Action, *Response, error) { +func (s *FloatingIPActionsServiceOp) Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error) { path := fmt.Sprintf("%s/%d", floatingIPActionPath(ip), actionID) - return s.get(path) + return s.get(ctx, path) } // List the actions for a particular floating IP. -func (s *FloatingIPActionsServiceOp) List(ip string, opt *ListOptions) ([]Action, *Response, error) { +func (s *FloatingIPActionsServiceOp) List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error) { path := floatingIPActionPath(ip) path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - return s.list(path) + return s.list(ctx, path) } -func (s *FloatingIPActionsServiceOp) doAction(ip string, request *ActionRequest) (*Action, *Response, error) { +func (s *FloatingIPActionsServiceOp) doAction(ctx context.Context, ip string, request *ActionRequest) (*Action, *Response, error) { path := floatingIPActionPath(ip) - req, err := s.client.NewRequest("POST", path, request) + req, err := s.client.NewRequest(ctx, "POST", path, request) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -67,14 +71,14 @@ func (s *FloatingIPActionsServiceOp) doAction(ip string, request *ActionRequest) return root.Event, resp, err } -func (s *FloatingIPActionsServiceOp) get(path string) (*Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *FloatingIPActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -82,14 +86,14 @@ func (s *FloatingIPActionsServiceOp) get(path string) (*Action, *Response, error return root.Event, resp, err } -func (s *FloatingIPActionsServiceOp) list(path string) ([]Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *FloatingIPActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index 205f1ff96..5c87c8c09 100644 --- a/vendor/github.com/digitalocean/godo/godo.go +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -14,10 +14,12 @@ import ( "github.com/google/go-querystring/query" headerLink "github.com/tent/http-link-go" + + "github.com/digitalocean/godo/context" ) const ( - libraryVersion = "0.1.0" + libraryVersion = "1.0.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" @@ -60,6 +62,7 @@ type Client struct { StorageActions StorageActionsService Tags TagsService LoadBalancers LoadBalancersService + Certificates CertificatesService // Optional function called after every successful request made to the DO APIs onRequestCompleted RequestCompletionCallback @@ -169,6 +172,7 @@ func NewClient(httpClient *http.Client) *Client { c.StorageActions = &StorageActionsServiceOp{client: c} c.Tags = &TagsServiceOp{client: c} c.LoadBalancers = &LoadBalancersServiceOp{client: c} + c.Certificates = &CertificatesServiceOp{client: c} return c } @@ -212,7 +216,7 @@ func SetUserAgent(ua string) ClientOpt { // NewRequest creates an API request. A relative URL can be provided in urlStr, which will be resolved to the // BaseURL of the Client. Relative URLS should always be specified without a preceding slash. If specified, the // value pointed to by body is JSON encoded and included in as the request body. -func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) { +func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body interface{}) (*http.Request, error) { rel, err := url.Parse(urlStr) if err != nil { return nil, err @@ -289,8 +293,8 @@ func (r *Response) populateRate() { // Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value // pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface, // the raw response will be written to v, without attempting to decode it. -func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { - resp, err := c.client.Do(req) +func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) { + resp, err := context.DoRequestWithClient(ctx, c.client, req) if err != nil { return nil, err } diff --git a/vendor/github.com/digitalocean/godo/image_actions.go b/vendor/github.com/digitalocean/godo/image_actions.go index 4c322b3e4..94ae6c2a4 100644 --- a/vendor/github.com/digitalocean/godo/image_actions.go +++ b/vendor/github.com/digitalocean/godo/image_actions.go @@ -1,13 +1,18 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) // ImageActionsService is an interface for interfacing with the image actions // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#image-actions type ImageActionsService interface { - Get(int, int) (*Action, *Response, error) - Transfer(int, *ActionRequest) (*Action, *Response, error) + Get(context.Context, int, int) (*Action, *Response, error) + Transfer(context.Context, int, *ActionRequest) (*Action, *Response, error) + Convert(context.Context, int) (*Action, *Response, error) } // ImageActionsServiceOp handles communition with the image action related methods of the @@ -19,7 +24,7 @@ type ImageActionsServiceOp struct { var _ ImageActionsService = &ImageActionsServiceOp{} // Transfer an image -func (i *ImageActionsServiceOp) Transfer(imageID int, transferRequest *ActionRequest) (*Action, *Response, error) { +func (i *ImageActionsServiceOp) Transfer(ctx context.Context, imageID int, transferRequest *ActionRequest) (*Action, *Response, error) { if imageID < 1 { return nil, nil, NewArgError("imageID", "cannot be less than 1") } @@ -30,13 +35,39 @@ func (i *ImageActionsServiceOp) Transfer(imageID int, transferRequest *ActionReq path := fmt.Sprintf("v2/images/%d/actions", imageID) - req, err := i.client.NewRequest("POST", path, transferRequest) + req, err := i.client.NewRequest(ctx, "POST", path, transferRequest) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := i.client.Do(req, root) + resp, err := i.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +// Convert an image to a snapshot +func (i *ImageActionsServiceOp) Convert(ctx context.Context, imageID int) (*Action, *Response, error) { + if imageID < 1 { + return nil, nil, NewArgError("imageID", "cannont be less than 1") + } + + path := fmt.Sprintf("v2/images/%d/actions", imageID) + + convertRequest := &ActionRequest{ + "type": "convert", + } + + req, err := i.client.NewRequest(ctx, "POST", path, convertRequest) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := i.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -45,7 +76,7 @@ func (i *ImageActionsServiceOp) Transfer(imageID int, transferRequest *ActionReq } // Get an action for a particular image by id. -func (i *ImageActionsServiceOp) Get(imageID, actionID int) (*Action, *Response, error) { +func (i *ImageActionsServiceOp) Get(ctx context.Context, imageID, actionID int) (*Action, *Response, error) { if imageID < 1 { return nil, nil, NewArgError("imageID", "cannot be less than 1") } @@ -56,13 +87,13 @@ func (i *ImageActionsServiceOp) Get(imageID, actionID int) (*Action, *Response, path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID) - req, err := i.client.NewRequest("GET", path, nil) + req, err := i.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := i.client.Do(req, root) + resp, err := i.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/images.go b/vendor/github.com/digitalocean/godo/images.go index d5c298da9..e8ae262d1 100644 --- a/vendor/github.com/digitalocean/godo/images.go +++ b/vendor/github.com/digitalocean/godo/images.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const imageBasePath = "v2/images" @@ -8,14 +12,14 @@ const imageBasePath = "v2/images" // endpoints of the DigitalOcean 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) + List(context.Context, *ListOptions) ([]Image, *Response, error) + ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) + GetByID(context.Context, int) (*Image, *Response, error) + GetBySlug(context.Context, string) (*Image, *Response, error) + Update(context.Context, int, *ImageUpdateRequest) (*Image, *Response, error) + Delete(context.Context, int) (*Response, error) } // ImagesServiceOp handles communication with the image related methods of the @@ -63,48 +67,48 @@ func (i Image) String() string { } // List lists all the images available. -func (s *ImagesServiceOp) List(opt *ListOptions) ([]Image, *Response, error) { - return s.list(opt, nil) +func (s *ImagesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { + return s.list(ctx, opt, nil) } // ListDistribution lists all the distribution images. -func (s *ImagesServiceOp) ListDistribution(opt *ListOptions) ([]Image, *Response, error) { +func (s *ImagesServiceOp) ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { listOpt := listImageOptions{Type: "distribution"} - return s.list(opt, &listOpt) + return s.list(ctx, opt, &listOpt) } // ListApplication lists all the application images. -func (s *ImagesServiceOp) ListApplication(opt *ListOptions) ([]Image, *Response, error) { +func (s *ImagesServiceOp) ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { listOpt := listImageOptions{Type: "application"} - return s.list(opt, &listOpt) + return s.list(ctx, opt, &listOpt) } // ListUser lists all the user images. -func (s *ImagesServiceOp) ListUser(opt *ListOptions) ([]Image, *Response, error) { +func (s *ImagesServiceOp) ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) { listOpt := listImageOptions{Private: true} - return s.list(opt, &listOpt) + return s.list(ctx, opt, &listOpt) } // GetByID retrieves an image by id. -func (s *ImagesServiceOp) GetByID(imageID int) (*Image, *Response, error) { +func (s *ImagesServiceOp) GetByID(ctx context.Context, imageID int) (*Image, *Response, error) { if imageID < 1 { return nil, nil, NewArgError("imageID", "cannot be less than 1") } - return s.get(interface{}(imageID)) + return s.get(ctx, interface{}(imageID)) } // GetBySlug retrieves an image by slug. -func (s *ImagesServiceOp) GetBySlug(slug string) (*Image, *Response, error) { +func (s *ImagesServiceOp) GetBySlug(ctx context.Context, slug string) (*Image, *Response, error) { if len(slug) < 1 { return nil, nil, NewArgError("slug", "cannot be blank") } - return s.get(interface{}(slug)) + return s.get(ctx, interface{}(slug)) } // Update an image name. -func (s *ImagesServiceOp) Update(imageID int, updateRequest *ImageUpdateRequest) (*Image, *Response, error) { +func (s *ImagesServiceOp) Update(ctx context.Context, imageID int, updateRequest *ImageUpdateRequest) (*Image, *Response, error) { if imageID < 1 { return nil, nil, NewArgError("imageID", "cannot be less than 1") } @@ -114,13 +118,13 @@ func (s *ImagesServiceOp) Update(imageID int, updateRequest *ImageUpdateRequest) } path := fmt.Sprintf("%s/%d", imageBasePath, imageID) - req, err := s.client.NewRequest("PUT", path, updateRequest) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) if err != nil { return nil, nil, err } root := new(imageRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -129,34 +133,34 @@ func (s *ImagesServiceOp) Update(imageID int, updateRequest *ImageUpdateRequest) } // Delete an image. -func (s *ImagesServiceOp) Delete(imageID int) (*Response, error) { +func (s *ImagesServiceOp) Delete(ctx context.Context, imageID int) (*Response, error) { if imageID < 1 { return nil, NewArgError("imageID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", imageBasePath, imageID) - req, err := s.client.NewRequest("DELETE", path, nil) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // Helper method for getting an individual image -func (s *ImagesServiceOp) get(ID interface{}) (*Image, *Response, error) { +func (s *ImagesServiceOp) get(ctx context.Context, ID interface{}) (*Image, *Response, error) { path := fmt.Sprintf("%s/%v", imageBasePath, ID) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(imageRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -165,7 +169,7 @@ func (s *ImagesServiceOp) get(ID interface{}) (*Image, *Response, error) { } // Helper method for listing images -func (s *ImagesServiceOp) list(opt *ListOptions, listOpt *listImageOptions) ([]Image, *Response, error) { +func (s *ImagesServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listImageOptions) ([]Image, *Response, error) { path := imageBasePath path, err := addOptions(path, opt) if err != nil { @@ -176,13 +180,13 @@ func (s *ImagesServiceOp) list(opt *ListOptions, listOpt *listImageOptions) ([]I return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(imagesRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/keys.go b/vendor/github.com/digitalocean/godo/keys.go index 913471a96..d7aaba1e0 100644 --- a/vendor/github.com/digitalocean/godo/keys.go +++ b/vendor/github.com/digitalocean/godo/keys.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const keysBasePath = "v2/account/keys" @@ -8,14 +12,14 @@ const keysBasePath = "v2/account/keys" // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#keys type KeysService interface { - List(*ListOptions) ([]Key, *Response, error) - GetByID(int) (*Key, *Response, error) - GetByFingerprint(string) (*Key, *Response, error) - Create(*KeyCreateRequest) (*Key, *Response, error) - UpdateByID(int, *KeyUpdateRequest) (*Key, *Response, error) - UpdateByFingerprint(string, *KeyUpdateRequest) (*Key, *Response, error) - DeleteByID(int) (*Response, error) - DeleteByFingerprint(string) (*Response, error) + List(context.Context, *ListOptions) ([]Key, *Response, error) + GetByID(context.Context, int) (*Key, *Response, error) + GetByFingerprint(context.Context, string) (*Key, *Response, error) + Create(context.Context, *KeyCreateRequest) (*Key, *Response, error) + UpdateByID(context.Context, int, *KeyUpdateRequest) (*Key, *Response, error) + UpdateByFingerprint(context.Context, string, *KeyUpdateRequest) (*Key, *Response, error) + DeleteByID(context.Context, int) (*Response, error) + DeleteByFingerprint(context.Context, string) (*Response, error) } // KeysServiceOp handles communication with key related method of the @@ -59,20 +63,20 @@ type KeyCreateRequest struct { } // List all keys -func (s *KeysServiceOp) List(opt *ListOptions) ([]Key, *Response, error) { +func (s *KeysServiceOp) List(ctx context.Context, opt *ListOptions) ([]Key, *Response, error) { path := keysBasePath path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(keysRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -84,14 +88,14 @@ func (s *KeysServiceOp) List(opt *ListOptions) ([]Key, *Response, error) { } // Performs a get given a path -func (s *KeysServiceOp) get(path string) (*Key, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *KeysServiceOp) get(ctx context.Context, path string) (*Key, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(keyRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -100,38 +104,38 @@ func (s *KeysServiceOp) get(path string) (*Key, *Response, error) { } // GetByID gets a Key by id -func (s *KeysServiceOp) GetByID(keyID int) (*Key, *Response, error) { +func (s *KeysServiceOp) GetByID(ctx context.Context, keyID int) (*Key, *Response, error) { if keyID < 1 { return nil, nil, NewArgError("keyID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", keysBasePath, keyID) - return s.get(path) + return s.get(ctx, path) } // GetByFingerprint gets a Key by by fingerprint -func (s *KeysServiceOp) GetByFingerprint(fingerprint string) (*Key, *Response, error) { +func (s *KeysServiceOp) GetByFingerprint(ctx context.Context, fingerprint string) (*Key, *Response, error) { if len(fingerprint) < 1 { return nil, nil, NewArgError("fingerprint", "cannot not be empty") } path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) - return s.get(path) + return s.get(ctx, path) } // Create a key using a KeyCreateRequest -func (s *KeysServiceOp) Create(createRequest *KeyCreateRequest) (*Key, *Response, error) { +func (s *KeysServiceOp) Create(ctx context.Context, createRequest *KeyCreateRequest) (*Key, *Response, error) { if createRequest == nil { return nil, nil, NewArgError("createRequest", "cannot be nil") } - req, err := s.client.NewRequest("POST", keysBasePath, createRequest) + req, err := s.client.NewRequest(ctx, "POST", keysBasePath, createRequest) if err != nil { return nil, nil, err } root := new(keyRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -140,7 +144,7 @@ func (s *KeysServiceOp) Create(createRequest *KeyCreateRequest) (*Key, *Response } // UpdateByID updates a key name by ID. -func (s *KeysServiceOp) UpdateByID(keyID int, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { +func (s *KeysServiceOp) UpdateByID(ctx context.Context, keyID int, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { if keyID < 1 { return nil, nil, NewArgError("keyID", "cannot be less than 1") } @@ -150,13 +154,13 @@ func (s *KeysServiceOp) UpdateByID(keyID int, updateRequest *KeyUpdateRequest) ( } path := fmt.Sprintf("%s/%d", keysBasePath, keyID) - req, err := s.client.NewRequest("PUT", path, updateRequest) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) if err != nil { return nil, nil, err } root := new(keyRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -165,7 +169,7 @@ func (s *KeysServiceOp) UpdateByID(keyID int, updateRequest *KeyUpdateRequest) ( } // UpdateByFingerprint updates a key name by fingerprint. -func (s *KeysServiceOp) UpdateByFingerprint(fingerprint string, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { +func (s *KeysServiceOp) UpdateByFingerprint(ctx context.Context, fingerprint string, updateRequest *KeyUpdateRequest) (*Key, *Response, error) { if len(fingerprint) < 1 { return nil, nil, NewArgError("fingerprint", "cannot be empty") } @@ -175,13 +179,13 @@ func (s *KeysServiceOp) UpdateByFingerprint(fingerprint string, updateRequest *K } path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) - req, err := s.client.NewRequest("PUT", path, updateRequest) + req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest) if err != nil { return nil, nil, err } root := new(keyRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -190,33 +194,33 @@ func (s *KeysServiceOp) UpdateByFingerprint(fingerprint string, updateRequest *K } // Delete key using a path -func (s *KeysServiceOp) delete(path string) (*Response, error) { - req, err := s.client.NewRequest("DELETE", path, nil) +func (s *KeysServiceOp) delete(ctx context.Context, path string) (*Response, error) { + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // DeleteByID deletes a key by its id -func (s *KeysServiceOp) DeleteByID(keyID int) (*Response, error) { +func (s *KeysServiceOp) DeleteByID(ctx context.Context, keyID int) (*Response, error) { if keyID < 1 { return nil, NewArgError("keyID", "cannot be less than 1") } path := fmt.Sprintf("%s/%d", keysBasePath, keyID) - return s.delete(path) + return s.delete(ctx, path) } // DeleteByFingerprint deletes a key by its fingerprint -func (s *KeysServiceOp) DeleteByFingerprint(fingerprint string) (*Response, error) { +func (s *KeysServiceOp) DeleteByFingerprint(ctx context.Context, fingerprint string) (*Response, error) { if len(fingerprint) < 1 { return nil, NewArgError("fingerprint", "cannot be empty") } path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint) - return s.delete(path) + return s.delete(ctx, path) } diff --git a/vendor/github.com/digitalocean/godo/links.go b/vendor/github.com/digitalocean/godo/links.go index 7769f054e..0c6110210 100644 --- a/vendor/github.com/digitalocean/godo/links.go +++ b/vendor/github.com/digitalocean/godo/links.go @@ -3,6 +3,8 @@ package godo import ( "net/url" "strconv" + + "github.com/digitalocean/godo/context" ) // Links manages links that are returned along with a List @@ -77,6 +79,6 @@ func pageForURL(urlText string) (int, error) { } // Get a link action by id. -func (la *LinkAction) Get(client *Client) (*Action, *Response, error) { - return client.Actions.Get(la.ID) +func (la *LinkAction) Get(ctx context.Context, client *Client) (*Action, *Response, error) { + return client.Actions.Get(ctx, la.ID) } diff --git a/vendor/github.com/digitalocean/godo/load_balancers.go b/vendor/github.com/digitalocean/godo/load_balancers.go old mode 100755 new mode 100644 index d5da16f0e..cd225b489 --- a/vendor/github.com/digitalocean/godo/load_balancers.go +++ b/vendor/github.com/digitalocean/godo/load_balancers.go @@ -2,6 +2,8 @@ package godo import ( "fmt" + + "github.com/digitalocean/godo/context" ) const loadBalancersBasePath = "/v2/load_balancers" @@ -11,15 +13,15 @@ const dropletsPath = "droplets" // LoadBalancersService is an interface for managing load balancers with the DigitalOcean API. // See: https://developers.digitalocean.com/documentation/v2#load-balancers type LoadBalancersService interface { - Get(lbID string) (*LoadBalancer, *Response, error) - List(opt *ListOptions) ([]LoadBalancer, *Response, error) - Create(lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) - Update(lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) - Delete(lbID string) (*Response, error) - AddDroplets(lbID string, dropletIDs ...int) (*Response, error) - RemoveDroplets(lbID string, dropletIDs ...int) (*Response, error) - AddForwardingRules(lbID string, rules ...ForwardingRule) (*Response, error) - RemoveForwardingRules(lbID string, rules ...ForwardingRule) (*Response, error) + Get(context.Context, string) (*LoadBalancer, *Response, error) + List(context.Context, *ListOptions) ([]LoadBalancer, *Response, error) + Create(context.Context, *LoadBalancerRequest) (*LoadBalancer, *Response, error) + Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) + Delete(ctx context.Context, lbID string) (*Response, error) + AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) + RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) + AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) + RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) } // LoadBalancer represents a DigitalOcean load balancer configuration. @@ -138,16 +140,16 @@ type LoadBalancersServiceOp struct { var _ LoadBalancersService = &LoadBalancersServiceOp{} // Get an existing load balancer by its identifier. -func (l *LoadBalancersServiceOp) Get(lbID string) (*LoadBalancer, *Response, error) { +func (l *LoadBalancersServiceOp) Get(ctx context.Context, lbID string) (*LoadBalancer, *Response, error) { path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID) - req, err := l.client.NewRequest("GET", path, nil) + req, err := l.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(loadBalancerRoot) - resp, err := l.client.Do(req, root) + resp, err := l.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -156,19 +158,19 @@ func (l *LoadBalancersServiceOp) Get(lbID string) (*LoadBalancer, *Response, err } // List load balancers, with optional pagination. -func (l *LoadBalancersServiceOp) List(opt *ListOptions) ([]LoadBalancer, *Response, error) { +func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]LoadBalancer, *Response, error) { path, err := addOptions(loadBalancersBasePath, opt) if err != nil { return nil, nil, err } - req, err := l.client.NewRequest("GET", path, nil) + req, err := l.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(loadBalancersRoot) - resp, err := l.client.Do(req, root) + resp, err := l.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -180,14 +182,14 @@ func (l *LoadBalancersServiceOp) List(opt *ListOptions) ([]LoadBalancer, *Respon } // Create a new load balancer with a given configuration. -func (l *LoadBalancersServiceOp) Create(lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { - req, err := l.client.NewRequest("POST", loadBalancersBasePath, lbr) +func (l *LoadBalancersServiceOp) Create(ctx context.Context, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { + req, err := l.client.NewRequest(ctx, "POST", loadBalancersBasePath, lbr) if err != nil { return nil, nil, err } root := new(loadBalancerRoot) - resp, err := l.client.Do(req, root) + resp, err := l.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -196,16 +198,16 @@ func (l *LoadBalancersServiceOp) Create(lbr *LoadBalancerRequest) (*LoadBalancer } // Update an existing load balancer with new configuration. -func (l *LoadBalancersServiceOp) Update(lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { +func (l *LoadBalancersServiceOp) Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) { path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID) - req, err := l.client.NewRequest("PUT", path, lbr) + req, err := l.client.NewRequest(ctx, "PUT", path, lbr) if err != nil { return nil, nil, err } root := new(loadBalancerRoot) - resp, err := l.client.Do(req, root) + resp, err := l.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -214,61 +216,61 @@ func (l *LoadBalancersServiceOp) Update(lbID string, lbr *LoadBalancerRequest) ( } // Delete a load balancer by its identifier. -func (l *LoadBalancersServiceOp) Delete(ldID string) (*Response, error) { +func (l *LoadBalancersServiceOp) Delete(ctx context.Context, ldID string) (*Response, error) { path := fmt.Sprintf("%s/%s", loadBalancersBasePath, ldID) - req, err := l.client.NewRequest("DELETE", path, nil) + req, err := l.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - return l.client.Do(req, nil) + return l.client.Do(ctx, req, nil) } // AddDroplets adds droplets to a load balancer. -func (l *LoadBalancersServiceOp) AddDroplets(lbID string, dropletIDs ...int) (*Response, error) { +func (l *LoadBalancersServiceOp) AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) { path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath) - req, err := l.client.NewRequest("POST", path, &dropletIDsRequest{IDs: dropletIDs}) + req, err := l.client.NewRequest(ctx, "POST", path, &dropletIDsRequest{IDs: dropletIDs}) if err != nil { return nil, err } - return l.client.Do(req, nil) + return l.client.Do(ctx, req, nil) } // RemoveDroplets removes droplets from a load balancer. -func (l *LoadBalancersServiceOp) RemoveDroplets(lbID string, dropletIDs ...int) (*Response, error) { +func (l *LoadBalancersServiceOp) RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) { path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath) - req, err := l.client.NewRequest("DELETE", path, &dropletIDsRequest{IDs: dropletIDs}) + req, err := l.client.NewRequest(ctx, "DELETE", path, &dropletIDsRequest{IDs: dropletIDs}) if err != nil { return nil, err } - return l.client.Do(req, nil) + return l.client.Do(ctx, req, nil) } // AddForwardingRules adds forwarding rules to a load balancer. -func (l *LoadBalancersServiceOp) AddForwardingRules(lbID string, rules ...ForwardingRule) (*Response, error) { +func (l *LoadBalancersServiceOp) AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) { path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath) - req, err := l.client.NewRequest("POST", path, &forwardingRulesRequest{Rules: rules}) + req, err := l.client.NewRequest(ctx, "POST", path, &forwardingRulesRequest{Rules: rules}) if err != nil { return nil, err } - return l.client.Do(req, nil) + return l.client.Do(ctx, req, nil) } // RemoveForwardingRules removes forwarding rules from a load balancer. -func (l *LoadBalancersServiceOp) RemoveForwardingRules(lbID string, rules ...ForwardingRule) (*Response, error) { +func (l *LoadBalancersServiceOp) RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) { path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath) - req, err := l.client.NewRequest("DELETE", path, &forwardingRulesRequest{Rules: rules}) + req, err := l.client.NewRequest(ctx, "DELETE", path, &forwardingRulesRequest{Rules: rules}) if err != nil { return nil, err } - return l.client.Do(req, nil) + return l.client.Do(ctx, req, nil) } diff --git a/vendor/github.com/digitalocean/godo/regions.go b/vendor/github.com/digitalocean/godo/regions.go index 0e1b7cef2..e2a7e6e49 100644 --- a/vendor/github.com/digitalocean/godo/regions.go +++ b/vendor/github.com/digitalocean/godo/regions.go @@ -1,10 +1,12 @@ package godo +import "github.com/digitalocean/godo/context" + // RegionsService is an interface for interfacing with the regions // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#regions type RegionsService interface { - List(*ListOptions) ([]Region, *Response, error) + List(context.Context, *ListOptions) ([]Region, *Response, error) } // RegionsServiceOp handles communication with the region related methods of the @@ -34,20 +36,20 @@ func (r Region) String() string { } // List all regions -func (s *RegionsServiceOp) List(opt *ListOptions) ([]Region, *Response, error) { +func (s *RegionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Region, *Response, error) { path := "v2/regions" path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(regionsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/sizes.go b/vendor/github.com/digitalocean/godo/sizes.go index 7f454e7eb..9591fd2fa 100644 --- a/vendor/github.com/digitalocean/godo/sizes.go +++ b/vendor/github.com/digitalocean/godo/sizes.go @@ -1,10 +1,12 @@ package godo +import "github.com/digitalocean/godo/context" + // SizesService is an interface for interfacing with the size // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#sizes type SizesService interface { - List(*ListOptions) ([]Size, *Response, error) + List(context.Context, *ListOptions) ([]Size, *Response, error) } // SizesServiceOp handles communication with the size related methods of the @@ -38,20 +40,20 @@ type sizesRoot struct { } // List all images -func (s *SizesServiceOp) List(opt *ListOptions) ([]Size, *Response, error) { +func (s *SizesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Size, *Response, error) { path := "v2/sizes" path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(sizesRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/snapshots.go b/vendor/github.com/digitalocean/godo/snapshots.go index 4ab350f6e..aa434bd3c 100644 --- a/vendor/github.com/digitalocean/godo/snapshots.go +++ b/vendor/github.com/digitalocean/godo/snapshots.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const snapshotBasePath = "v2/snapshots" @@ -8,11 +12,11 @@ const snapshotBasePath = "v2/snapshots" // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#snapshots type SnapshotsService interface { - List(*ListOptions) ([]Snapshot, *Response, error) - ListVolume(*ListOptions) ([]Snapshot, *Response, error) - ListDroplet(*ListOptions) ([]Snapshot, *Response, error) - Get(string) (*Snapshot, *Response, error) - Delete(string) (*Response, error) + List(context.Context, *ListOptions) ([]Snapshot, *Response, error) + ListVolume(context.Context, *ListOptions) ([]Snapshot, *Response, error) + ListDroplet(context.Context, *ListOptions) ([]Snapshot, *Response, error) + Get(context.Context, string) (*Snapshot, *Response, error) + Delete(context.Context, string) (*Response, error) } // SnapshotsServiceOp handles communication with the snapshot related methods of the @@ -53,52 +57,52 @@ func (s Snapshot) String() string { } // List lists all the snapshots available. -func (s *SnapshotsServiceOp) List(opt *ListOptions) ([]Snapshot, *Response, error) { - return s.list(opt, nil) +func (s *SnapshotsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { + return s.list(ctx, opt, nil) } // ListDroplet lists all the Droplet snapshots. -func (s *SnapshotsServiceOp) ListDroplet(opt *ListOptions) ([]Snapshot, *Response, error) { +func (s *SnapshotsServiceOp) ListDroplet(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { listOpt := listSnapshotOptions{ResourceType: "droplet"} - return s.list(opt, &listOpt) + return s.list(ctx, opt, &listOpt) } // ListVolume lists all the volume snapshots. -func (s *SnapshotsServiceOp) ListVolume(opt *ListOptions) ([]Snapshot, *Response, error) { +func (s *SnapshotsServiceOp) ListVolume(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) { listOpt := listSnapshotOptions{ResourceType: "volume"} - return s.list(opt, &listOpt) + return s.list(ctx, opt, &listOpt) } // Get retrieves an snapshot by id. -func (s *SnapshotsServiceOp) Get(snapshotID string) (*Snapshot, *Response, error) { - return s.get(interface{}(snapshotID)) +func (s *SnapshotsServiceOp) Get(ctx context.Context, snapshotID string) (*Snapshot, *Response, error) { + return s.get(ctx, snapshotID) } // Delete an snapshot. -func (s *SnapshotsServiceOp) Delete(snapshotID string) (*Response, error) { +func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Response, error) { path := fmt.Sprintf("%s/%s", snapshotBasePath, snapshotID) - req, err := s.client.NewRequest("DELETE", path, nil) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // Helper method for getting an individual snapshot -func (s *SnapshotsServiceOp) get(ID interface{}) (*Snapshot, *Response, error) { - path := fmt.Sprintf("%s/%v", snapshotBasePath, ID) +func (s *SnapshotsServiceOp) get(ctx context.Context, ID string) (*Snapshot, *Response, error) { + path := fmt.Sprintf("%s/%s", snapshotBasePath, ID) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(snapshotRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -107,7 +111,7 @@ func (s *SnapshotsServiceOp) get(ID interface{}) (*Snapshot, *Response, error) { } // Helper method for listing snapshots -func (s *SnapshotsServiceOp) list(opt *ListOptions, listOpt *listSnapshotOptions) ([]Snapshot, *Response, error) { +func (s *SnapshotsServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listSnapshotOptions) ([]Snapshot, *Response, error) { path := snapshotBasePath path, err := addOptions(path, opt) if err != nil { @@ -118,13 +122,13 @@ func (s *SnapshotsServiceOp) list(opt *ListOptions, listOpt *listSnapshotOptions return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(snapshotsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/storage.go b/vendor/github.com/digitalocean/godo/storage.go index e3a9606d5..ab9052e98 100644 --- a/vendor/github.com/digitalocean/godo/storage.go +++ b/vendor/github.com/digitalocean/godo/storage.go @@ -3,6 +3,8 @@ package godo import ( "fmt" "time" + + "github.com/digitalocean/godo/context" ) const ( @@ -15,14 +17,14 @@ const ( // endpoints of the Digital Ocean API. // See: https://developers.digitalocean.com/documentation/v2#storage type StorageService interface { - ListVolumes(*ListOptions) ([]Volume, *Response, error) - GetVolume(string) (*Volume, *Response, error) - CreateVolume(*VolumeCreateRequest) (*Volume, *Response, error) - DeleteVolume(string) (*Response, error) - ListSnapshots(volumeID string, opts *ListOptions) ([]Snapshot, *Response, error) - GetSnapshot(string) (*Snapshot, *Response, error) - CreateSnapshot(*SnapshotCreateRequest) (*Snapshot, *Response, error) - DeleteSnapshot(string) (*Response, error) + ListVolumes(context.Context, *ListVolumeParams) ([]Volume, *Response, error) + GetVolume(context.Context, string) (*Volume, *Response, error) + CreateVolume(context.Context, *VolumeCreateRequest) (*Volume, *Response, error) + DeleteVolume(context.Context, string) (*Response, error) + ListSnapshots(ctx context.Context, volumeID string, opts *ListOptions) ([]Snapshot, *Response, error) + GetSnapshot(context.Context, string) (*Snapshot, *Response, error) + CreateSnapshot(context.Context, *SnapshotCreateRequest) (*Snapshot, *Response, error) + DeleteSnapshot(context.Context, string) (*Response, error) } // StorageServiceOp handles communication with the storage volumes related methods of the @@ -31,6 +33,13 @@ type StorageServiceOp struct { client *Client } +// ListVolumeParams stores the options you can set for a ListVolumeCall +type ListVolumeParams struct { + Region string `json:"region"` + Name string `json:"name"` + ListOptions *ListOptions `json:"list_options,omitempty"` +} + var _ StorageService = &StorageServiceOp{} // Volume represents a Digital Ocean block store volume. @@ -65,22 +74,33 @@ type VolumeCreateRequest struct { Name string `json:"name"` Description string `json:"description"` SizeGigaBytes int64 `json:"size_gigabytes"` + SnapshotID string `json:"snapshot_id"` } // ListVolumes lists all storage volumes. -func (svc *StorageServiceOp) ListVolumes(opt *ListOptions) ([]Volume, *Response, error) { - path, err := addOptions(storageAllocPath, opt) - if err != nil { - return nil, nil, err +func (svc *StorageServiceOp) ListVolumes(ctx context.Context, params *ListVolumeParams) ([]Volume, *Response, error) { + path := storageAllocPath + if params != nil { + if params.Region != "" && params.Name != "" { + path = fmt.Sprintf("%s?name=%s®ion=%s", path, params.Name, params.Region) + } + + if params.ListOptions != nil { + var err error + path, err = addOptions(path, params.ListOptions) + if err != nil { + return nil, nil, err + } + } } - req, err := svc.client.NewRequest("GET", path, nil) + req, err := svc.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(storageVolumesRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -93,16 +113,16 @@ func (svc *StorageServiceOp) ListVolumes(opt *ListOptions) ([]Volume, *Response, } // CreateVolume creates a storage volume. The name must be unique. -func (svc *StorageServiceOp) CreateVolume(createRequest *VolumeCreateRequest) (*Volume, *Response, error) { +func (svc *StorageServiceOp) CreateVolume(ctx context.Context, createRequest *VolumeCreateRequest) (*Volume, *Response, error) { path := storageAllocPath - req, err := svc.client.NewRequest("POST", path, createRequest) + req, err := svc.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(storageVolumeRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -110,16 +130,16 @@ func (svc *StorageServiceOp) CreateVolume(createRequest *VolumeCreateRequest) (* } // GetVolume retrieves an individual storage volume. -func (svc *StorageServiceOp) GetVolume(id string) (*Volume, *Response, error) { +func (svc *StorageServiceOp) GetVolume(ctx context.Context, id string) (*Volume, *Response, error) { path := fmt.Sprintf("%s/%s", storageAllocPath, id) - req, err := svc.client.NewRequest("GET", path, nil) + req, err := svc.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(storageVolumeRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -128,14 +148,14 @@ func (svc *StorageServiceOp) GetVolume(id string) (*Volume, *Response, error) { } // DeleteVolume deletes a storage volume. -func (svc *StorageServiceOp) DeleteVolume(id string) (*Response, error) { +func (svc *StorageServiceOp) DeleteVolume(ctx context.Context, id string) (*Response, error) { path := fmt.Sprintf("%s/%s", storageAllocPath, id) - req, err := svc.client.NewRequest("DELETE", path, nil) + req, err := svc.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - return svc.client.Do(req, nil) + return svc.client.Do(ctx, req, nil) } // SnapshotCreateRequest represents a request to create a block store @@ -147,20 +167,20 @@ type SnapshotCreateRequest struct { } // ListSnapshots lists all snapshots related to a storage volume. -func (svc *StorageServiceOp) ListSnapshots(volumeID string, opt *ListOptions) ([]Snapshot, *Response, error) { +func (svc *StorageServiceOp) ListSnapshots(ctx context.Context, volumeID string, opt *ListOptions) ([]Snapshot, *Response, error) { path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, volumeID) path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - req, err := svc.client.NewRequest("GET", path, nil) + req, err := svc.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(snapshotsRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -173,16 +193,16 @@ func (svc *StorageServiceOp) ListSnapshots(volumeID string, opt *ListOptions) ([ } // CreateSnapshot creates a snapshot of a storage volume. -func (svc *StorageServiceOp) CreateSnapshot(createRequest *SnapshotCreateRequest) (*Snapshot, *Response, error) { +func (svc *StorageServiceOp) CreateSnapshot(ctx context.Context, createRequest *SnapshotCreateRequest) (*Snapshot, *Response, error) { path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, createRequest.VolumeID) - req, err := svc.client.NewRequest("POST", path, createRequest) + req, err := svc.client.NewRequest(ctx, "POST", path, createRequest) if err != nil { return nil, nil, err } root := new(snapshotRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -190,16 +210,16 @@ func (svc *StorageServiceOp) CreateSnapshot(createRequest *SnapshotCreateRequest } // GetSnapshot retrieves an individual snapshot. -func (svc *StorageServiceOp) GetSnapshot(id string) (*Snapshot, *Response, error) { +func (svc *StorageServiceOp) GetSnapshot(ctx context.Context, id string) (*Snapshot, *Response, error) { path := fmt.Sprintf("%s/%s", storageSnapPath, id) - req, err := svc.client.NewRequest("GET", path, nil) + req, err := svc.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(snapshotRoot) - resp, err := svc.client.Do(req, root) + resp, err := svc.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -208,12 +228,12 @@ func (svc *StorageServiceOp) GetSnapshot(id string) (*Snapshot, *Response, error } // DeleteSnapshot deletes a snapshot. -func (svc *StorageServiceOp) DeleteSnapshot(id string) (*Response, error) { +func (svc *StorageServiceOp) DeleteSnapshot(ctx context.Context, id string) (*Response, error) { path := fmt.Sprintf("%s/%s", storageSnapPath, id) - req, err := svc.client.NewRequest("DELETE", path, nil) + req, err := svc.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - return svc.client.Do(req, nil) + return svc.client.Do(ctx, req, nil) } diff --git a/vendor/github.com/digitalocean/godo/storage_actions.go b/vendor/github.com/digitalocean/godo/storage_actions.go index 992c34375..1cc0a9d3f 100644 --- a/vendor/github.com/digitalocean/godo/storage_actions.go +++ b/vendor/github.com/digitalocean/godo/storage_actions.go @@ -1,17 +1,20 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) // StorageActionsService is an interface for interfacing with the // storage actions endpoints of the Digital Ocean API. // See: https://developers.digitalocean.com/documentation/v2#storage-actions type StorageActionsService interface { - Attach(volumeID string, dropletID int) (*Action, *Response, error) - Detach(volumeID string) (*Action, *Response, error) - DetachByDropletID(volumeID string, dropletID int) (*Action, *Response, error) - Get(volumeID string, actionID int) (*Action, *Response, error) - List(volumeID string, opt *ListOptions) ([]Action, *Response, error) - Resize(volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) + Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) + DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) + Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error) + List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error) + Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) } // StorageActionsServiceOp handles communication with the storage volumes @@ -27,68 +30,60 @@ type StorageAttachment struct { } // Attach a storage volume to a Droplet. -func (s *StorageActionsServiceOp) Attach(volumeID string, dropletID int) (*Action, *Response, error) { +func (s *StorageActionsServiceOp) Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) { request := &ActionRequest{ "type": "attach", "droplet_id": dropletID, } - return s.doAction(volumeID, request) -} - -// Detach a storage volume from a Droplet. -func (s *StorageActionsServiceOp) Detach(volumeID string) (*Action, *Response, error) { - request := &ActionRequest{ - "type": "detach", - } - return s.doAction(volumeID, request) + return s.doAction(ctx, volumeID, request) } // DetachByDropletID a storage volume from a Droplet by Droplet ID. -func (s *StorageActionsServiceOp) DetachByDropletID(volumeID string, dropletID int) (*Action, *Response, error) { +func (s *StorageActionsServiceOp) DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) { request := &ActionRequest{ "type": "detach", "droplet_id": dropletID, } - return s.doAction(volumeID, request) + return s.doAction(ctx, volumeID, request) } // Get an action for a particular storage volume by id. -func (s *StorageActionsServiceOp) Get(volumeID string, actionID int) (*Action, *Response, error) { +func (s *StorageActionsServiceOp) Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error) { path := fmt.Sprintf("%s/%d", storageAllocationActionPath(volumeID), actionID) - return s.get(path) + return s.get(ctx, path) } // List the actions for a particular storage volume. -func (s *StorageActionsServiceOp) List(volumeID string, opt *ListOptions) ([]Action, *Response, error) { +func (s *StorageActionsServiceOp) List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error) { path := storageAllocationActionPath(volumeID) path, err := addOptions(path, opt) if err != nil { return nil, nil, err } - return s.list(path) + return s.list(ctx, path) } // Resize a storage volume. -func (s *StorageActionsServiceOp) Resize(volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) { +func (s *StorageActionsServiceOp) Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) { request := &ActionRequest{ "type": "resize", "size_gigabytes": sizeGigabytes, "region": regionSlug, } - return s.doAction(volumeID, request) + return s.doAction(ctx, volumeID, request) } -func (s *StorageActionsServiceOp) doAction(volumeID string, request *ActionRequest) (*Action, *Response, error) { +func (s *StorageActionsServiceOp) doAction(ctx context.Context, volumeID string, request *ActionRequest) (*Action, *Response, error) { path := storageAllocationActionPath(volumeID) - req, err := s.client.NewRequest("POST", path, request) + req, err := s.client.NewRequest(ctx, "POST", path, request) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -96,14 +91,14 @@ func (s *StorageActionsServiceOp) doAction(volumeID string, request *ActionReque return root.Event, resp, err } -func (s *StorageActionsServiceOp) get(path string) (*Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *StorageActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -111,14 +106,14 @@ func (s *StorageActionsServiceOp) get(path string) (*Action, *Response, error) { return root.Event, resp, err } -func (s *StorageActionsServiceOp) list(path string) ([]Action, *Response, error) { - req, err := s.client.NewRequest("GET", path, nil) +func (s *StorageActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) { + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(actionsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } diff --git a/vendor/github.com/digitalocean/godo/tags.go b/vendor/github.com/digitalocean/godo/tags.go index 745c16f62..cbd5c5bae 100644 --- a/vendor/github.com/digitalocean/godo/tags.go +++ b/vendor/github.com/digitalocean/godo/tags.go @@ -1,6 +1,10 @@ package godo -import "fmt" +import ( + "fmt" + + "github.com/digitalocean/godo/context" +) const tagsBasePath = "v2/tags" @@ -8,14 +12,13 @@ const tagsBasePath = "v2/tags" // endpoints of the DigitalOcean API // See: https://developers.digitalocean.com/documentation/v2#tags type TagsService interface { - List(*ListOptions) ([]Tag, *Response, error) - Get(string) (*Tag, *Response, error) - Create(*TagCreateRequest) (*Tag, *Response, error) - Update(string, *TagUpdateRequest) (*Response, error) - Delete(string) (*Response, error) + List(context.Context, *ListOptions) ([]Tag, *Response, error) + Get(context.Context, string) (*Tag, *Response, error) + Create(context.Context, *TagCreateRequest) (*Tag, *Response, error) + Delete(context.Context, string) (*Response, error) - TagResources(string, *TagResourcesRequest) (*Response, error) - UntagResources(string, *UntagResourcesRequest) (*Response, error) + TagResources(context.Context, string, *TagResourcesRequest) (*Response, error) + UntagResources(context.Context, string, *UntagResourcesRequest) (*Response, error) } // TagsServiceOp handles communication with tag related method of the @@ -62,11 +65,6 @@ type TagCreateRequest struct { Name string `json:"name"` } -//TagUpdateRequest represents the JSON structure of a request of that type. -type TagUpdateRequest struct { - Name string `json:"name"` -} - // TagResourcesRequest represents the JSON structure of a request of that type. type TagResourcesRequest struct { Resources []Resource `json:"resources"` @@ -87,7 +85,7 @@ type tagRoot struct { } // List all tags -func (s *TagsServiceOp) List(opt *ListOptions) ([]Tag, *Response, error) { +func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Response, error) { path := tagsBasePath path, err := addOptions(path, opt) @@ -95,13 +93,13 @@ func (s *TagsServiceOp) List(opt *ListOptions) ([]Tag, *Response, error) { return nil, nil, err } - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(tagsRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -113,16 +111,16 @@ func (s *TagsServiceOp) List(opt *ListOptions) ([]Tag, *Response, error) { } // Get a single tag -func (s *TagsServiceOp) Get(name string) (*Tag, *Response, error) { +func (s *TagsServiceOp) Get(ctx context.Context, name string) (*Tag, *Response, error) { path := fmt.Sprintf("%s/%s", tagsBasePath, name) - req, err := s.client.NewRequest("GET", path, nil) + req, err := s.client.NewRequest(ctx, "GET", path, nil) if err != nil { return nil, nil, err } root := new(tagRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -131,18 +129,18 @@ func (s *TagsServiceOp) Get(name string) (*Tag, *Response, error) { } // Create a new tag -func (s *TagsServiceOp) Create(createRequest *TagCreateRequest) (*Tag, *Response, error) { +func (s *TagsServiceOp) Create(ctx context.Context, createRequest *TagCreateRequest) (*Tag, *Response, error) { if createRequest == nil { return nil, nil, NewArgError("createRequest", "cannot be nil") } - req, err := s.client.NewRequest("POST", tagsBasePath, createRequest) + req, err := s.client.NewRequest(ctx, "POST", tagsBasePath, createRequest) if err != nil { return nil, nil, err } root := new(tagRoot) - resp, err := s.client.Do(req, root) + resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } @@ -150,46 +148,25 @@ func (s *TagsServiceOp) Create(createRequest *TagCreateRequest) (*Tag, *Response return root.Tag, resp, err } -// Update an exsting tag -func (s *TagsServiceOp) Update(name string, updateRequest *TagUpdateRequest) (*Response, error) { - if name == "" { - return nil, NewArgError("name", "cannot be empty") - } - - if updateRequest == nil { - return nil, NewArgError("updateRequest", "cannot be nil") - } - - path := fmt.Sprintf("%s/%s", tagsBasePath, name) - req, err := s.client.NewRequest("PUT", path, updateRequest) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - - return resp, err -} - // Delete an existing tag -func (s *TagsServiceOp) Delete(name string) (*Response, error) { +func (s *TagsServiceOp) Delete(ctx context.Context, name string) (*Response, error) { if name == "" { return nil, NewArgError("name", "cannot be empty") } path := fmt.Sprintf("%s/%s", tagsBasePath, name) - req, err := s.client.NewRequest("DELETE", path, nil) + req, err := s.client.NewRequest(ctx, "DELETE", path, nil) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // TagResources associates resources with a given Tag. -func (s *TagsServiceOp) TagResources(name string, tagRequest *TagResourcesRequest) (*Response, error) { +func (s *TagsServiceOp) TagResources(ctx context.Context, name string, tagRequest *TagResourcesRequest) (*Response, error) { if name == "" { return nil, NewArgError("name", "cannot be empty") } @@ -199,18 +176,18 @@ func (s *TagsServiceOp) TagResources(name string, tagRequest *TagResourcesReques } path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name) - req, err := s.client.NewRequest("POST", path, tagRequest) + req, err := s.client.NewRequest(ctx, "POST", path, tagRequest) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } // UntagResources dissociates resources with a given Tag. -func (s *TagsServiceOp) UntagResources(name string, untagRequest *UntagResourcesRequest) (*Response, error) { +func (s *TagsServiceOp) UntagResources(ctx context.Context, name string, untagRequest *UntagResourcesRequest) (*Response, error) { if name == "" { return nil, NewArgError("name", "cannot be empty") } @@ -220,12 +197,12 @@ func (s *TagsServiceOp) UntagResources(name string, untagRequest *UntagResources } path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name) - req, err := s.client.NewRequest("DELETE", path, untagRequest) + req, err := s.client.NewRequest(ctx, "DELETE", path, untagRequest) if err != nil { return nil, err } - resp, err := s.client.Do(req, nil) + resp, err := s.client.Do(ctx, req, nil) return resp, err } diff --git a/vendor/vendor.json b/vendor/vendor.json index 09a55c3d8..2f3adf627 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1372,11 +1372,17 @@ "revisionTime": "2016-06-17T17:01:58Z" }, { - "checksumSHA1": "tOlmmumwQ9pCv5cQgs+W7sgPVgU=", + "checksumSHA1": "uuenX+nAyhQfYqedBhQ+yhBh1mA=", "comment": "v0.9.0-20-gf75d769", "path": "github.com/digitalocean/godo", - "revision": "767976000cc435d38646653b52be9be572727f30", - "revisionTime": "2017-02-14T20:43:37Z" + "revision": "83908b1ddd666d08a9b020c697b55ae3895be2fd", + "revisionTime": "2017-04-26T22:25:10Z" + }, + { + "checksumSHA1": "YpWoCsk+u9H5ctWNKKSVPf4b2as=", + "path": "github.com/digitalocean/godo/context", + "revision": "83908b1ddd666d08a9b020c697b55ae3895be2fd", + "revisionTime": "2017-04-26T22:25:10Z" }, { "checksumSHA1": "1PlWp7ZA8IBK6J6XcIwRpoSTNoc=", From 45ad54c816dbbf44cb400c71a8a50e73e594619a Mon Sep 17 00:00:00 2001 From: Caio Filipini Date: Tue, 16 May 2017 12:40:33 +0200 Subject: [PATCH 2/6] provider/digitalocean: Add support for certificates Besides the support for DO certificates themselves, this commit also includes: 1) A new `RandTLSCert` function that generates a valid, self-signed TLS certificate to be used in the test 2) A fix for the PEM encoding of the private key generated in `RandSSHKeyPair`: the PEM was always empty --- .../resource_digitalocean_certificate.go | 119 ++++++++++++++++++ .../resource_digitalocean_certificate_test.go | 117 +++++++++++++++++ helper/acctest/random.go | 73 +++++++++-- 3 files changed, 297 insertions(+), 12 deletions(-) create mode 100644 builtin/providers/digitalocean/resource_digitalocean_certificate.go create mode 100644 builtin/providers/digitalocean/resource_digitalocean_certificate_test.go diff --git a/builtin/providers/digitalocean/resource_digitalocean_certificate.go b/builtin/providers/digitalocean/resource_digitalocean_certificate.go new file mode 100644 index 000000000..d04af32c6 --- /dev/null +++ b/builtin/providers/digitalocean/resource_digitalocean_certificate.go @@ -0,0 +1,119 @@ +package digitalocean + +import ( + "context" + "fmt" + "log" + + "github.com/digitalocean/godo" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceDigitalOceanCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourceDigitalOceanCertificateCreate, + Read: resourceDigitalOceanCertificateRead, + Delete: resourceDigitalOceanCertificateDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "private_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "leaf_certificate": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "certificate_chain": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "not_after": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "sha1_fingerprint": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func buildCertificateRequest(d *schema.ResourceData) (*godo.CertificateRequest, error) { + req := &godo.CertificateRequest{ + Name: d.Get("name").(string), + PrivateKey: d.Get("private_key").(string), + LeafCertificate: d.Get("leaf_certificate").(string), + CertificateChain: d.Get("certificate_chain").(string), + } + + return req, nil +} + +func resourceDigitalOceanCertificateCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*godo.Client) + + log.Printf("[INFO] Create a Certificate Request") + + certReq, err := buildCertificateRequest(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] Certificate Create: %#v", certReq) + cert, _, err := client.Certificates.Create(context.Background(), certReq) + if err != nil { + return fmt.Errorf("Error creating Certificate: %s", err) + } + + d.SetId(cert.ID) + + return resourceDigitalOceanCertificateRead(d, meta) +} + +func resourceDigitalOceanCertificateRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*godo.Client) + + log.Printf("[INFO] Reading the details of the Certificate %s", d.Id()) + cert, _, err := client.Certificates.Get(context.Background(), d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving Certificate: %s", err) + } + + d.Set("name", cert.Name) + d.Set("not_after", cert.NotAfter) + d.Set("sha1_fingerprint", cert.SHA1Fingerprint) + + return nil + +} + +func resourceDigitalOceanCertificateDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*godo.Client) + + log.Printf("[INFO] Deleting Certificate: %s", d.Id()) + _, err := client.Certificates.Delete(context.Background(), d.Id()) + if err != nil { + return fmt.Errorf("Error deleting Certificate: %s", err) + } + + d.SetId("") + return nil + +} diff --git a/builtin/providers/digitalocean/resource_digitalocean_certificate_test.go b/builtin/providers/digitalocean/resource_digitalocean_certificate_test.go new file mode 100644 index 000000000..1ae6ae8bb --- /dev/null +++ b/builtin/providers/digitalocean/resource_digitalocean_certificate_test.go @@ -0,0 +1,117 @@ +package digitalocean + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/digitalocean/godo" + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccDigitalOceanCertificate_Basic(t *testing.T) { + var cert godo.Certificate + rInt := acctest.RandInt() + leafCertMaterial, privateKeyMaterial, err := acctest.RandTLSCert("Acme Co") + if err != nil { + t.Fatalf("Cannot generate test TLS certificate: %s", err) + } + rootCertMaterial, _, err := acctest.RandTLSCert("Acme Go") + if err != nil { + t.Fatalf("Cannot generate test TLS certificate: %s", err) + } + certChainMaterial := fmt.Sprintf("%s\n%s", strings.TrimSpace(rootCertMaterial), leafCertMaterial) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDigitalOceanCertificateDestroy, + Steps: []resource.TestStep{ + { + ExpectNonEmptyPlan: true, + Config: testAccCheckDigitalOceanCertificateConfig_basic(rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanCertificateExists("digitalocean_certificate.foobar", &cert), + resource.TestCheckResourceAttr( + "digitalocean_certificate.foobar", "name", fmt.Sprintf("certificate-%d", rInt)), + resource.TestCheckResourceAttr( + "digitalocean_certificate.foobar", "private_key", fmt.Sprintf("%s\n", privateKeyMaterial)), + resource.TestCheckResourceAttr( + "digitalocean_certificate.foobar", "leaf_certificate", fmt.Sprintf("%s\n", leafCertMaterial)), + resource.TestCheckResourceAttr( + "digitalocean_certificate.foobar", "certificate_chain", fmt.Sprintf("%s\n", certChainMaterial)), + ), + }, + }, + }) +} + +func testAccCheckDigitalOceanCertificateDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*godo.Client) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "digitalocean_certificate" { + continue + } + + _, _, err := client.Certificates.Get(context.Background(), rs.Primary.ID) + + if err != nil && !strings.Contains(err.Error(), "404") { + return fmt.Errorf( + "Error waiting for certificate (%s) to be destroyed: %s", + rs.Primary.ID, err) + } + } + + return nil +} + +func testAccCheckDigitalOceanCertificateExists(n string, cert *godo.Certificate) 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 Certificate ID is set") + } + + client := testAccProvider.Meta().(*godo.Client) + + c, _, err := client.Certificates.Get(context.Background(), rs.Primary.ID) + + if err != nil { + return err + } + + if c.ID != rs.Primary.ID { + return fmt.Errorf("Certificate not found") + } + + *cert = *c + + return nil + } +} + +func testAccCheckDigitalOceanCertificateConfig_basic(rInt int, privateKeyMaterial, leafCert, certChain string) string { + return fmt.Sprintf(` +resource "digitalocean_certificate" "foobar" { + name = "certificate-%d" + private_key = < Date: Wed, 17 May 2017 21:20:25 +0200 Subject: [PATCH 3/6] provider/digitalocean: Add documentation for Certificate resource --- .../providers/do/r/certificate.html.markdown | 65 +++++++++++++++++++ website/source/layouts/digitalocean.erb | 3 + 2 files changed, 68 insertions(+) create mode 100644 website/source/docs/providers/do/r/certificate.html.markdown diff --git a/website/source/docs/providers/do/r/certificate.html.markdown b/website/source/docs/providers/do/r/certificate.html.markdown new file mode 100644 index 000000000..a1d8ba0d2 --- /dev/null +++ b/website/source/docs/providers/do/r/certificate.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "digitalocean" +page_title: "DigitalOcean: digitalocean_certificate" +sidebar_current: "docs-do-resource-certificate" +description: |- + Provides a DigitalOcean Certificate resource. +--- + +# digitalocean\_certificate + +Provides a DigitalOcean Certificate resource that allows you to manage +certificates for configuring TLS termination in Load Balancers. +Certificates created with this resource can be referenced in your +Load Balancer configuration via their ID. + +## Example Usage + +```hcl +# Create a new TLS certificate +resource "digitalocean_certificate" "cert" { + name = "Terraform Example" + private_key = "${file("/Users/terraform/certs/privkey.pem")}" + leaf_certificate = "${file("/Users/terraform/certs/cert.pem")}" + certificate_chain = "${file("/Users/terraform/certs/fullchain.pem")}" +} + +# Create a new Load Balancer with TLS termination +resource "digitalocean_loadbalancer" "public" { + name = "secure-loadbalancer-1" + region = "nyc3" + droplet_tag = "backend" + + forwarding_rule { + entry_port = 443 + entry_protocol = "https" + + target_port = 80 + target_protocol = "http" + + certificate_id = "${digitalocean_certificate.cert.id}" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the certificate for identification. +* `private_key` - (Required) The contents of a PEM-formatted private-key +corresponding to the SSL certificate. +* `leaf_certificate` - (Required) The contents of a PEM-formatted public +TLS certificate. +* `certificate_chain` - (Optional) The full PEM-formatted trust chain +between the certificate authority's certificate and your domain's TLS +certificate. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The unique ID of the certificate +* `name` - The name of the certificate +* `not_after` - The expiration date of the certificate +* `sha1_fingerprint` - The SHA-1 fingerprint of the certificate diff --git a/website/source/layouts/digitalocean.erb b/website/source/layouts/digitalocean.erb index c124499a2..1daea7eb8 100644 --- a/website/source/layouts/digitalocean.erb +++ b/website/source/layouts/digitalocean.erb @@ -22,6 +22,9 @@ > Resources