Vendor main dependencies.
This commit is contained in:
parent
49a09ab7dd
commit
dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions
22
vendor/github.com/timewasted/linode/LICENSE
generated
vendored
Normal file
22
vendor/github.com/timewasted/linode/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2016, Ryan Rogers
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
69
vendor/github.com/timewasted/linode/dns/dns.go
generated
vendored
Normal file
69
vendor/github.com/timewasted/linode/dns/dns.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/timewasted/linode"
|
||||
)
|
||||
|
||||
type (
|
||||
// DNS represents the interface to the DNS portion of Linode's API.
|
||||
DNS struct {
|
||||
linode *linode.Linode
|
||||
}
|
||||
)
|
||||
|
||||
// New returns a pointer to a new DNS object.
|
||||
func New(apiKey string) *DNS {
|
||||
return &DNS{
|
||||
linode: linode.New(apiKey),
|
||||
}
|
||||
}
|
||||
|
||||
// FromLinode returns a pointer to a new DNS object, using the provided Linode
|
||||
// instance as backing.
|
||||
func FromLinode(l *linode.Linode) *DNS {
|
||||
return &DNS{
|
||||
linode: l,
|
||||
}
|
||||
}
|
||||
|
||||
// ToLinode returns a pointer to the internal Linode object.
|
||||
func (d *DNS) ToLinode() *linode.Linode {
|
||||
return d.linode
|
||||
}
|
||||
|
||||
// GetDomains executes the "domain.list" API call. When domainID is nil, this
|
||||
// will return a list of domains. Otherwise, it will return only the domain
|
||||
// specified by domainID.
|
||||
func (d *DNS) GetDomains(domainId interface{}) ([]*Domain, error) {
|
||||
params := linode.Parameters{}
|
||||
if domainId != nil {
|
||||
id, ok := domainId.(int)
|
||||
if ok {
|
||||
params.Set("DomainID", strconv.Itoa(id))
|
||||
}
|
||||
}
|
||||
|
||||
var list []*Domain
|
||||
_, err := d.linode.Request("domain.list", params, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// GetDomainResources executes the "domain.resource.list" API call. This will
|
||||
// return a list of domain resources associated with the specified domainID.
|
||||
func (d *DNS) GetDomainResources(domainID int) ([]*Resource, error) {
|
||||
params := linode.Parameters{
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
}
|
||||
|
||||
var list []*Resource
|
||||
_, err := d.linode.Request("domain.resource.list", params, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
63
vendor/github.com/timewasted/linode/dns/domain.go
generated
vendored
Normal file
63
vendor/github.com/timewasted/linode/dns/domain.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/timewasted/linode"
|
||||
)
|
||||
|
||||
type (
|
||||
// Domain represents a domain.
|
||||
Domain struct {
|
||||
AXFR_IPs string `json:"AXFR_IPS"`
|
||||
Description string `json:"DESCRIPTION"`
|
||||
Domain string `json:"DOMAIN"`
|
||||
DomainID int `json:"DOMAINID"`
|
||||
Expire_Sec int `json:"EXPIRE_SEC"`
|
||||
LPM_DisplayGroup string `json:"LPM_DISPLAYGROUP"`
|
||||
Master_IPs string `json:"MASTER_IPS"`
|
||||
Refresh_Sec int `json:"REFRESH_SEC"`
|
||||
Retry_Sec int `json:"RETRY_SEC"`
|
||||
SOA_Email string `json:"SOA_EMAIL"`
|
||||
Status int `json:"STATUS"`
|
||||
TTL_Sec int `json:"TTL_SEC"`
|
||||
Type string `json:"TYPE"`
|
||||
}
|
||||
// DomainResponse represents the response to a create, update, or
|
||||
// delete domain API call.
|
||||
DomainResponse struct {
|
||||
DomainID int `json:"DomainID"`
|
||||
}
|
||||
)
|
||||
|
||||
// DeleteDomain executes the "domain.delete" API call. This will delete the
|
||||
// domain specified by domainID.
|
||||
func (d *DNS) DeleteDomain(domainID int) (*DomainResponse, error) {
|
||||
params := linode.Parameters{
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
}
|
||||
var response *DomainResponse
|
||||
_, err := d.linode.Request("domain.delete", params, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// GetDomain returns the specified domain. This search is not case-sensitive.
|
||||
func (d *DNS) GetDomain(domain string) (*Domain, error) {
|
||||
list, err := d.GetDomains(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range list {
|
||||
if strings.EqualFold(d.Domain, domain) {
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, linode.NewError(errors.New("dns: requested domain not found"))
|
||||
}
|
228
vendor/github.com/timewasted/linode/dns/resource.go
generated
vendored
Normal file
228
vendor/github.com/timewasted/linode/dns/resource.go
generated
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/timewasted/linode"
|
||||
)
|
||||
|
||||
type (
|
||||
// Resource represents a domain resource.
|
||||
Resource struct {
|
||||
DomainID int `json:"DOMAINID"`
|
||||
Name string `json:"NAME"`
|
||||
Port interface{} `json:"PORT"`
|
||||
Priority interface{} `json:"PRIORITY"`
|
||||
Protocol string `json:"PROTOCOL"`
|
||||
ResourceID int `json:"RESOURCEID"`
|
||||
Target string `json:"TARGET"`
|
||||
TTL_Sec int `json:"TTL_SEC"`
|
||||
Type string `json:"TYPE"`
|
||||
Weight interface{} `json:"WEIGHT"`
|
||||
}
|
||||
// ResourceResponse represents the response to a create, update, or
|
||||
// delete resource API call.
|
||||
ResourceResponse struct {
|
||||
ResourceID int `json:"ResourceID"`
|
||||
}
|
||||
)
|
||||
|
||||
// CreateDomainResourceA executes the "domain.resource.create" API call. This
|
||||
// will create a new "A" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceA(domainID int, name, target string, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "A",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceAAAA executes the "domain.resource.create" API call.
|
||||
// This will create a new "AAAA" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceAAAA(domainID int, name, target string, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "AAAA",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceCNAME executes the "domain.resource.create" API call.
|
||||
// This will create a new "CNAME" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceCNAME(domainID int, name, target string, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "CNAME",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceMX executes the "domain.resource.create" API call. This
|
||||
// will create a new "MX" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceMX(domainID int, name, target string, priority, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "MX",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"Priority": strconv.Itoa(priority),
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceNS executes the "domain.resource.create" API call. This
|
||||
// will create a new "NS" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceNS(domainID int, name, target string, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "NS",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceSRV executes the "domain.resource.create" API call. This
|
||||
// will create a new "SRV" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceSRV(domainID int, name, target, protocol string, priority, ttlSeconds int) (*ResourceResponse, error) {
|
||||
// FIXME: This probably also needs weight and port. Weight has a valid
|
||||
// range of 0-255, while port is 0-65535.
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "SRV",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"Protocol": protocol,
|
||||
"Priority": strconv.Itoa(priority),
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResourceTXT executes the "domain.resource.create" API call. This
|
||||
// will create a new "TXT" resource using the specified parameters.
|
||||
func (d *DNS) CreateDomainResourceTXT(domainID int, name, target string, ttlSeconds int) (*ResourceResponse, error) {
|
||||
return d.createDomainResource(linode.Parameters{
|
||||
"Type": "TXT",
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"Name": name,
|
||||
"Target": target,
|
||||
"TTL_Sec": strconv.Itoa(ttlSeconds),
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDomainResource executes the "domain.resource.create" API call. This
|
||||
// will create a new resource using the values specified in the resource.
|
||||
func (d *DNS) CreateDomainResource(r *Resource) (*ResourceResponse, error) {
|
||||
// Ensure that the resource has a name.
|
||||
if len(r.Name) == 0 {
|
||||
return nil, linode.NewError(errors.New("dns: creating a resource requires Name be specified"))
|
||||
}
|
||||
|
||||
// Initialize parameters that are shared across resource types.
|
||||
params := linode.Parameters{
|
||||
"DomainID": strconv.Itoa(r.DomainID),
|
||||
"Name": r.Name,
|
||||
"TTL_Sec": strconv.Itoa(r.TTL_Sec),
|
||||
}
|
||||
|
||||
// Ensure that the resource has a valid, supported type.
|
||||
r.Type = strings.ToUpper(r.Type)
|
||||
switch r.Type {
|
||||
case "A":
|
||||
case "AAAA":
|
||||
case "CNAME":
|
||||
case "MX":
|
||||
case "NS":
|
||||
case "TXT":
|
||||
// No further processing required for these types.
|
||||
break
|
||||
case "SRV":
|
||||
// Ensure that SRV has a protocol.
|
||||
if len(r.Protocol) == 0 {
|
||||
return nil, linode.NewError(errors.New("dns: creating a SRV resource requires Priority be specified"))
|
||||
}
|
||||
params.Set("Protocol", r.Protocol)
|
||||
break
|
||||
default:
|
||||
// Unsupported type.
|
||||
return nil, linode.NewError(errors.New("dns: can not create resource of unsupported type: " + r.Type))
|
||||
}
|
||||
params.Set("Type", r.Type)
|
||||
|
||||
// Ensure that the resource has a valid target.
|
||||
if len(r.Target) == 0 {
|
||||
return nil, linode.NewError(errors.New("dns: creating a resource requires Target to be specified"))
|
||||
}
|
||||
params.Set("Target", r.Target)
|
||||
|
||||
if r.Name == "MX" || r.Name == "SRV" {
|
||||
// If priority is defined, ensure that it's valid.
|
||||
if r.Priority != nil {
|
||||
priority, ok := r.Priority.(int)
|
||||
if !ok {
|
||||
return nil, linode.NewError(errors.New("dns: priority must be specified as an int"))
|
||||
}
|
||||
if priority < 0 || priority > 255 {
|
||||
return nil, linode.NewError(errors.New("dns: priority must be within the range of 0-255"))
|
||||
}
|
||||
r.Priority = priority
|
||||
params.Set("Priority", strconv.Itoa(priority))
|
||||
}
|
||||
}
|
||||
|
||||
// Create the resource.
|
||||
return d.createDomainResource(params)
|
||||
}
|
||||
|
||||
// createDomainResource executes the "domain.resource.create" API call. This
|
||||
// will create a resource using the specified parameters.
|
||||
func (d *DNS) createDomainResource(params linode.Parameters) (*ResourceResponse, error) {
|
||||
var response *ResourceResponse
|
||||
_, err := d.linode.Request("domain.resource.create", params, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// DeleteDomainResource executes the "domain.resource.delete" API call. This
|
||||
// will delete the resource specified by resourceID under the domain specified
|
||||
// by domainID.
|
||||
func (d *DNS) DeleteDomainResource(domainID, resourceID int) (*ResourceResponse, error) {
|
||||
params := linode.Parameters{
|
||||
"DomainID": strconv.Itoa(domainID),
|
||||
"ResourceID": strconv.Itoa(resourceID),
|
||||
}
|
||||
var response *ResourceResponse
|
||||
_, err := d.linode.Request("domain.resource.delete", params, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// GetResourceByType returns a list of domain resources that match the specified
|
||||
// type. This search is not case-sensitive.
|
||||
func (d *DNS) GetResourcesByType(domainID int, res_type string) ([]*Resource, error) {
|
||||
resources, err := d.GetDomainResources(domainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := []*Resource{}
|
||||
for _, r := range resources {
|
||||
if strings.EqualFold(r.Type, res_type) {
|
||||
list = append(list, r)
|
||||
}
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
73
vendor/github.com/timewasted/linode/errors.go
generated
vendored
Normal file
73
vendor/github.com/timewasted/linode/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
package linode
|
||||
|
||||
const (
|
||||
ERR_OK = 0
|
||||
ERR_BAD_REQUEST = 1
|
||||
ERR_NO_ACTION_REQUESTED = 2
|
||||
ERR_CLASS_DOES_NOT_EXIST = 3
|
||||
ERR_AUTHENTICATION_FAILED = 4
|
||||
ERR_OBJECT_NOT_FOUND = 5
|
||||
ERR_REQUIRED_PROPERTY_MISSING = 6
|
||||
ERR_INVALID_PROPERTY = 7
|
||||
ERR_DATA_VALIDATION_FAILED = 8
|
||||
ERR_METHOD_NOT_IMPLEMENTED = 9
|
||||
ERR_TOO_MANY_BATCHED_REQUESTS = 10
|
||||
ERR_REQUEST_INVALID_JSON = 11
|
||||
ERR_BATCH_TIMED_OUT = 12
|
||||
ERR_PERMISSION_DENIED = 13
|
||||
ERR_API_RATE_LIMIT_EXCEEDED = 14
|
||||
|
||||
ERR_CREDIT_CARD_CHARGE_FAILED = 30
|
||||
ERR_CREDIT_CARD_EXPIRED = 31
|
||||
|
||||
ERR_LINODES_PER_HOUR_LIMIT_EXCEEDED = 40
|
||||
ERR_LINODE_STILL_HAS_DISKS = 41
|
||||
)
|
||||
|
||||
type (
|
||||
// apiError represents an error as returned by the API.
|
||||
apiError struct {
|
||||
code int
|
||||
msg string
|
||||
}
|
||||
// Error represents an error, either API related or not.
|
||||
Error struct {
|
||||
apiError *apiError
|
||||
Err error
|
||||
}
|
||||
)
|
||||
|
||||
// NewError returns an instance of Error which represents a non-API error.
|
||||
func NewError(err error) *Error {
|
||||
return &Error{
|
||||
apiError: nil,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// NewApiError returns an instance of Error which represents an API error.
|
||||
func NewApiError(code int, msg string) *Error {
|
||||
return &Error{
|
||||
apiError: &apiError{
|
||||
code: code,
|
||||
msg: msg,
|
||||
},
|
||||
Err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements the Error() method of the error interface.
|
||||
func (e *Error) Error() string {
|
||||
if e.apiError != nil {
|
||||
return e.apiError.msg
|
||||
}
|
||||
if e.Err == nil {
|
||||
return ""
|
||||
}
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// IsApiError returns true if the error is an API error, or false otherwise.
|
||||
func (e *Error) IsApiError() bool {
|
||||
return e.apiError != nil
|
||||
}
|
197
vendor/github.com/timewasted/linode/linode.go
generated
vendored
Normal file
197
vendor/github.com/timewasted/linode/linode.go
generated
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
package linode
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// ApiEndpoint is the base URL for the Linode API endpoint.
|
||||
ApiEndpoint = "https://api.linode.com/"
|
||||
)
|
||||
|
||||
// The following are keys related to working with the Linode API.
|
||||
const (
|
||||
apiAction = "api_action"
|
||||
apiKey = "api_key"
|
||||
apiRequestArray = "api_requestArray"
|
||||
)
|
||||
|
||||
var (
|
||||
// client is an HTTP client which will be used for making API calls.
|
||||
client = &http.Client{
|
||||
Transport: &http.Transport{},
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
// Action represents an action to be performed.
|
||||
Action struct {
|
||||
parameters Parameters
|
||||
result interface{}
|
||||
}
|
||||
// Linode represents the interface to the Linode API.
|
||||
Linode struct {
|
||||
apiEndpoint string
|
||||
apiKey string
|
||||
actions []Action
|
||||
}
|
||||
// ResponseError represents an error returned by an API call.
|
||||
ResponseError struct {
|
||||
Code int `json:"ERRORCODE"`
|
||||
Message string `json:"ERRORMESSAGE"`
|
||||
}
|
||||
// Response represents the response to an API call. Data is defined as
|
||||
// an interface, because each API call will return a different response.
|
||||
// It is the user's responsibility to turn it into something useful.
|
||||
Response struct {
|
||||
Action string `json:"ACTION"`
|
||||
RawData json.RawMessage `json:"DATA"`
|
||||
Errors []ResponseError `json:"ERRORARRAY"`
|
||||
Data interface{} `json:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
// New returns a pointer to a new Linode object.
|
||||
func New(apiKey string) *Linode {
|
||||
return &Linode{
|
||||
apiEndpoint: ApiEndpoint,
|
||||
apiKey: apiKey,
|
||||
actions: []Action{},
|
||||
}
|
||||
}
|
||||
|
||||
// SetEndpoint sets the endpoint that all API requests will be sent to. This
|
||||
// should only be used for testing/debugging purposes!
|
||||
func (l *Linode) SetEndpoint(endpoint string) {
|
||||
l.apiEndpoint = endpoint
|
||||
}
|
||||
|
||||
// Request performs a single API operation and returns the full response.
|
||||
func (l *Linode) Request(action string, params Parameters, result interface{}) (*Response, error) {
|
||||
// Initialize the request.
|
||||
req, err := http.NewRequest("GET", l.apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
params.Set(apiAction, action)
|
||||
params.Set(apiKey, l.apiKey)
|
||||
req.URL.RawQuery = params.Encode()
|
||||
|
||||
// Make the request.
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, NewError(fmt.Errorf("Expected status code %d, received %d", http.StatusOK, resp.StatusCode))
|
||||
}
|
||||
|
||||
// Decode the response.
|
||||
var response *Response
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
if err = decoder.Decode(&response); err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
|
||||
// Decode the raw data into action-specific data.
|
||||
if result != nil {
|
||||
if err = json.Unmarshal(response.RawData, &result); err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
response.Data = result
|
||||
}
|
||||
|
||||
// If we have errors in the response, return both the response as well
|
||||
// as an API error.
|
||||
if len(response.Errors) != 0 {
|
||||
return response, NewApiError(response.Errors[0].Code, response.Errors[0].Message)
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// Batch adds a new action to the batch request to be performed.
|
||||
func (l *Linode) Batch(action string, params Parameters, result interface{}) {
|
||||
params.Set(apiAction, action)
|
||||
l.actions = append(l.actions, Action{
|
||||
parameters: params,
|
||||
result: result,
|
||||
})
|
||||
}
|
||||
|
||||
// Process performs all batch actions that have been added.
|
||||
func (l *Linode) Process() ([]*Response, error) {
|
||||
// Quickly handle the case where we have zero or one actions to perform.
|
||||
count := len(l.actions)
|
||||
if count == 0 {
|
||||
return nil, NewError(errors.New("linode: request must contain at least one action"))
|
||||
}
|
||||
defer l.Reset()
|
||||
if count == 1 {
|
||||
resp, err := l.Request(l.actions[0].parameters.Get(apiAction), l.actions[0].parameters, l.actions[0].result)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*Response{resp}, err
|
||||
}
|
||||
|
||||
// Prepare the parameters.
|
||||
params := make([]Parameters, 0, len(l.actions))
|
||||
for _, action := range l.actions {
|
||||
params = append(params, action.parameters)
|
||||
}
|
||||
jsonParams, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
|
||||
// Initialize the request.
|
||||
req, err := http.NewRequest("GET", l.apiEndpoint, nil)
|
||||
if err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
query := Parameters{
|
||||
apiKey: l.apiKey,
|
||||
apiAction: "batch",
|
||||
apiRequestArray: string(jsonParams),
|
||||
}
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
// Do the request.
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Decode the response.
|
||||
var response []*Response
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
if err = decoder.Decode(&response); err != nil {
|
||||
return nil, NewError(err)
|
||||
}
|
||||
|
||||
// Decode the raw data into action-specific data.
|
||||
// FIXME: This whole block needs error handling, and I think since this
|
||||
// is handling multiple actions, it should probably handle errors on a
|
||||
// per-action basis.
|
||||
for index, action := range response {
|
||||
if l.actions[index].result == nil {
|
||||
continue
|
||||
}
|
||||
if err = json.Unmarshal(action.RawData, &l.actions[index].result); err != nil {
|
||||
continue
|
||||
}
|
||||
response[index].Data = l.actions[index].result
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// Reset clears the list of actions to be performed.
|
||||
func (l *Linode) Reset() {
|
||||
l.actions = []Action{}
|
||||
}
|
54
vendor/github.com/timewasted/linode/parameters.go
generated
vendored
Normal file
54
vendor/github.com/timewasted/linode/parameters.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
package linode
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type (
|
||||
// Parameters represents the parameters that are passed for an API call.
|
||||
Parameters map[string]string
|
||||
)
|
||||
|
||||
// Get gets the parameter associated with the given key. If no parameter is
|
||||
// associated with the key, Get returns the empty string.
|
||||
func (p Parameters) Get(key string) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
value, ok := p[key]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// Set sets the key to value. It replaces any existing value.
|
||||
func (p Parameters) Set(key, value string) {
|
||||
p[key] = value
|
||||
}
|
||||
|
||||
// Del deletes the parameter associated with key.
|
||||
func (p Parameters) Del(key string) {
|
||||
delete(p, key)
|
||||
}
|
||||
|
||||
// Encode encodes the parameters into "URL encoded" form ("bar=baz&foo=quux")
|
||||
// sorted by key.
|
||||
func (p Parameters) Encode() string {
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(p))
|
||||
for k := range p {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(url.QueryEscape(k) + "=")
|
||||
buf.WriteString(url.QueryEscape(p[k]))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue