• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

config/H06-Aug-2018-

datatypes/H06-Aug-2018-

examples/H06-Aug-2018-

filter/H06-Aug-2018-

helpers/H06-Aug-2018-

services/H06-Aug-2018-

session/H06-Aug-2018-

sl/H06-Aug-2018-

tests/H06-Aug-2018-

tools/H06-Aug-2018-

.gitignoreH A D06-Aug-2018314

.travis.ymlH A D06-Aug-201868

LICENSEH A D06-Aug-201811.1 KiB

MakefileH A D06-Aug-20181.7 KiB

README.mdH A D06-Aug-201810.2 KiB

README.md

1# softlayer-go
2
3[![Build Status](https://travis-ci.org/softlayer/softlayer-go.svg?branch=master)](https://travis-ci.org/softlayer/softlayer-go)
4[![GoDoc](https://godoc.org/github.com/softlayer/softlayer-go?status.svg)](https://godoc.org/github.com/softlayer/softlayer-go)
5[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
6
7The Official and Complete SoftLayer API Client for Golang (the Go programming language).
8
9## Introduction
10
11This library contains a complete implementation of the SoftLayer API for client application development in the Go programming language. Code for each API data type and service method is pre-generated, using the SoftLayer API metadata endpoint as input, thus ensuring 100% coverage of the API right out of the gate.
12
13It was designed to feel as natural as possible for programmers familiar with other popular SoftLayer SDKs, and attempts to minimize unnecessary boilerplate and type assertions where possible.
14
15## Usage
16
17### Basic example:
18
19Three easy steps:
20
21```go
22// 1. Create a session
23sess := session.New(username, apikey)
24
25// 2. Get a service
26accountService := services.GetAccountService(sess)
27
28// 3. Invoke a method:
29account, err := accountService.GetObject()
30```
31
32[More examples](https://github.com/softlayer/softlayer-go/tree/master/examples)
33
34### Sessions
35
36In addition to the example above, sessions can also be created using values
37set in the environment, or from the local configuration file (i.e. ~/.softlayer):
38
39```go
40sess := session.New()
41```
42
43In this usage, the username, API key, and endpoint are read from specific environment
44variables, then the local configuration file (i.e. ~/.softlayer).  First match ends
45the search:
46
47* _Username_
48	1. environment variable `SL_USERNAME`
49	1. environment variable `SOFTLAYER_USERNAME`
50	1. local config `username`.
51* _API Key_
52	1. environment variable `SL_API_KEY`
53	1. environment variable `SOFTLAYER_API_KEY`
54	1. local config `api_key`.
55* _Endpoint_
56	1. environment variable `SL_ENDPOINT_URL`
57	1. environment variable `SOFTLAYER_ENDPOINT_URL`
58	1. local config `endpoint_url`.
59* _Timeout_
60	1. environment variable `SL_TIMEOUT`
61	1. environment variable `SOFTLAYER_TIMEOUT`
62	1. local config `timeout`.
63
64*Note:* Endpoint defaults to `https://api.softlayer.com/rest/v3` if not configured through any of the above methods. Timeout defaults to 120 seconds.
65
66Example of the **~/.softlayer** local configuration file:
67```
68[softlayer]
69username = <your username>
70api_key = <your api key>
71endpoint_url = <optional>
72timeout = <optional>
73```
74
75### Instance methods
76
77To call a method on a specific instance, set the instance ID before making the call:
78
79```go
80service := services.GetUserCustomerService(sess)
81
82service.Id(6786566).GetObject()
83```
84
85### Passing Parameters
86
87All non-slice method parameters are passed as pointers. This is to allow for optional values to be omitted (by passing `nil`)
88
89```go
90guestId := 123456
91userCustomerService.RemoveVirtualGuestAccess(&guestId)
92```
93
94For convenience, a set of helper functions exists that allocate storage for a literal and return a pointer. The above can be refactored to:
95
96```go
97userCustomerService.RemoveVirtualGuestAccess(sl.Int(123456))
98```
99
100### Using datatypes
101
102A complete library of SoftLayer API data type structs exists in the `datatypes` package. Like method parameters, all non-slice members are declared as pointers. This has the advantage of permitting updates without re-sending the complete data structure (since `nil` values are omitted from the resulting JSON). Use the same set of helper functions to assist in populating individual members.
103
104```go
105package main
106
107import (
108	"fmt"
109	"log"
110
111	"github.com/softlayer/softlayer-go/datatypes"
112	"github.com/softlayer/softlayer-go/services"
113	"github.com/softlayer/softlayer-go/session"
114	"github.com/softlayer/softlayer-go/sl"
115)
116
117func main() {
118	sess := session.New() // See above for details about creating a new session
119
120	// Get the Virtual_Guest service
121	service := services.GetVirtualGuestService(sess)
122
123	// Create a Virtual_Guest struct as a template
124	vGuestTemplate := datatypes.Virtual_Guest{
125		// Set Creation values - use helpers from the sl package to set pointer values.
126		// Unset (nil) values are not sent
127		Hostname:                     sl.String("sample"),
128		Domain:                       sl.String("example.com"),
129		MaxMemory:                    sl.Int(4096),
130		StartCpus:                    sl.Int(1),
131		Datacenter:                   &datatypes.Location{Name: sl.String("wdc01")},
132		OperatingSystemReferenceCode: sl.String("UBUNTU_LATEST"),
133		LocalDiskFlag:                sl.Bool(true),
134	}
135
136	// Tell the API to create the virtual guest
137	newGuest, err := service.CreateObject(&vGuestTemplate)
138	// optional error checking...
139	if err != nil {
140		log.Fatal(err)
141	}
142
143	// Print the ID of the new guest.  Don't forget to dereference
144	fmt.Printf("New guest %d created", *newGuest.Id)
145}
146```
147
148### Object Masks, Filters, Result Limits
149
150Object masks, object filters, and pagination (limit and offset) can be set
151by calling the `Mask()`, `Filter()`, `Limit()` and `Offset()` service methods
152prior to invoking an API method.
153
154For example, to set an object mask and filter that will be applied to
155the results of the Account.GetObject() method:
156
157```go
158accountService := services.GetAccountService(sess)
159
160accountService.
161	Mask("id;hostname").
162	Filter(`{"virtualGuests":{"domain":{"operation":"example.com"}}}`).
163	GetObject()
164```
165
166The mask and filter are applied to the current request only, and reset after the
167method returns. To preserve these options for future requests, save the return value:
168
169```go
170accountServiceWithMaskAndFilter = accountService.Mask("id;hostname").
171	Filter(`{"virtualGuests":{"domain":{"operation":"example.com"}}}`)
172```
173
174Result limits are specified as separate `Limit` and `Offset` values:
175
176```go
177accountService.
178	Offset(100).      // start at the 100th element in the list
179	Limit(25).        // limit to 25 results
180	GetVirtualGuests()
181```
182
183#### Filter Builder
184
185There is also a **filter builder** you can use to create a _Filter_ instead of writing out the raw string:
186
187```go
188// requires importing the filter package
189accountServiceWithMaskAndFilter = accountService.
190    Mask("id;hostname").
191    Filter(filter.Path("virtualGuests.domain").Eq("example.com").Build())
192```
193
194You can also create a filter incrementally:
195
196```go
197// Create initial filters
198filters := filter.New(
199    filter.Path("virtualGuests.hostname").StartsWith("KM078"),
200    filter.Path("virtualGuests.id").NotEq(12345),
201)
202
203// ....
204// Later, append another filter
205filters = append(filters, filter.Path("virtualGuests.domain").Eq("example.com"))
206
207accountServiceWithMaskAndFilter = accountService.
208    Mask("id;hostname").
209    Filter(filters.Build())
210```
211
212Or you can build all those filters in one step:
213
214```go
215// Create initial filters
216filters := filter.Build(
217    filter.Path("virtualGuests.hostname").StartsWith("KM078"),
218    filter.Path("virtualGuests.id").NotEq(12345),
219    filter.Path("virtualGuests.domain").Eq("example.com"),
220)
221
222accountServiceWithMaskAndFilter = accountService.
223    Mask("id;hostname").Filter(filters)
224```
225
226See _filter/filters.go_ for the full range of operations supported.
227The file at _examples/filters.go_ will show additional examples.
228Also, [this is a good article](https://sldn.softlayer.com/article/object-filters) that describes SoftLayer filters at length.
229
230### Handling Errors
231
232For any error that occurs within one of the SoftLayer API services, a custom
233error type is returned, with individual fields that can be parsed separately.
234
235```go
236_, err := service.Id(0).      // invalid object ID
237	GetObject()
238
239if err != nil {
240	// Note: type assertion is only necessary for inspecting individual fields
241	apiErr := err.(sl.Error)
242	fmt.Printf("API Error:")
243	fmt.Printf("HTTP Status Code: %d\n", apiErr.StatusCode)
244	fmt.Printf("API Code: %s\n", apiErr.Exception)
245	fmt.Printf("API Error: %s\n", apiErr.Message)
246}
247```
248
249Note that `sl.Error` implements the standard `error` interface, so it can
250be handled like any other error, if the above granularity is not needed:
251
252```go
253_, err := service.GetObject()
254if err != nil {
255	fmt.Println("Error during processing: ", err)
256}
257```
258
259### Session Options
260
261To set a different endpoint (e.g., the backend network endpoint):
262
263```go
264session.Endpoint = "https://api.service.softlayer.com/rest/v3"
265```
266
267To enable debug output:
268
269```go
270session.Debug = true
271```
272
273By default, the debug output is sent to standard output. You can customize this by setting up your own logger:
274
275```go
276import "github.com/softlayer/softlayer-go/session"
277
278session.Logger = log.New(os.Stderr, "[CUSTOMIZED] ", log.LstdFlags)
279```
280
281You can also tell the session to retry the api requests if there is a timeout error:
282
283```go
284// Specify how many times to retry the request, the request timeout, and how much time to wait
285// between retries.
286services.GetVirtualGuestService(
287	sess.SetTimeout(900).SetRetries(2).SetRetryWait(3)
288).GetObject(...)
289```
290
291### Password-based authentication
292
293Password-based authentication (via requesting a token from the API) is
294only supported when talking to the API using the XML-RPC transport protocol.
295
296To use the XML-RPC protocol, simply specify an XML-RPC endpoint url:
297
298```go
299func main() {
300    // Create a session specifying an XML-RPC endpoint url.
301    sess := &session.Session{
302        Endpoint: "https://api.softlayer.com/xmlrpc/v3",
303    }
304
305    // Get a token from the api using your username and password
306    userService := services.GetUserCustomerService(sess)
307    token, err := userService.GetPortalLoginToken(username, password, nil, nil)
308    if err != nil {
309        log.Fatal(err)
310    }
311
312    // Add user id and token to the session.
313    sess.UserId = *token.UserId
314    sess.AuthToken = *token.Hash
315
316    // You have a complete authenticated session now.
317    // Call any api from this point on as normal...
318    keys, err := userService.Id(sess.UserId).GetApiAuthenticationKeys()
319    if err != nil {
320        log.Fatal(err)
321    }
322
323    log.Println("API Key:", *keys[0].AuthenticationKey)
324}
325```
326
327## Development
328
329### Setup
330
331To get _softlayer-go_:
332
333```
334go get github.com/softlayer/softlayer-go/...
335```
336
337### Build
338
339```
340make
341```
342
343### Test
344
345```
346make test
347```
348
349### Updating dependencies
350
351```
352make update_deps
353```
354
355## Copyright
356
357This software is Copyright (c) 2016 IBM Corp. See the bundled LICENSE file for more information.
358