1# linodego 2 3[![Build Status](https://travis-ci.com/linode/linodego.svg?branch=master)](https://travis-ci.com/linode/linodego) 4[![Release](https://img.shields.io/github/v/release/linode/linodego)](https://github.com/linode/linodego/releases/latest) 5[![GoDoc](https://godoc.org/github.com/linode/linodego?status.svg)](https://godoc.org/github.com/linode/linodego) 6[![Go Report Card](https://goreportcard.com/badge/github.com/linode/linodego)](https://goreportcard.com/report/github.com/linode/linodego) 7[![codecov](https://codecov.io/gh/linode/linodego/branch/master/graph/badge.svg)](https://codecov.io/gh/linode/linodego) 8 9Go client for [Linode REST v4 API](https://developers.linode.com/api/v4) 10 11## Installation 12 13```sh 14go get -u github.com/linode/linodego 15``` 16 17## API Support 18 19Check [API_SUPPORT.md](API_SUPPORT.md) for current support of the Linode `v4` API endpoints. 20 21** Note: This project will change and break until we release a v1.0.0 tagged version. Breaking changes in v0.x.x will be denoted with a minor version bump (v0.2.4 -> v0.3.0) ** 22 23## Documentation 24 25See [godoc](https://godoc.org/github.com/linode/linodego) for a complete reference. 26 27The API generally follows the naming patterns prescribed in the [OpenAPIv3 document for Linode APIv4](https://developers.linode.com/api/v4). 28 29Deviations in naming have been made to avoid using "Linode" and "Instance" redundantly or inconsistently. 30 31A brief summary of the features offered in this API client are shown here. 32 33## Examples 34 35### General Usage 36 37```go 38package main 39 40import ( 41 "context" 42 "fmt" 43 44 "github.com/linode/linodego" 45 "golang.org/x/oauth2" 46 47 "log" 48 "net/http" 49 "os" 50) 51 52func main() { 53 apiKey, ok := os.LookupEnv("LINODE_TOKEN") 54 if !ok { 55 log.Fatal("Could not find LINODE_TOKEN, please assert it is set.") 56 } 57 tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: apiKey}) 58 59 oauth2Client := &http.Client{ 60 Transport: &oauth2.Transport{ 61 Source: tokenSource, 62 }, 63 } 64 65 linodeClient := linodego.NewClient(oauth2Client) 66 linodeClient.SetDebug(true) 67 68 res, err := linodeClient.GetInstance(context.Background(), 4090913) 69 if err != nil { 70 log.Fatal(err) 71 } 72 fmt.Printf("%v", res) 73} 74``` 75 76### Pagination 77 78#### Auto-Pagination Requests 79 80```go 81kernels, err := linodego.ListKernels(context.Background(), nil) 82// len(kernels) == 218 83``` 84 85Or, use a page value of "0": 86 87```go 88opts := linodego.NewListOptions(0,"") 89kernels, err := linodego.ListKernels(context.Background(), opts) 90// len(kernels) == 218 91``` 92 93#### Single Page 94 95```go 96opts := linodego.NewListOptions(2,"") 97// or opts := linodego.ListOptions{PageOptions: &linodego.PageOptions{Page: 2}, PageSize: 500} 98kernels, err := linodego.ListKernels(context.Background(), opts) 99// len(kernels) == 100 100``` 101 102ListOptions are supplied as a pointer because the Pages and Results 103values are set in the supplied ListOptions. 104 105```go 106// opts.Results == 218 107``` 108 109#### Filtering 110 111```go 112opts := linodego.ListOptions{Filter: "{\"mine\":true}"} 113// or opts := linodego.NewListOptions(0, "{\"mine\":true}") 114stackscripts, err := linodego.ListStackscripts(context.Background(), opts) 115``` 116 117### Error Handling 118 119#### Getting Single Entities 120 121```go 122linode, err := linodego.GetInstance(context.Background(), 555) // any Linode ID that does not exist or is not yours 123// linode == nil: true 124// err.Error() == "[404] Not Found" 125// err.Code == "404" 126// err.Message == "Not Found" 127``` 128 129#### Lists 130 131For lists, the list is still returned as `[]`, but `err` works the same way as on the `Get` request. 132 133```go 134linodes, err := linodego.ListInstances(context.Background(), linodego.NewListOptions(0, "{\"foo\":bar}")) 135// linodes == [] 136// err.Error() == "[400] [X-Filter] Cannot filter on foo" 137``` 138 139Otherwise sane requests beyond the last page do not trigger an error, just an empty result: 140 141```go 142linodes, err := linodego.ListInstances(context.Background(), linodego.NewListOptions(9999, "")) 143// linodes == [] 144// err = nil 145``` 146 147### Writes 148 149When performing a `POST` or `PUT` request, multiple field related errors will be returned as a single error, currently like: 150 151```go 152// err.Error() == "[400] [field1] foo problem; [field2] bar problem; [field3] baz problem" 153``` 154 155## Tests 156 157Run `make testunit` to run the unit tests. 158 159Run `make testint` to run the integration tests. The integration tests use fixtures. 160 161To update the test fixtures, run `make fixtures`. This will record the API responses into the `fixtures/` directory. 162Be careful about committing any sensitive account details. An attempt has been made to sanitize IP addresses and 163dates, but no automated sanitization will be performed against `fixtures/*Account*.yaml`, for example. 164 165To prevent disrupting unaffected fixtures, target fixture generation like so: `make ARGS="-run TestListVolumes" fixtures`. 166 167## Discussion / Help 168 169Join us at [#linodego](https://gophers.slack.com/messages/CAG93EB2S) on the [gophers slack](https://gophers.slack.com) 170 171## License 172 173[MIT License](LICENSE) 174