Skip to content

Commit 3d74d8d

Browse files
committed
Updates for documentation and small changes based on internal suggestions
1 parent a375087 commit 3d74d8d

10 files changed

Lines changed: 253 additions & 14 deletions

File tree

doc_src/ContributionGuide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+
# Contribution Guide

doc_src/Foundation.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# `softlayer_api` Foundation
2+
3+
The Foundation Layer of the `softlayer_api` Gem handles communication, authentication, and direct interaction with the SoftLayer API. The majority of this functionality is embodied in the `SoftLayer::Client` and `SoftLayer::Service` classes. Tools are added to those to support important features of the SoftLayer API such as Object Masks, Result Limits, and Object Filters. This document explains what developers must do to connect to, and interact with, the SoftLayer API using this Gem.
4+
5+
# Getting Started
6+
7+
Getting started with the SoftLayer API is fairly straightforward. There is some key information that you will have to provide to the Gem in order to connect to the SoftLayer API. You provide that information to classes instantiated from the Gem's source and use those instances to make calls into the API.
8+
9+
## Key Information
10+
In order to communicate with the SoftLayer API, the system needs to have three key pieces of information:
11+
12+
* User name — a user name for the SoftLayer account you wish to work with.
13+
* API key — API keys are obtained through the SoftLayer web portal.
14+
* Endpoint URL — A URL to the SoftLayer Endpoint your code would like to communicate with.
15+
16+
The user name is simply the name of one of the user accounts created within your SoftLayer account. While it is possible to use the Master User account we recommend that you create one or more dedicated API user accounts so that you can carefully control account permissions for your API access.
17+
18+
The API key must be generated for the user account you use to access the API. Information on generating API keys can be found in the [Authenticating to the SoftLayer API](http://sldn.softlayer.com/article/Authenticating-SoftLayer-API) article on SLDN under the heading, _Generating Your API Key_. Please remember, your API key is privileged information and you should protect carefully as you would a password.
19+
20+
SoftLayer provides two different endpoint URLs to scripts. One is associated with the public internet and may be accessed from anywhere. These two URLs are available as global variables in the SoftLayer module:
21+
22+
# The base URL of the SoftLayer API available to the public internet.
23+
API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3/'
24+
25+
# The base URL of the SoftLayer API available through SoftLayer's private network
26+
API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3/'
27+
28+
In most cases, you will not have to specify the endpoint URL and the Gem will use the `API_PUBLIC_ENDPOINT` by default.
29+
30+
## Creating a Client
31+
32+
Once you have a username and API key, you need to provide them to the library. An instance of the `SoftLayer::Client` class is responsible the credentials provides them to any object that calls into the network API. One way to create a client is to provide the key information as hash parameters when constructing the client:
33+
34+
softlayer_client = SoftLayer::Client.new(
35+
:username => "joecustomer", # enter your username here
36+
:api_key => "feeddeadbeefbadf00d...", # enter your api key here
37+
:endpoint_URL => API_PUBLIC_ENDPOINT
38+
)
39+
40+
(Note: In the call above, the :endpoint_url is shown explicitly, though in most cases you can leave it off and the `API_PUBLIC_ENDPOINT` will be used by default).
41+
42+
The `SoftLayer::Client` class works through the `SoftLayer::Config` class to discover the communication settings. Config allows developers to use a variety of techniques to provide these settings, for more information see the documentation of that class.
43+
44+
## Obtaining a Service
45+
46+
With a fully configured client, the next step is to obtain an instance of the `SoftLayer::Service` class. Calls to the network SoftLayer API are done through Service objects. The Services of the network SoftLayer API are documented on the [SLDN](http://sldn.softlayer.com) web site.
47+
48+
In this example we will use the `SoftLayer_Account` service. Given the variable `softlayer_client` which is a properly configured Client object, getting the `SoftLayer_Account` service is done as follows:
49+
50+
account_service = softlayer_client.service_named("Account")
51+
52+
or more succinctly
53+
54+
account_service = softlayer_client["Account"]
55+
56+
(Please note: Service names are case sensitive and using the prefix `SoftLayer_` in the service name is optional)
57+
58+
## Working with the network API
59+
60+
With a service in hand, calling thorough to the network SoftLayer API is straightforward. Using the `account_service` created above we may call the `getOpenTickets` method in that service directly:
61+
62+
open_tickets = account_service.getOpenTickets()
63+
64+
The open_tickets variable should receive an array of hashes representing the open tickets for the account that are visible to the user provided to the Client object. As a more complete example, the following script uses the techniques just describe to obtain a list of the open tickets on an account and print the titles of those tickets to the console
65+
66+
softlayer_client = SoftLayer::Client.new( :username => "joecustomer", api_key => "feeddeadbeefbadf00d...)
67+
open_tickets = softlayer_client["Account"].getOpenTickets
68+
69+
open_tickets.each { |ticket_hash| puts ticket_hash["title"] }
70+
71+
This short example shows the essence of working with the Foundation API, you create a client, obtain a service, and make calls to the network SoftLayer API through that service.
72+
73+
## Request Results
74+
75+
Most of the information you get back from the network SoftLayer API at the foundation level is returned as Hashes, or arrays of hashes. These structures are often nested. The keys of the hashes will be strings and use the property name specified in the [SLDN documentation](http://sldn.softlayer.com). The values in the hashes vary depending on the data type of the property represented by the hash key. In the example above, the `getOpenTickets` call returns an array of hashes. Each hash offers information about a single ticket in the account's open ticket list.
76+
77+
The network SoftLayer API provides helpful techniques for limiting and filtering the result set from calls to the network and the `softlayer_api` offers helpful routines for making use of these. Please see the section on Service Helpers below.
78+
79+
## Error reporting
80+
81+
Calls to the network SoftLayer API that result in errors being returned by the server are caught in the XML-RPC layer and passed back to scripts as Exceptions. It is prudent to wrap your calls in exception handling code.
82+
83+
## Troubleshooting
84+
85+
Communication with the SoftLayer servers is handled through the XML-RPC client that is built into the Ruby Core library. As a consequence the network communication is also handled by Core library classes.
86+
87+
One aspect of network communication that the `softlayer_api` relies on the Ruby Core library to provide is SSL certificate authentication. Problems with this authentication often arise if your Ruby environment is not properly configured with SSL root certificates. If you find you are having trouble communicating with the network SoftLayer API, and the error messages point to SSL certificate authentication, please consider a web search using your specific error message as a search string. This will often reveal answers that can help you resolve networking issues your Ruby environment.
88+
89+
Another valuable tool for troubleshooting is the global `$DEBUG` variable. This variable can be set to `true` explicitly in your code, or from the command line by adding the `-d` flag to the ruby command. When set, calls to the XML-RPC library will print both both the request and response sides of server communication. In addition, many of the classes in the `softlayer_api` Gem may respond to this variable and print debugging information to the console.
90+
91+
# Service Helpers
92+
93+
Service helpers are convenient routines that modify the network requests sent to the network API. They allow scripts to take advantage of specific features offered by the network API. To use a service helper, you place a call in the calling chain between a service, and the method that will invoke the network API. For example:
94+
95+
ticket_service = softlayer_client["Ticket"]
96+
assigned_user = ticket_service.object_with_id(12345).getAssignedUser()
97+
98+
In this example the method `object_with_id` is a service helper. It instructs the network API to direct the `getAssignedUser` call to the ticket whose `id` is 12345.
99+
100+
It is permissible to invoke more than one helper in a given calling sequence.
101+
102+
Service helpers may also be used to simplify your code as the result of calling a service helper is, itself, an object. Using the example above, if you wished to make multiple calls to the ticket with the `id` 12345 you can store the result of applying the `object_with_id` helper in a variable and create a service proxy with that filter applied. For example:
103+
104+
my_ticket = softlayer_client["Ticket"].object_with_id(12345)
105+
my_ticket.addUpdate({"entry" : "Ticket has been updated"})
106+
my_ticket.markAsViewed
107+
108+
The result of calling `object_with_id` on the ticket service is stored in `my_ticket` creating a service proxy that is then used to call both `addUpdate` and `markAsViewed` in the network API. Both of the network calls would be directed at the ticket whose id is 12345 since both the Ticket service, and the applied helper `object_with_id` are part of the proxy.
109+
110+
The remainder of this section looks at the service helpers offered by the `softlayer_api` Gem.
111+
112+
## `object_with_id`
113+
114+
Entities in the SoftLayer environment are uniquely identified by the Service in which they are found, and their object `id`. The `object_with_id` service helper is used to direct a network request to a particular object in the SoftLayer Environment.
115+
116+
Examples of using `object_with_id` to direct a network API request to a particular object (in this case a ticket) are given in the introduction to the Service Helpers section above.
117+
118+
A particular calling sequence should only include one invocation of the `object_with_id` service helper.
119+
120+
## Object Masks
121+
122+
Object Masks offer a way for a script to limit the results of a particular call so that the result includes particular properties of the objects returned by the call. For example, if a problem's solution required the list of open tickets for an account, including each ticket's title and a count of the updates made to the ticket, A script could limit the information returned for each ticket to the title and update count using an object mask:
123+
124+
softlayer_client["Account"].object_mask("mask[title,updateCount]").getOpenTickets()
125+
126+
The service helper for providing object masks is simply `object_mask`. The parameter to the call is a valid object mask string. More information about the format of object strings may be found in the SLDN documentation on [Object Masks](http://sldn.softlayer.com/article/Object-Masks). In this example, the mask asks the network API to return the `title` and `updateCount` properties of the objects (in this case Tickets) returned by `getOpenTickets`.
127+
128+
Crafting a careful object mask can help your code get exactly the information it needs.
129+
130+
A calling sequence may contain more than one call to the `object_mask` service helper. The masks will be combined and simplified by the library before being passed to the server.
131+
132+
## Result Limits
133+
134+
Result limits are applied to network API calls that return arrays of items. By providing a result limit, your code can ask that only a particular range of items in the array be returned. For example, given an account with 100 open tickets, if you were only interested in 5th through 10th tickets you could request just those tickets using a result limit helper:
135+
136+
softlayer_client["Account"].result_limit(4,5).getOpenTickets()
137+
138+
The first argument to the `result_limit` helper is the index in the array of the first item you wish to receive. Because indexes are 0 based, to get the 5th element in the call above we have specified and index of 4. The second argument to a `result_limit` call is the number of items you wish to have included in the results. In this case we wanted 5 tickets.
139+
140+
Only one call to the `result_limit` helper should be included in any calling sequence.
141+
142+
## Object Filters
143+
144+
Object Filters ask the server to filter the result set using a set of criteria before returning its results. Unfortunately, at the time of this writing, constructing object filters is not a well documented process. Luckily, the `softlayer_api` Ruby Gem, offers some convenience functionality to help you create simple object filters. If you want help crafting a particular object filter, we suggest you ask in the [SLDN Forums](https://forums.softlayer.com/forum/softlayer-developer-network) for assistance.
145+
146+
As an example, suppose you wished to obtain a list of all the virtual servers on an account that were in the domain kitchentools.com. To get the list of virtual servers on an account you would use the `SoftLayer_Account` service and call the `getVirtualGuests` method. The filter we wish to apply is based on the `domain` property of the virtual servers being returned. That code would look like this:
147+
148+
filter = SoftLayer::ObjectFilter.build("domain", "kitchentools.com")
149+
softlayer_client['Account'].object_filter(filter).getVirtualGuests()
150+
151+
The object filter is applied using the `object_filter` service helper. This method takes a single parameter, the object filter to apply to the network API call.
152+
153+
In order to get the filter we wish to apply, this example uses the `SoftLayer::ObjectFilter#build` method. The first parameter to `build` is the property that we wish our filter based on. The second parameter is a query string, in this case the query string means "objects whose property value exactly matches 'kitchentools.com'". Other query strings possible. For example, if we wanted to select the servers whose domain names end with 'tools.com' we could use the query string '*tools.com'. For more information about query strings, please see the documentation for the `SoftLayer::ObjectFilter#query_to_filter_operation` method.
154+
155+
The `SoftLayer::ObjectFilter#build` routine also allows a block syntax which lets you specify the filter criteria using a very simple Domain Specific Language (DSL). Here is an example of constructing the same filter `domain` filter from the previous using the block technique:
156+
157+
filter = SoftLayer::ObjectFilter.build("domain") { is("kichentools.com") }
158+
159+
This filter also asks that the domain exactly match "kitchentools.com". Other matchers can be found in as the instance methods of the `SoftLayer::ObjectFilterBlockHandler` class.
160+

doc_src/Welcome.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Welcome
2+
3+
The `softlyer_api` Ruby Gem provides a convenient way to call into the SoftLayer API from the Ruby programming language. This is accomplished using the XML-RPC interface provided by SoftLayer and the XMLRPC client built into the core Ruby language.
4+
5+
For more information about the SoftLayer API, and the routines and data structures it offers should visit the [SoftLayer Developer Network (SLDN) website](http://sldn.softlayer.com).
6+
7+
This document is written for Ruby developers who wish to interact with their SoftLayer accounts through Ruby scripts. SoftLayer also offers a command line tool for performing common tasks. If prefer to use that tool, we invite you to look into the [command line interface](https://softlayer-python.readthedocs.org/en/latest/cli.html) that is part of the [softlayer-python](http://github.com/softlayer/softlayer-python) project.
8+
9+
This documentation is also written for Ruby developers who wish to contribute to the `softlayer_api` Gem. The Gem is a work in progress. We welcome the support of the SoftLayer development community to improve the Gem. The project is open source and we hope that source will serve as a useful library, stand as sample code to assist exploration, and serve as an opportunity for developers to shape it for both those needs.
10+
11+
The primary repository for the Gem's source code is the [softlayer-ruby](http://github.com/softlayer/softlayer-ruby) github project.
12+
13+
# Overview
14+
15+
These Ruby language bindings allow access to the SoftLayer API on two different levels. A Foundation layer for low-level interaction with the SoftLayer API, and an abstraction layer that simplifies and isolates scripts from some of the details found in the Foundation.
16+
17+
The Foundation layer, makes use of the [XMLRPC client](http://www.ruby-doc.org/stdlib-2.1.2/libdoc/xmlrpc/rdoc/XMLRPC/Client.html) which is part of the Core library of Ruby itself. This foundation is embodied primarily in the `SoftLayer::Client` and `SoftLayer::Service` classes. Requests are made, and responses retrieved using fundamental Ruby types such as Hashes, Arrays, Strings, and Integers.
18+
19+
The Model layer is built atop the foundation as object class hierarchy. The class hierarchy models the structures found in the SoftLayer environment using the object-oriented features of Ruby. It does this to abstract out some of the implementation detail that a developer would commonly have to work with to communicate with SoftLayer through the foundation layer.
20+
21+
The Model layer is by no means complete; quite to the contrary it is in its infancy and we believe that much of the development effort in the Gem will focus on incorporating new models into this layer. Because it is incomplete, however, we have put some effort into bridges from the functionality of the model, down to the lower level foundation, without trouble. Also, as a result of this, developers interested in using the Model layer should also should familiarize themselves with the Foundation.
22+
23+
All developers should continue their exploration of the `softlayer_api` gem by examining the Foundation documentation. Clients that wish to make use of the abstractions provided in the object hierarchy may continue their exploration by looking at the Model Layer documentation. Developers who wish to expand the models found in the `softlayer_api` Gem should read the [Contribution Guide](ContributionGuide_md.html)

examples/account_info.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
begin
2828
softlayer_client = SoftLayer::Client.new(
29-
# :username => "joecustomer" # enter your username here
29+
# :username => "joecustomer", # enter your username here
3030
# :api_key => "feeddeadbeefbadf00d..." # enter your api key here
3131
)
3232

lib/softlayer/Client.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,8 @@ module SoftLayer
3030
# - +:api_key+ - a non-empty string providing the api key to use for requests to the client
3131
# - +:endpoint_url+ - a non-empty string providing the endpoint URL to use for requests to the client
3232
#
33-
# If any of the options above are missing then the constructor will try to use the corresponding
34-
# global variable declared in the SoftLayer Module:
35-
# - +$SL_API_USERNAME+
36-
# - +$SL_API_KEY+
37-
# - +$SL_API_BASE_URL+
33+
# If any of these are missing then the Client class will look to the SoftLayer::Config
34+
# class to provide the missing information. Please see that class for details.
3835
#
3936
class Client
4037
# A username passed as authentication for each request. Cannot be emtpy or nil.

0 commit comments

Comments
 (0)