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