From 6f8ae776bce042ee8389d1411b7f0aef229864eb Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Tue, 6 Jun 2017 19:16:43 +0300 Subject: [PATCH] provider/digitalocean: Bump godo SDK to 1.1.0 (#15121) This allows support for DigitalOcean Firewalls --- .../github.com/digitalocean/godo/CHANGELOG.md | 10 + vendor/github.com/digitalocean/godo/README.md | 2 +- .../digitalocean/godo/droplet_actions.go | 42 +-- .../github.com/digitalocean/godo/firewalls.go | 263 ++++++++++++++++++ vendor/github.com/digitalocean/godo/godo.go | 4 +- vendor/vendor.json | 14 +- 6 files changed, 307 insertions(+), 28 deletions(-) create mode 100644 vendor/github.com/digitalocean/godo/firewalls.go diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index 71886a354..b89def70b 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## [v1.1.0] - 2017-06-06 + +### Added +- #145 Add FirewallsService for managing Firewalls with the DigitalOcean API. - @viola +- #139 Add TTL field to the Domains. - @xmudrii + +### Fixed +- #143 Fix oauth2.NoContext depreciation. - @jbowens +- #141 Fix DropletActions on tagged resources. - @xmudrii + ## [v1.0.0] - 2017-03-10 ### Added diff --git a/vendor/github.com/digitalocean/godo/README.md b/vendor/github.com/digitalocean/godo/README.md index 4d5cdf83e..44b2e4d0b 100644 --- a/vendor/github.com/digitalocean/godo/README.md +++ b/vendor/github.com/digitalocean/godo/README.md @@ -44,7 +44,7 @@ func (t *TokenSource) Token() (*oauth2.Token, error) { tokenSource := &TokenSource{ AccessToken: pat, } -oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource) +oauthClient := oauth2.NewClient(context.Background(), tokenSource) client := godo.NewClient(oauthClient) ``` diff --git a/vendor/github.com/digitalocean/godo/droplet_actions.go b/vendor/github.com/digitalocean/godo/droplet_actions.go index 7cc0d0852..4902fd6e5 100644 --- a/vendor/github.com/digitalocean/godo/droplet_actions.go +++ b/vendor/github.com/digitalocean/godo/droplet_actions.go @@ -15,31 +15,31 @@ type ActionRequest map[string]interface{} // See: https://developers.digitalocean.com/documentation/v2#droplet-actions type DropletActionsService interface { Shutdown(context.Context, int) (*Action, *Response, error) - ShutdownByTag(context.Context, string) (*Action, *Response, error) + ShutdownByTag(context.Context, string) ([]Action, *Response, error) PowerOff(context.Context, int) (*Action, *Response, error) - PowerOffByTag(context.Context, string) (*Action, *Response, error) + PowerOffByTag(context.Context, string) ([]Action, *Response, error) PowerOn(context.Context, int) (*Action, *Response, error) - PowerOnByTag(context.Context, string) (*Action, *Response, error) + PowerOnByTag(context.Context, string) ([]Action, *Response, error) PowerCycle(context.Context, int) (*Action, *Response, error) - PowerCycleByTag(context.Context, string) (*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) + SnapshotByTag(context.Context, string, string) ([]Action, *Response, error) EnableBackups(context.Context, int) (*Action, *Response, error) - EnableBackupsByTag(context.Context, string) (*Action, *Response, error) + EnableBackupsByTag(context.Context, string) ([]Action, *Response, error) DisableBackups(context.Context, int) (*Action, *Response, error) - DisableBackupsByTag(context.Context, string) (*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) + EnableIPv6ByTag(context.Context, string) ([]Action, *Response, error) EnablePrivateNetworking(context.Context, int) (*Action, *Response, error) - EnablePrivateNetworkingByTag(context.Context, string) (*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) @@ -60,7 +60,7 @@ func (s *DropletActionsServiceOp) Shutdown(ctx context.Context, id int) (*Action } // ShutdownByTag shuts down Droplets matched by a Tag. -func (s *DropletActionsServiceOp) ShutdownByTag(ctx context.Context, tag string) (*Action, *Response, error) { +func (s *DropletActionsServiceOp) ShutdownByTag(ctx context.Context, tag string) ([]Action, *Response, error) { request := &ActionRequest{"type": "shutdown"} return s.doActionByTag(ctx, tag, request) } @@ -72,7 +72,7 @@ func (s *DropletActionsServiceOp) PowerOff(ctx context.Context, id int) (*Action } // PowerOffByTag powers off Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerOffByTag(ctx context.Context, 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(ctx, tag, request) } @@ -84,7 +84,7 @@ func (s *DropletActionsServiceOp) PowerOn(ctx context.Context, id int) (*Action, } // PowerOnByTag powers on Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerOnByTag(ctx context.Context, 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(ctx, tag, request) } @@ -96,7 +96,7 @@ func (s *DropletActionsServiceOp) PowerCycle(ctx context.Context, id int) (*Acti } // PowerCycleByTag power cycles Droplets matched by a Tag. -func (s *DropletActionsServiceOp) PowerCycleByTag(ctx context.Context, 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(ctx, tag, request) } @@ -149,7 +149,7 @@ func (s *DropletActionsServiceOp) Snapshot(ctx context.Context, id int, name str } // SnapshotByTag snapshots Droplets matched by a Tag. -func (s *DropletActionsServiceOp) SnapshotByTag(ctx context.Context, 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, @@ -165,7 +165,7 @@ func (s *DropletActionsServiceOp) EnableBackups(ctx context.Context, id int) (*A } // EnableBackupsByTag enables backups for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnableBackupsByTag(ctx context.Context, 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(ctx, tag, request) } @@ -177,7 +177,7 @@ func (s *DropletActionsServiceOp) DisableBackups(ctx context.Context, id int) (* } // DisableBackupsByTag disables backups for Droplet matched by a Tag. -func (s *DropletActionsServiceOp) DisableBackupsByTag(ctx context.Context, 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(ctx, tag, request) } @@ -213,7 +213,7 @@ func (s *DropletActionsServiceOp) EnableIPv6(ctx context.Context, id int) (*Acti } // EnableIPv6ByTag enables IPv6 for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnableIPv6ByTag(ctx context.Context, 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(ctx, tag, request) } @@ -225,7 +225,7 @@ func (s *DropletActionsServiceOp) EnablePrivateNetworking(ctx context.Context, i } // EnablePrivateNetworkingByTag enables private networking for Droplets matched by a Tag. -func (s *DropletActionsServiceOp) EnablePrivateNetworkingByTag(ctx context.Context, 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(ctx, tag, request) } @@ -261,7 +261,7 @@ func (s *DropletActionsServiceOp) doAction(ctx context.Context, id int, request return root.Event, resp, err } -func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, 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") } @@ -277,13 +277,13 @@ func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, tag string, return nil, nil, err } - root := new(actionRoot) + root := new(actionsRoot) resp, err := s.client.Do(ctx, req, root) if err != nil { return nil, resp, err } - return root.Event, resp, err + return root.Actions, resp, err } // Get an action for a particular Droplet by id. diff --git a/vendor/github.com/digitalocean/godo/firewalls.go b/vendor/github.com/digitalocean/godo/firewalls.go new file mode 100644 index 000000000..661f944f6 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/firewalls.go @@ -0,0 +1,263 @@ +package godo + +import ( + "path" + "strconv" + + "github.com/digitalocean/godo/context" +) + +const firewallsBasePath = "/v2/firewalls" + +// FirewallsService is an interface for managing Firewalls with the DigitalOcean API. +// See: https://developers.digitalocean.com/documentation/documentation/v2/#firewalls +type FirewallsService interface { + Get(context.Context, string) (*Firewall, *Response, error) + Create(context.Context, *FirewallRequest) (*Firewall, *Response, error) + Update(context.Context, string, *FirewallRequest) (*Firewall, *Response, error) + Delete(context.Context, string) (*Response, error) + List(context.Context, *ListOptions) ([]Firewall, *Response, error) + ListByDroplet(context.Context, int, *ListOptions) ([]Firewall, *Response, error) + AddDroplets(context.Context, string, ...int) (*Response, error) + RemoveDroplets(context.Context, string, ...int) (*Response, error) + AddTags(context.Context, string, ...string) (*Response, error) + RemoveTags(context.Context, string, ...string) (*Response, error) + AddRules(context.Context, string, *FirewallRulesRequest) (*Response, error) + RemoveRules(context.Context, string, *FirewallRulesRequest) (*Response, error) +} + +// FirewallsServiceOp handles communication with Firewalls methods of the DigitalOcean API. +type FirewallsServiceOp struct { + client *Client +} + +// Firewall represents a DigitalOcean Firewall configuration. +type Firewall struct { + ID string `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + InboundRules []InboundRule `json:"inbound_rules"` + OutboundRules []OutboundRule `json:"outbound_rules"` + DropletIDs []int `json:"droplet_ids"` + Tags []string `json:"tags"` + Created string `json:"created_at"` + PendingChanges []PendingChange `json:"pending_changes"` +} + +// String creates a human-readable description of a Firewall. +func (fw Firewall) String() string { + return Stringify(fw) +} + +// FirewallRequest represents the configuration to be applied to an existing or a new Firewall. +type FirewallRequest struct { + Name string `json:"name"` + InboundRules []InboundRule `json:"inbound_rules"` + OutboundRules []OutboundRule `json:"outbound_rules"` + DropletIDs []int `json:"droplet_ids"` + Tags []string `json:"tags"` +} + +// FirewallRulesRequest represents rules configuration to be applied to an existing Firewall. +type FirewallRulesRequest struct { + InboundRules []InboundRule `json:"inbound_rules"` + OutboundRules []OutboundRule `json:"outbound_rules"` +} + +// InboundRule represents a DigitalOcean Firewall inbound rule. +type InboundRule struct { + Protocol string `json:"protocol,omitempty"` + PortRange string `json:"ports,omitempty"` + Sources *Sources `json:"sources"` +} + +// OutboundRule represents a DigitalOcean Firewall outbound rule. +type OutboundRule struct { + Protocol string `json:"protocol,omitempty"` + PortRange string `json:"ports,omitempty"` + Destinations *Destinations `json:"destinations"` +} + +// Sources represents a DigitalOcean Firewall InboundRule sources. +type Sources struct { + Addresses []string `json:"addresses,omitempty"` + Tags []string `json:"tags,omitempty"` + DropletIDs []int `json:"droplet_ids,omitempty"` + LoadBalancerUIDs []string `json:"load_balancer_uids,omitempty"` +} + +// PendingChange represents a DigitalOcean Firewall status details. +type PendingChange struct { + DropletID int `json:"droplet_id,omitempty"` + Removing bool `json:"removing,omitempty"` + Status string `json:"status,omitempty"` +} + +// Destinations represents a DigitalOcean Firewall OutboundRule destinations. +type Destinations struct { + Addresses []string `json:"addresses,omitempty"` + Tags []string `json:"tags,omitempty"` + DropletIDs []int `json:"droplet_ids,omitempty"` + LoadBalancerUIDs []string `json:"load_balancer_uids,omitempty"` +} + +var _ FirewallsService = &FirewallsServiceOp{} + +// Get an existing Firewall by its identifier. +func (fw *FirewallsServiceOp) Get(ctx context.Context, fID string) (*Firewall, *Response, error) { + path := path.Join(firewallsBasePath, fID) + + req, err := fw.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(firewallRoot) + resp, err := fw.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Firewall, resp, err +} + +// Create a new Firewall with a given configuration. +func (fw *FirewallsServiceOp) Create(ctx context.Context, fr *FirewallRequest) (*Firewall, *Response, error) { + req, err := fw.client.NewRequest(ctx, "POST", firewallsBasePath, fr) + if err != nil { + return nil, nil, err + } + + root := new(firewallRoot) + resp, err := fw.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Firewall, resp, err +} + +// Update an existing Firewall with new configuration. +func (fw *FirewallsServiceOp) Update(ctx context.Context, fID string, fr *FirewallRequest) (*Firewall, *Response, error) { + path := path.Join(firewallsBasePath, fID) + + req, err := fw.client.NewRequest(ctx, "PUT", path, fr) + if err != nil { + return nil, nil, err + } + + root := new(firewallRoot) + resp, err := fw.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Firewall, resp, err +} + +// Delete a Firewall by its identifier. +func (fw *FirewallsServiceOp) Delete(ctx context.Context, fID string) (*Response, error) { + path := path.Join(firewallsBasePath, fID) + return fw.createAndDoReq(ctx, "DELETE", path, nil) +} + +// List Firewalls. +func (fw *FirewallsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Firewall, *Response, error) { + path, err := addOptions(firewallsBasePath, opt) + if err != nil { + return nil, nil, err + } + + return fw.listHelper(ctx, path) +} + +// ListByDroplet Firewalls. +func (fw *FirewallsServiceOp) ListByDroplet(ctx context.Context, dID int, opt *ListOptions) ([]Firewall, *Response, error) { + basePath := path.Join(dropletBasePath, strconv.Itoa(dID), "firewalls") + path, err := addOptions(basePath, opt) + if err != nil { + return nil, nil, err + } + + return fw.listHelper(ctx, path) +} + +// AddDroplets to a Firewall. +func (fw *FirewallsServiceOp) AddDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "droplets") + return fw.createAndDoReq(ctx, "POST", path, &dropletsRequest{IDs: dropletIDs}) +} + +// RemoveDroplets from a Firewall. +func (fw *FirewallsServiceOp) RemoveDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "droplets") + return fw.createAndDoReq(ctx, "DELETE", path, &dropletsRequest{IDs: dropletIDs}) +} + +// AddTags to a Firewall. +func (fw *FirewallsServiceOp) AddTags(ctx context.Context, fID string, tags ...string) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "tags") + return fw.createAndDoReq(ctx, "POST", path, &tagsRequest{Tags: tags}) +} + +// RemoveTags from a Firewall. +func (fw *FirewallsServiceOp) RemoveTags(ctx context.Context, fID string, tags ...string) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "tags") + return fw.createAndDoReq(ctx, "DELETE", path, &tagsRequest{Tags: tags}) +} + +// AddRules to a Firewall. +func (fw *FirewallsServiceOp) AddRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "rules") + return fw.createAndDoReq(ctx, "POST", path, rr) +} + +// RemoveRules from a Firewall. +func (fw *FirewallsServiceOp) RemoveRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) { + path := path.Join(firewallsBasePath, fID, "rules") + return fw.createAndDoReq(ctx, "DELETE", path, rr) +} + +type dropletsRequest struct { + IDs []int `json:"droplet_ids"` +} + +type tagsRequest struct { + Tags []string `json:"tags"` +} + +type firewallRoot struct { + Firewall *Firewall `json:"firewall"` +} + +type firewallsRoot struct { + Firewalls []Firewall `json:"firewalls"` + Links *Links `json:"links"` +} + +func (fw *FirewallsServiceOp) createAndDoReq(ctx context.Context, method, path string, v interface{}) (*Response, error) { + req, err := fw.client.NewRequest(ctx, method, path, v) + if err != nil { + return nil, err + } + + return fw.client.Do(ctx, req, nil) +} + +func (fw *FirewallsServiceOp) listHelper(ctx context.Context, path string) ([]Firewall, *Response, error) { + req, err := fw.client.NewRequest(ctx, "GET", path, nil) + if err != nil { + return nil, nil, err + } + + root := new(firewallsRoot) + resp, err := fw.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + if l := root.Links; l != nil { + resp.Links = l + } + + return root.Firewalls, resp, err +} diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index 5c87c8c09..9dfef2a31 100644 --- a/vendor/github.com/digitalocean/godo/godo.go +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -19,7 +19,7 @@ import ( ) const ( - libraryVersion = "1.0.0" + libraryVersion = "1.1.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" @@ -63,6 +63,7 @@ type Client struct { Tags TagsService LoadBalancers LoadBalancersService Certificates CertificatesService + Firewalls FirewallsService // Optional function called after every successful request made to the DO APIs onRequestCompleted RequestCompletionCallback @@ -173,6 +174,7 @@ func NewClient(httpClient *http.Client) *Client { c.Tags = &TagsServiceOp{client: c} c.LoadBalancers = &LoadBalancersServiceOp{client: c} c.Certificates = &CertificatesServiceOp{client: c} + c.Firewalls = &FirewallsServiceOp{client: c} return c } diff --git a/vendor/vendor.json b/vendor/vendor.json index a06cd3b59..efd685e28 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1373,17 +1373,21 @@ "revisionTime": "2016-06-17T17:01:58Z" }, { - "checksumSHA1": "uuenX+nAyhQfYqedBhQ+yhBh1mA=", + "checksumSHA1": "tnm1kZ74wERuTfq7f1i56KnU0fw=", "comment": "v0.9.0-20-gf75d769", "path": "github.com/digitalocean/godo", - "revision": "83908b1ddd666d08a9b020c697b55ae3895be2fd", - "revisionTime": "2017-04-26T22:25:10Z" + "revision": "4fa9e9d999007b447089056a1c581b5594f0f851", + "revisionTime": "2017-06-06T13:50:45Z", + "version": "v1.1.0", + "versionExact": "v1.1.0" }, { "checksumSHA1": "YpWoCsk+u9H5ctWNKKSVPf4b2as=", "path": "github.com/digitalocean/godo/context", - "revision": "83908b1ddd666d08a9b020c697b55ae3895be2fd", - "revisionTime": "2017-04-26T22:25:10Z" + "revision": "4fa9e9d999007b447089056a1c581b5594f0f851", + "revisionTime": "2017-06-06T13:50:45Z", + "version": "v1.1.0", + "versionExact": "v1.1.0" }, { "checksumSHA1": "1PlWp7ZA8IBK6J6XcIwRpoSTNoc=",