lego/vendor/github.com/linode/linodego/client.go
2019-06-24 20:08:55 +02:00

257 lines
10 KiB
Go

package linodego
import (
"context"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"
"gopkg.in/resty.v1"
)
const (
// APIHost Linode API hostname
APIHost = "api.linode.com"
// APIVersion Linode API version
APIVersion = "v4"
// APIProto connect to API with http(s)
APIProto = "https"
// Version of linodego
Version = "0.7.0"
// APIEnvVar environment var to check for API token
APIEnvVar = "LINODE_TOKEN"
// APISecondsPerPoll how frequently to poll for new Events or Status in WaitFor functions
APISecondsPerPoll = 3
// DefaultUserAgent is the default User-Agent sent in HTTP request headers
DefaultUserAgent = "linodego " + Version + " https://github.com/linode/linodego"
)
var (
envDebug = false
)
// Client is a wrapper around the Resty client
type Client struct {
resty *resty.Client
userAgent string
resources map[string]*Resource
debug bool
millisecondsPerPoll time.Duration
Images *Resource
InstanceDisks *Resource
InstanceConfigs *Resource
InstanceSnapshots *Resource
InstanceIPs *Resource
InstanceVolumes *Resource
Instances *Resource
IPAddresses *Resource
IPv6Pools *Resource
IPv6Ranges *Resource
Regions *Resource
StackScripts *Resource
Volumes *Resource
Kernels *Resource
Types *Resource
Domains *Resource
DomainRecords *Resource
Longview *Resource
LongviewClients *Resource
LongviewSubscriptions *Resource
NodeBalancers *Resource
NodeBalancerConfigs *Resource
NodeBalancerNodes *Resource
SSHKeys *Resource
Tickets *Resource
Tokens *Resource
Token *Resource
Account *Resource
Invoices *Resource
InvoiceItems *Resource
Events *Resource
Notifications *Resource
Profile *Resource
Managed *Resource
Tags *Resource
Users *Resource
}
func init() {
// Wether or not we will enable Resty debugging output
if apiDebug, ok := os.LookupEnv("LINODE_DEBUG"); ok {
if parsed, err := strconv.ParseBool(apiDebug); err == nil {
envDebug = parsed
log.Println("[INFO] LINODE_DEBUG being set to", envDebug)
} else {
log.Println("[WARN] LINODE_DEBUG should be an integer, 0 or 1")
}
}
}
// SetUserAgent sets a custom user-agent for HTTP requests
func (c *Client) SetUserAgent(ua string) *Client {
c.userAgent = ua
c.resty.SetHeader("User-Agent", c.userAgent)
return c
}
// R wraps resty's R method
func (c *Client) R(ctx context.Context) *resty.Request {
return c.resty.R().
ExpectContentType("application/json").
SetHeader("Content-Type", "application/json").
SetContext(ctx).
SetError(APIError{})
}
// SetDebug sets the debug on resty's client
func (c *Client) SetDebug(debug bool) *Client {
c.debug = debug
c.resty.SetDebug(debug)
return c
}
// SetBaseURL sets the base URL of the Linode v4 API (https://api.linode.com/v4)
func (c *Client) SetBaseURL(url string) *Client {
c.resty.SetHostURL(url)
return c
}
// SetPollDelay sets the number of milliseconds to wait between events or status polls.
// Affects all WaitFor* functions.
func (c *Client) SetPollDelay(delay time.Duration) *Client {
c.millisecondsPerPoll = delay
return c
}
// Resource looks up a resource by name
func (c Client) Resource(resourceName string) *Resource {
selectedResource, ok := c.resources[resourceName]
if !ok {
log.Fatalf("Could not find resource named '%s', exiting.", resourceName)
}
return selectedResource
}
// NewClient factory to create new Client struct
func NewClient(hc *http.Client) (client Client) {
restyClient := resty.NewWithClient(hc)
client.resty = restyClient
client.SetUserAgent(DefaultUserAgent)
client.SetBaseURL(fmt.Sprintf("%s://%s/%s", APIProto, APIHost, APIVersion))
client.SetPollDelay(1000 * APISecondsPerPoll)
resources := map[string]*Resource{
stackscriptsName: NewResource(&client, stackscriptsName, stackscriptsEndpoint, false, Stackscript{}, StackscriptsPagedResponse{}),
imagesName: NewResource(&client, imagesName, imagesEndpoint, false, Image{}, ImagesPagedResponse{}),
instancesName: NewResource(&client, instancesName, instancesEndpoint, false, Instance{}, InstancesPagedResponse{}),
instanceDisksName: NewResource(&client, instanceDisksName, instanceDisksEndpoint, true, InstanceDisk{}, InstanceDisksPagedResponse{}),
instanceConfigsName: NewResource(&client, instanceConfigsName, instanceConfigsEndpoint, true, InstanceConfig{}, InstanceConfigsPagedResponse{}),
instanceSnapshotsName: NewResource(&client, instanceSnapshotsName, instanceSnapshotsEndpoint, true, InstanceSnapshot{}, nil),
instanceIPsName: NewResource(&client, instanceIPsName, instanceIPsEndpoint, true, InstanceIP{}, nil), // really?
instanceVolumesName: NewResource(&client, instanceVolumesName, instanceVolumesEndpoint, true, nil, InstanceVolumesPagedResponse{}), // really?
ipaddressesName: NewResource(&client, ipaddressesName, ipaddressesEndpoint, false, nil, IPAddressesPagedResponse{}), // really?
ipv6poolsName: NewResource(&client, ipv6poolsName, ipv6poolsEndpoint, false, nil, IPv6PoolsPagedResponse{}), // really?
ipv6rangesName: NewResource(&client, ipv6rangesName, ipv6rangesEndpoint, false, IPv6Range{}, IPv6RangesPagedResponse{}),
regionsName: NewResource(&client, regionsName, regionsEndpoint, false, Region{}, RegionsPagedResponse{}),
volumesName: NewResource(&client, volumesName, volumesEndpoint, false, Volume{}, VolumesPagedResponse{}),
kernelsName: NewResource(&client, kernelsName, kernelsEndpoint, false, LinodeKernel{}, LinodeKernelsPagedResponse{}),
typesName: NewResource(&client, typesName, typesEndpoint, false, LinodeType{}, LinodeTypesPagedResponse{}),
domainsName: NewResource(&client, domainsName, domainsEndpoint, false, Domain{}, DomainsPagedResponse{}),
domainRecordsName: NewResource(&client, domainRecordsName, domainRecordsEndpoint, true, DomainRecord{}, DomainRecordsPagedResponse{}),
longviewName: NewResource(&client, longviewName, longviewEndpoint, false, nil, nil), // really?
longviewclientsName: NewResource(&client, longviewclientsName, longviewclientsEndpoint, false, LongviewClient{}, LongviewClientsPagedResponse{}),
longviewsubscriptionsName: NewResource(&client, longviewsubscriptionsName, longviewsubscriptionsEndpoint, false, LongviewSubscription{}, LongviewSubscriptionsPagedResponse{}),
nodebalancersName: NewResource(&client, nodebalancersName, nodebalancersEndpoint, false, NodeBalancer{}, NodeBalancerConfigsPagedResponse{}),
nodebalancerconfigsName: NewResource(&client, nodebalancerconfigsName, nodebalancerconfigsEndpoint, true, NodeBalancerConfig{}, NodeBalancerConfigsPagedResponse{}),
nodebalancernodesName: NewResource(&client, nodebalancernodesName, nodebalancernodesEndpoint, true, NodeBalancerNode{}, NodeBalancerNodesPagedResponse{}),
notificationsName: NewResource(&client, notificationsName, notificationsEndpoint, false, Notification{}, NotificationsPagedResponse{}),
sshkeysName: NewResource(&client, sshkeysName, sshkeysEndpoint, false, SSHKey{}, SSHKeysPagedResponse{}),
ticketsName: NewResource(&client, ticketsName, ticketsEndpoint, false, Ticket{}, TicketsPagedResponse{}),
tokensName: NewResource(&client, tokensName, tokensEndpoint, false, Token{}, TokensPagedResponse{}),
accountName: NewResource(&client, accountName, accountEndpoint, false, Account{}, nil), // really?
eventsName: NewResource(&client, eventsName, eventsEndpoint, false, Event{}, EventsPagedResponse{}),
invoicesName: NewResource(&client, invoicesName, invoicesEndpoint, false, Invoice{}, InvoicesPagedResponse{}),
invoiceItemsName: NewResource(&client, invoiceItemsName, invoiceItemsEndpoint, true, InvoiceItem{}, InvoiceItemsPagedResponse{}),
profileName: NewResource(&client, profileName, profileEndpoint, false, nil, nil), // really?
managedName: NewResource(&client, managedName, managedEndpoint, false, nil, nil), // really?
tagsName: NewResource(&client, tagsName, tagsEndpoint, false, Tag{}, TagsPagedResponse{}),
usersName: NewResource(&client, usersName, usersEndpoint, false, User{}, UsersPagedResponse{}),
}
client.resources = resources
client.SetDebug(envDebug)
client.Images = resources[imagesName]
client.StackScripts = resources[stackscriptsName]
client.Instances = resources[instancesName]
client.Regions = resources[regionsName]
client.InstanceDisks = resources[instanceDisksName]
client.InstanceConfigs = resources[instanceConfigsName]
client.InstanceSnapshots = resources[instanceSnapshotsName]
client.InstanceIPs = resources[instanceIPsName]
client.InstanceVolumes = resources[instanceVolumesName]
client.IPAddresses = resources[ipaddressesName]
client.IPv6Pools = resources[ipv6poolsName]
client.IPv6Ranges = resources[ipv6rangesName]
client.Volumes = resources[volumesName]
client.Kernels = resources[kernelsName]
client.Types = resources[typesName]
client.Domains = resources[domainsName]
client.DomainRecords = resources[domainRecordsName]
client.Longview = resources[longviewName]
client.LongviewSubscriptions = resources[longviewsubscriptionsName]
client.NodeBalancers = resources[nodebalancersName]
client.NodeBalancerConfigs = resources[nodebalancerconfigsName]
client.NodeBalancerNodes = resources[nodebalancernodesName]
client.Notifications = resources[notificationsName]
client.SSHKeys = resources[sshkeysName]
client.Tickets = resources[ticketsName]
client.Tokens = resources[tokensName]
client.Account = resources[accountName]
client.Events = resources[eventsName]
client.Invoices = resources[invoicesName]
client.Profile = resources[profileName]
client.Managed = resources[managedName]
client.Tags = resources[tagsName]
client.Users = resources[usersName]
return
}
func copyBool(bPtr *bool) *bool {
if bPtr == nil {
return nil
}
var t = *bPtr
return &t
}
func copyInt(iPtr *int) *int {
if iPtr == nil {
return nil
}
var t = *iPtr
return &t
}
func copyString(sPtr *string) *string {
if sPtr == nil {
return nil
}
var t = *sPtr
return &t
}
func copyTime(tPtr *time.Time) *time.Time {
if tPtr == nil {
return nil
}
var t = *tPtr
return &t
}