softlayer_api 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.textile +7 -0
- data/examples/account_info.rb +1 -1
- data/lib/softlayer/Client.rb +9 -14
- data/lib/softlayer/Config.rb +55 -1
- data/lib/softlayer/ModelBase.rb +11 -11
- data/lib/softlayer/ObjectFilter.rb +1 -1
- data/lib/softlayer/ProductPackage.rb +3 -1
- data/lib/softlayer/VirtualServer.rb +2 -2
- data/lib/softlayer/base.rb +3 -3
- metadata +2 -4
- data/LICENSE.textile +0 -19
- data/README.textile +0 -311
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 390f9ff4017222664251b8ccf219c01fe051f936
|
4
|
+
data.tar.gz: 7f3bd11e1d5915e3bbe5c1a47602543fa86768a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 204a913bcc8b5f3bb79f3fd591ee32f123b9b9918b9469868b81afee662882af114f88a4fa1774215cfc1e67e1fed08d4a4fcfefecb420bf5b9ba962dab07446
|
7
|
+
data.tar.gz: e425eae9d1a0b3f2fd66434ce014ec67b02234c4451072f9c0f658384d9b8059731b58c95e2e48f2081c29fe68252d069da794a89531a19cfc36efdf43527251
|
data/CHANGELOG.textile
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
*2.2*
|
2
|
+
* Added a method to reboot servers.
|
3
|
+
|
4
|
+
*2.1.1*
|
5
|
+
* Virtual server upgrades no longer raise exceptions
|
6
|
+
* Formalized the RDoc documentation process. Added overview and welcome documentation and changed the README so it directs folks to the new documentation.
|
7
|
+
|
1
8
|
*2.1.0*
|
2
9
|
* Began implementing a model framework that allows Ruby developers to work with elements in the SoftLayer API in a more object-oriented fashion. The first release of this framework includes the Ticket, VirtualServer, and BareMetalServer classes.
|
3
10
|
|
data/examples/account_info.rb
CHANGED
@@ -26,7 +26,7 @@ require 'pp'
|
|
26
26
|
|
27
27
|
begin
|
28
28
|
softlayer_client = SoftLayer::Client.new(
|
29
|
-
# :username => "joecustomer"
|
29
|
+
# :username => "joecustomer", # enter your username here
|
30
30
|
# :api_key => "feeddeadbeefbadf00d..." # enter your api key here
|
31
31
|
)
|
32
32
|
|
data/lib/softlayer/Client.rb
CHANGED
@@ -30,11 +30,8 @@ module SoftLayer
|
|
30
30
|
# - +:api_key+ - a non-empty string providing the api key to use for requests to the client
|
31
31
|
# - +:endpoint_url+ - a non-empty string providing the endpoint URL to use for requests to the client
|
32
32
|
#
|
33
|
-
# If any of
|
34
|
-
#
|
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.
|
38
35
|
#
|
39
36
|
class Client
|
40
37
|
# A username passed as authentication for each request. Cannot be emtpy or nil.
|
@@ -119,20 +116,18 @@ module SoftLayer
|
|
119
116
|
def service_named(service_name, service_options = {})
|
120
117
|
raise ArgumentError,"Please provide a service name" if service_name.nil? || service_name.empty?
|
121
118
|
|
122
|
-
#
|
123
|
-
#
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
if not service_name =~ /\ASoftLayer_/
|
128
|
-
service_name = "SoftLayer_#{service_name}"
|
119
|
+
# Strip whitespace from service_name and ensure that it starts with "SoftLayer_".
|
120
|
+
# If it does not, then add the prefix.
|
121
|
+
full_name = service_name.to_s.strip
|
122
|
+
if not full_name =~ /\ASoftLayer_/
|
123
|
+
full_name = "SoftLayer_#{service_name}"
|
129
124
|
end
|
130
125
|
|
131
126
|
# if we've already created this service, just return it
|
132
127
|
# otherwise create a new service
|
133
|
-
service_key =
|
128
|
+
service_key = full_name.to_sym
|
134
129
|
if !@services.has_key?(service_key)
|
135
|
-
@services[service_key] = SoftLayer::Service.new(
|
130
|
+
@services[service_key] = SoftLayer::Service.new(full_name, {:client => self}.merge(service_options))
|
136
131
|
end
|
137
132
|
|
138
133
|
@services[service_key]
|
data/lib/softlayer/Config.rb
CHANGED
@@ -23,6 +23,59 @@
|
|
23
23
|
require 'configparser'
|
24
24
|
|
25
25
|
module SoftLayer
|
26
|
+
|
27
|
+
# The SoftLayer Config class is responsible for providing the key information
|
28
|
+
# the library needs to communicate with the network SoftLayer API. Those three crucial
|
29
|
+
# pieces of information are the Username, the API Key, and the endpoint_url. This information
|
30
|
+
# is collected in a hash with the keys `:username`, `:api_key`, and `:endpoint_url` repsectively.
|
31
|
+
#
|
32
|
+
# The routine used to retrieve this information from a Config object is Config.client_settings
|
33
|
+
#
|
34
|
+
# There are several locations that the Config class looks for this information:
|
35
|
+
#
|
36
|
+
# * Stored in a configuration file
|
37
|
+
# * In the Environment Variables of the running process
|
38
|
+
# * Placed in Global Variables
|
39
|
+
# * In a hash provided directly to the Config class.
|
40
|
+
#
|
41
|
+
# These locations are searched in the order listed above. Information found
|
42
|
+
# lower in this list will replace the information found at higher levels. For example
|
43
|
+
# if the configuration file provides a username but a different username is also set
|
44
|
+
# in the global variables, the Config class allows the global variable to override the name
|
45
|
+
# from the config file.
|
46
|
+
#
|
47
|
+
# = Config File
|
48
|
+
#
|
49
|
+
# The library will search for the SoftLayer config file at the file locations listed in
|
50
|
+
# the `SoftLayer::Config::FILE_LOCATIONS` array. The config file follows the format
|
51
|
+
# recognized by Python's ConfigParser class (and consequently is compatible with the)
|
52
|
+
# SoftLayer-Python language bindings). A simple config file looks something like this:
|
53
|
+
#
|
54
|
+
# [softlayer]
|
55
|
+
# username = joeusername
|
56
|
+
# api_key = DEADBEEFBADF00D
|
57
|
+
#
|
58
|
+
# = Environment Variables
|
59
|
+
#
|
60
|
+
# The config class will search the environment variables SL_USERNAME and SL_API_KEY for
|
61
|
+
# the username and API key respectively. The endpoint_url may not be set thorugh
|
62
|
+
# environment variables.
|
63
|
+
#
|
64
|
+
# = Global Variables
|
65
|
+
#
|
66
|
+
# The names of the global variables that can be used to provide authentication key are:
|
67
|
+
#
|
68
|
+
# - +$SL_API_USERNAME+
|
69
|
+
# - +$SL_API_KEY+
|
70
|
+
# - +$SL_API_BASE_URL+
|
71
|
+
#
|
72
|
+
# = Direct parameters
|
73
|
+
#
|
74
|
+
# Finally, the Config.client_settings routine accepts a hash of arguments. If any
|
75
|
+
# of the key information is provided in that hash, that information will override
|
76
|
+
# any discovered through the techniques above.
|
77
|
+
#
|
78
|
+
|
26
79
|
class Config
|
27
80
|
def Config.globals_settings
|
28
81
|
result = {}
|
@@ -65,7 +118,8 @@ module SoftLayer
|
|
65
118
|
end
|
66
119
|
|
67
120
|
def Config.client_settings(provided_settings = {})
|
68
|
-
|
121
|
+
settings = { :endpoint_url => API_PUBLIC_ENDPOINT }
|
122
|
+
settings.merge! file_settings
|
69
123
|
settings.merge! environment_settings
|
70
124
|
settings.merge! globals_settings
|
71
125
|
settings.merge! provided_settings
|
data/lib/softlayer/ModelBase.rb
CHANGED
@@ -82,17 +82,6 @@ module SoftLayer
|
|
82
82
|
@softlayer_hash = self.softlayer_properties(object_mask)
|
83
83
|
end
|
84
84
|
|
85
|
-
##
|
86
|
-
# Subclasses should implement this method as part of enabling the
|
87
|
-
# refresh_details fuctionality The implementation should make a request
|
88
|
-
# to the SoftLayer API and retrieve an up-to-date SoftLayer hash
|
89
|
-
# representation of this object. That hash should be the return value
|
90
|
-
# of this routine.
|
91
|
-
#
|
92
|
-
def softlayer_properties(object_mask = nil)
|
93
|
-
raise "Abstract method softlayer_properties in ModelBase was called"
|
94
|
-
end
|
95
|
-
|
96
85
|
##
|
97
86
|
# Returns the value of of the given property as stored in the
|
98
87
|
# softlayer_hash. This gives you access to the low-level, raw
|
@@ -132,6 +121,17 @@ module SoftLayer
|
|
132
121
|
|
133
122
|
protected
|
134
123
|
|
124
|
+
##
|
125
|
+
# Subclasses should implement this method as part of enabling the
|
126
|
+
# refresh_details fuctionality The implementation should make a request
|
127
|
+
# to the SoftLayer API and retrieve an up-to-date SoftLayer hash
|
128
|
+
# representation of this object. That hash should be the return value
|
129
|
+
# of this routine.
|
130
|
+
#
|
131
|
+
def softlayer_properties(object_mask = nil)
|
132
|
+
raise "Abstract method softlayer_properties in ModelBase was called"
|
133
|
+
end
|
134
|
+
|
135
135
|
##
|
136
136
|
# The softlayer_hash stores the low-level information about an
|
137
137
|
# object as it was retrieved from the SoftLayer API.
|
@@ -63,7 +63,7 @@ module SoftLayer
|
|
63
63
|
# This class defines the routines that are valid within the block provided to a call to
|
64
64
|
# ObjectFilter.build. This allows you to create object filters like:
|
65
65
|
#
|
66
|
-
#
|
66
|
+
# object_filter = SoftLayer::ObjectFilter.build("hardware.memory") { is_greater_than(2) }
|
67
67
|
#
|
68
68
|
class ObjectFilterBlockHandler
|
69
69
|
# Matches when the value is found within the field
|
@@ -20,6 +20,8 @@
|
|
20
20
|
# THE SOFTWARE.
|
21
21
|
#
|
22
22
|
|
23
|
+
require 'json'
|
24
|
+
|
23
25
|
module SoftLayer
|
24
26
|
##
|
25
27
|
# Each SoftLayer ProductPackage provides information about ordering a product
|
@@ -140,7 +142,7 @@ module SoftLayer
|
|
140
142
|
softlayer_client = client || Client.default_client
|
141
143
|
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
142
144
|
|
143
|
-
filter = SoftLayer::ObjectFilter.build('type.keyName'
|
145
|
+
filter = SoftLayer::ObjectFilter.build('type.keyName', key_name)
|
144
146
|
filtered_service = softlayer_client['Product_Package'].object_filter(filter).object_mask(self.default_object_mask('mask'))
|
145
147
|
packages_data = filtered_service.getAllObjects
|
146
148
|
packages_data.collect { |package_data| ProductPackage.new(softlayer_client, package_data) }
|
@@ -75,7 +75,7 @@ module SoftLayer
|
|
75
75
|
#
|
76
76
|
sl_dynamic_attr :upgrade_options do |resource|
|
77
77
|
resource.should_update? do
|
78
|
-
@
|
78
|
+
@upgrade_options == nil
|
79
79
|
end
|
80
80
|
|
81
81
|
resource.to_update do
|
@@ -365,7 +365,7 @@ module SoftLayer
|
|
365
365
|
# and whose capacity matches the value given. Returns the item_price or nil
|
366
366
|
#
|
367
367
|
def _item_price_in_category(which_category, capacity)
|
368
|
-
item_prices_in_category = self.
|
368
|
+
item_prices_in_category = self.upgrade_options.select { |item_price| item_price["categories"].find { |category| category["categoryCode"] == which_category } }
|
369
369
|
item_prices_in_category.find { |ram_item| ram_item["item"]["capacity"].to_i == capacity}
|
370
370
|
end
|
371
371
|
|
data/lib/softlayer/base.rb
CHANGED
@@ -31,12 +31,12 @@ require 'rubygems'
|
|
31
31
|
# - +$SL_API_BASE_URL+- The default URL used to access the SoftLayer API. This defaults to the value of +SoftLayer::API_PUBLIC_ENDPOINT+
|
32
32
|
#
|
33
33
|
module SoftLayer
|
34
|
-
VERSION = "2.1.
|
34
|
+
VERSION = "2.1.1" # version history in the CHANGELOG.textile file at the root of the source
|
35
35
|
|
36
|
-
# The base URL of the SoftLayer API
|
36
|
+
# The base URL of the SoftLayer API available to the public internet.
|
37
37
|
API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3/'
|
38
38
|
|
39
|
-
# The base URL of the SoftLayer API
|
39
|
+
# The base URL of the SoftLayer API available through SoftLayer's private network
|
40
40
|
API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3/'
|
41
41
|
|
42
42
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: softlayer_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SoftLayer Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: configparser
|
@@ -94,8 +94,6 @@ extensions: []
|
|
94
94
|
extra_rdoc_files: []
|
95
95
|
files:
|
96
96
|
- CHANGELOG.textile
|
97
|
-
- LICENSE.textile
|
98
|
-
- README.textile
|
99
97
|
- examples/account_info.rb
|
100
98
|
- examples/account_servers.rb
|
101
99
|
- examples/create_ticket.rb
|
data/LICENSE.textile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
Copyright (c) 2010-2014 "SoftLayer Technologies, Inc.":http://www.softlayer.com/ All rights reserved.
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
of this software and associated documentation files (the "Software"), to deal
|
5
|
-
in the Software without restriction, including without limitation the rights
|
6
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
copies of the Software, and to permit persons to whom the Software is
|
8
|
-
furnished to do so, subject to the following conditions:
|
9
|
-
|
10
|
-
The above copyright notice and this permission notice shall be included in
|
11
|
-
all copies or substantial portions of the Software.
|
12
|
-
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
THE SOFTWARE.
|
data/README.textile
DELETED
@@ -1,311 +0,0 @@
|
|
1
|
-
h1=. SoftLayer API Client for Ruby
|
2
|
-
|
3
|
-
The SoftLayer API Client for Ruby is a library for connecting to and calling the routines of "The SoftLayer API":http://sldn.softlayer.com/article/The_SoftLayer_API from the "Ruby":http://www.ruby-lang.org programming language.
|
4
|
-
|
5
|
-
<div id="note" style="margin: 1em; padding: 0.5em; background-color: #fcfcfc; border: 1px solid black">
|
6
|
-
*Important Note*
|
7
|
-
|
8
|
-
If you are arriving at this build from verison 1.0 of the @softlayer_api@ gem, you will probably have to change some of your existing scripts. Please see "What's New":#whats-new for details.
|
9
|
-
</div>
|
10
|
-
|
11
|
-
h2. Overview
|
12
|
-
|
13
|
-
The client invokes methods in the API using XML-RPC as a transport mechanism. XML-RPC is handled using @XMLRPC@ classes from the Ruby core library.
|
14
|
-
|
15
|
-
To make calls to the Ruby API through the client you will create an instance of the @SoftLayer::Client@ class, optionally identifying an API endpoint, and providing authentication information in the form of a username and API key. From the client you can obtain various @SoftLayer::Service@ instances and use them to invoke the methods of the API. Results of those calls are communicated from the server to the client as XML, then decoded and returned to you as standard Ruby objects like Hashes, Arrays, and Strings.
|
16
|
-
|
17
|
-
Source code for daily builds of this Gem can be found on the "SoftLayer github public repositories":http://github.com/softlayer/. The latest release version of the Gem is available from the Ruby gem system. (see "Installation":#installation below)
|
18
|
-
|
19
|
-
Should you encounter problems with the client, please contact us in the "SoftLayer Developer Network forums":http://forums.softlayer.com/forum/softlayer-developer-network or open a support ticket in the SoftLayer customer portal.
|
20
|
-
|
21
|
-
h2. Requirements
|
22
|
-
|
23
|
-
The Ruby client has been tested using a wide variety of Ruby implementations including Ruby version 1.9.2, 2.0, and 2.1. It has also been tested on JRuby running in 1.9 mode.
|
24
|
-
|
25
|
-
A network connection is required, and a valid SoftLayer API username and api key are required to call the SoftLayer API. A connection to the SoftLayer private network is required to connect to SoftLayer's private network API endpoints.
|
26
|
-
|
27
|
-
h2(#whats-new). What's New
|
28
|
-
|
29
|
-
The softlayer_api gem no longer supports Ruby 1.8.x
|
30
|
-
|
31
|
-
**Version 2.1** of @softlayer_api@ builds an object model of SoftLayer clases on top of the low-level SoftLayer API calls. The object model provides a high-level interface to the elements within the SoftLayer environment and encapsulates some of the details of the "raw" SoftLayer API.
|
32
|
-
|
33
|
-
|
34
|
-
With this first release, the Object Model provides classes for the SoftLayer Account, Bare Metal and Virutal servers, and Tickets. The model also provides classes to help you place orders for both Bare Metal and Virtual Servers. The class structure is not meant to be comprehensive. Our goal is to provide a simple API for performing common operations.
|
35
|
-
|
36
|
-
Interface documentation for the new object hierarchy is available in the gem's source. More comprehensive documentation including a design guide for new clases and a contribution guide for developers will be added in the future.
|
37
|
-
|
38
|
-
**Version 2.0** of the @softlayer_api@ gem changes the protocol used to communicate with the SoftLayer API from REST to XML-RPC. This change alone should not require any changes to scripts written to the version 1.0 gem. However there are two new behaviors which will require existing version 1.0 scripts to change:
|
39
|
-
|
40
|
-
* Object Masks are now sent to the server using the "Extended Object Mask Format":http://sldn.softlayer.com/article/Object-Masks.
|
41
|
-
* Result limits are now specified using a single call rather than requiring two
|
42
|
-
|
43
|
-
The gem now allows you to specify your SoftLayer username and API key through a config file. See "Providing authentication in a config file":#config_authorization for more information.
|
44
|
-
|
45
|
-
h3. XML-RPC
|
46
|
-
|
47
|
-
In the broad view of the SoftLayer API, when sending requests to the server, an API client may use "SOAP":http://sldn.softlayer.com/article/SOAP, "XML-RPC":http://sldn.softlayer.com/article/XML-RPC, or "REST":http://sldn.softlayer.com/article/REST. Previous versions of the SoftLayer API Gem used REST to communicate with the server. This version uses XML-RPC. Adopting the XML-RPC transport mechanism allows the Gem to take adavantage of features of the API that are not available through the REST interface.
|
48
|
-
|
49
|
-
h3. Extended Object Masks
|
50
|
-
|
51
|
-
In previous versions of the SoftLayer Gem the @object_mask@ call modifier accepted Ruby structres like Arrays and Hashes and would do its best to construct Object Masks from them. @object_mask@ now expects masks to be passed as strings in the "Object Mask":http://sldn.softlayer.com/article/Object-Masks format and passes them through to the API for processing. If you are using @object_mask@, you will probably have to change your existing scripts.
|
52
|
-
|
53
|
-
The Gem extends the Ruby @Hash@ class with a method, @to_sl_object_mask@, which can help with the conversion between masks made of structured objects and the string format. This method, however, must be called explicitly. Here is an example of calling @to_sl_object_mask@:
|
54
|
-
|
55
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">mask_hash = { "mask" => ["id", {"assignedUser" => ["id", "username"]}, "createDate"],
|
56
|
-
"mask(SoftLayer_Hardware_Server)" => ["id", "bareMetalInstanceFlag"] }
|
57
|
-
mask_string = mask_hash.to_sl_object_mask
|
58
|
-
# mask_string is "[mask[id,assignedUser[id,username],createDate],mask(SoftLayer_Hardware_Server)[id,bareMetalInstanceFlag]]"
|
59
|
-
</code></pre>
|
60
|
-
|
61
|
-
h3. Result Limits
|
62
|
-
|
63
|
-
In previous versions of the SoftLayer API Gem, result limits were specified using two API filters:
|
64
|
-
|
65
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">account_service.result_offset(3).result_limit(5).getOpenTickets # this is the "old way" of specifying a result limit
|
66
|
-
</code></pre>
|
67
|
-
|
68
|
-
These two API filters have been combined into a single result limits filter:
|
69
|
-
|
70
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">account_service.result_limit(3, 5).getOpenTickets # this is the "new way" of supplying a result limit
|
71
|
-
</code></pre>
|
72
|
-
|
73
|
-
h2(#installation). Installation
|
74
|
-
|
75
|
-
The Ruby client is available as the @softlayer_api@ Ruby gem. On most systems, the command:
|
76
|
-
|
77
|
-
@gem install softlayer_api@
|
78
|
-
|
79
|
-
installs the gem and makes it available to Ruby scripts. Where the gem is installed on your computer will depend on your particular distribution of Ruby. Refer to the gem documentation for your distribution for more information.
|
80
|
-
|
81
|
-
h2. Usage
|
82
|
-
|
83
|
-
To begin using the Ruby client, you will have to create an instance of the @SoftLayer::Client@. From the Client you must obtain @SoftLayer::Service@ objects corresponding to each of the "API Services":http://sldn.softlayer.com/reference/services that your code wants to call. To create the client instance, you will have to provide information that the library will use to authenticate your account with the API servers.
|
84
|
-
|
85
|
-
h3. Authentication
|
86
|
-
|
87
|
-
That instance will have to know your "API authentication information":http://sldn.softlayer.com/article/Authenticating_to_the_SoftLayer_API consisting of your account username and API key. In addition, you will have to select an endpoint, the web address the client will use to contact the SoftLayer API. You may provide this information in a configuration file, through global variables, or by passing them to the constructor.
|
88
|
-
|
89
|
-
h4(#config_authorization). Providing authentication in a config file
|
90
|
-
|
91
|
-
The Ruby client will look for a configuration file that can provide the username and api_key for requests. A sample configuraiton file looks like this:
|
92
|
-
|
93
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">[softlayer]
|
94
|
-
username = joeusername
|
95
|
-
api_key = DEADBEEFBADF00D
|
96
|
-
</code></pre>
|
97
|
-
|
98
|
-
It is important that the config file declare the section "softlayer". The keys accepted in that section are @username@, @api_key@, and @endpoint_url@. You will have to provide an explicit endpoint url, for example, if you want to use the SoftLayer private network API endpoint.
|
99
|
-
|
100
|
-
The client will look for configuration files in your home directory under the name ".softlayer" or in the directory @/etc/softlayer.conf@
|
101
|
-
|
102
|
-
h4. Providing authentication information through Globals
|
103
|
-
|
104
|
-
The SoftLayer Ruby Client makes use of three global variables, in the @SoftLayer@ name space, related to creating instances of the @SoftLayer::Service@ class:
|
105
|
-
|
106
|
-
table{position:relative;left:2em;width:80%}.
|
107
|
-
|{vertical-align:baseline;width:30%}.@$SL_API_USERNAME@|A string used as the default username used when creating @Service@ objects|
|
108
|
-
|{vertical-align:baseline}.@$SL_API_KEY@|A string used as the default API key used when creating @Service@ objects.|
|
109
|
-
|{vertical-align:baseline}.@$SL_API_BASE_URL@|The endpoint base URL used by the service. This variable defaults to @API_PUBLIC_ENDPOINT@ |
|
110
|
-
|
111
|
-
If you are going to create a lot of different @Service@ objects and they are all going to use the same authentication information it may be convenient to set the values in these globals.
|
112
|
-
|
113
|
-
In addition to the globals, the @SoftLayer@ namespace defines two constants representing the endpoints for the SoftLayer API on the private and public networks:
|
114
|
-
|
115
|
-
table{position:relative;left:2em;width:80%}.
|
116
|
-
|{vertical-align:baseline;width:35%}.@API_PUBLIC_ENDPOINT@|A constant containing the base address for the public network XML-RPC endpoint of the SoftLayer API - @https://api.softlayer.com/xmlrpc/v3/@|
|
117
|
-
|{vertical-align:baseline}.@API_PRIVATE_ENDPOINT@|A constant containing the base address for the private network XML-RPC endpoint of the SoftLayer API - @https://api.service.softlayer.com/xmlrpc/v3/@|
|
118
|
-
|
119
|
-
For more information about the two networks see "Choosing_the_Public_or_Private_Network":http://sldn.softlayer.com/article/The_SoftLayer_API#Choosing_the_Public_or_Private_Network. You can change the default endpoint URL by setting the global variable @$SL_API_BASE_URL@ to either of these two values.
|
120
|
-
|
121
|
-
Here is an example of using these globals to create a service:
|
122
|
-
|
123
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">$SL_API_USERNAME = "joeusername";
|
124
|
-
$SL_API_KEY = "omitted_for_brevity"
|
125
|
-
|
126
|
-
client = SoftLayer::Client.new()
|
127
|
-
account_service = client.service_named("Account")
|
128
|
-
</code></pre>
|
129
|
-
|
130
|
-
Note that the endpoint URL is not specified. The default endpoint URL is set to the @API_PUBLIC_ENDPOINT@
|
131
|
-
|
132
|
-
h4. Providing authentication information through the Constructor
|
133
|
-
|
134
|
-
You can provide the authentication information needed by a @Client@ object as hash arguments in the constructor. The keys used in the hash arguments are symbols whose values should be strings:
|
135
|
-
|
136
|
-
table{position:relative;left:2em;width:80%}.
|
137
|
-
|{vertical-align:baseline;width:30%}.@:username@|The username used to authenticate with the server.|
|
138
|
-
|{vertical-align:baseline}.@:api_key@|The API key used to authenticate with the server.|
|
139
|
-
|{vertical-align:baseline}.@:endpoint_url@|The endpoint address that will receive the method calls.|
|
140
|
-
|
141
|
-
Here is an example, analogous to the one for global variables, which provides the username and API key as hash arguments. This example also changes the endpoint with the @:endpoint_url@ symbol so that the service will use the API on the SoftLayer Private Network:
|
142
|
-
|
143
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">client = SoftLayer::Client.new(:username => "joeusername",
|
144
|
-
:api_key => "omitted_for_brevity",
|
145
|
-
:endpoint_url => API_PRIVATE_ENDPOINT)
|
146
|
-
account_service = client.service_named("Account")
|
147
|
-
</code></pre>
|
148
|
-
|
149
|
-
h3. Calling Service Methods
|
150
|
-
|
151
|
-
With an instance of @SoftLayer::Service@ in hand, you can call the methods provided by that service. Calling a API method on a service is as easy as calling a Ruby method on the service object. For example, given the @account_service@ objects created above, a call to get a list of the open tickets on an account using the @SoftLayer_Account@ service's @getOpenTickets@ method would look like this:
|
152
|
-
|
153
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">open_tickets = account_service.getOpenTickets
|
154
|
-
</code></pre>
|
155
|
-
|
156
|
-
If the method requires arguments, you can supply them as arguments to the method you're calling on the service object. The arguments should be arguments that XML-RPC can encode into XML. Generally this means your argument should be hashes, arrays, strings, numbers, booleans, or nil.
|
157
|
-
|
158
|
-
Here is an example of calling the @createStandardTicket@ method on a ticket service. This example also uses the "bracket" syntax on a client @client['<service-name>']@ to obtain the service object:
|
159
|
-
|
160
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">#authentication information will be found in the global variables
|
161
|
-
client = SoftLayer::Client.new()
|
162
|
-
ticket_service = client['Ticket']
|
163
|
-
new_ticket = ticket_service.createStandardTicket(
|
164
|
-
{
|
165
|
-
"assignedUserId" => my_account_id,
|
166
|
-
"subjectId" => 1022,
|
167
|
-
"notifyUserOnUpdateFlag" => true
|
168
|
-
},
|
169
|
-
"This is a test ticket created from a Ruby client")
|
170
|
-
</code></pre>
|
171
|
-
|
172
|
-
h4. Identifying Particular Objects
|
173
|
-
|
174
|
-
Some method calls in the SoftLayer API are made on particular objects, rather than on the services themselves. These objects, however, are always obtained by a service. To call a method on a particular object you can chain a call to @object_with_id@ onto the service that provides the object in question. @object_with_id@ takes one argument, the object id of the object you are interested in. For example, if you were interested in getting the Ticket with a ticket id of 123456 you could so so by calling:
|
175
|
-
|
176
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">ticket_of_interest = ticket_service.object_with_id(123456).getObject
|
177
|
-
</code></pre>
|
178
|
-
|
179
|
-
The @object_with_id@ call returns an object that you can use as a reference to a particular object through the service. This allows you to reuse that object multiple times without having to repeatedly tack @object_with_id@ on to all your requests. For example, if you want to find a ticket with the id 98765 and add an update to it if it's assigned to user 123456, you might write code like this:
|
180
|
-
|
181
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">begin
|
182
|
-
ticket_ref = ticket_service.object_with_id(98765)
|
183
|
-
ticket = ticket_ref.object_mask("mask.assignedUserId").getObject
|
184
|
-
if ticket['assignedUserId'] == 123456
|
185
|
-
updates = ticket_ref.addUpdate({"entry" => "Get to work on these tickets!"})
|
186
|
-
end
|
187
|
-
rescue Exception => exception
|
188
|
-
puts "An error occurred while updating the ticket: #{exception}"
|
189
|
-
end
|
190
|
-
</code></pre>
|
191
|
-
|
192
|
-
The code creates a variable named @ticket_ref@ which refers to ticket 98765 through the tickets_service. This @ticket_ref@ is used with an @object_mask@ to retrieve the ticket and, if the ticket meets the conditional requirement, that same @ticket_ref@ is reused to add an update to the ticket.
|
193
|
-
|
194
|
-
h4. Adding an Object Mask
|
195
|
-
|
196
|
-
If you wish to limit the volume of information that the server returns about a particular object, you can use an Object Mask to indicate exactly which attributes you are interested in. To provide an Object Mask you simply insert a call to @object_mask@ in the call chain for the method you are invoking.
|
197
|
-
|
198
|
-
The arguments to @object_mask@ must strings. Each string should be a well defined Object Mask as defined in the "SLDN documentation":http://sldn.softlayer.com/article/Object-Masks.
|
199
|
-
|
200
|
-
To look at some examples, consider the following object from the server. It has four properties: @id@, @title@, @createDate@ and @modifyDate@. It also has an entity, @assignedUser@. The @assignedUser@ entity has three properties: @id@, @username@, and @health@.
|
201
|
-
|
202
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">{
|
203
|
-
"id"=>1736473,
|
204
|
-
"title"=>"VM Polling Failure - unable to login",
|
205
|
-
"createDate"=>"2010-04-22T00:12:36-05:00",
|
206
|
-
"modifyDate"=>"2010-06-09T06:44:18-05:00"
|
207
|
-
"assignedUser"=> {
|
208
|
-
"id"=>14
|
209
|
-
"username"=>"AlfredQHacker",
|
210
|
-
"health"=>"Fantastic"
|
211
|
-
},
|
212
|
-
}</code></pre>
|
213
|
-
|
214
|
-
If we were making a request to the server to retrieve this object, or an array of such objects, we might want to limit the response so that it contains just the @id@ fields:
|
215
|
-
|
216
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">an_api_service.object_mask("mask.id").getObject
|
217
|
-
=> {"id"=>1736473}
|
218
|
-
</code></pre>
|
219
|
-
|
220
|
-
If we want more than one property back from the server the call to @object_mask@ can identify multiple properties as separate argumnents:
|
221
|
-
|
222
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">an_api_service.object_mask("mask[id,createDate]").getObject
|
223
|
-
=> {"id"=>1736473, "createDate"=>"2010-04-22T00:12:36-05:00"}
|
224
|
-
</code></pre>
|
225
|
-
|
226
|
-
If we ask for the @assignedUser@ we get back that entire entity:
|
227
|
-
|
228
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">an_api_service.object_mask("mask.assignedUser").getObject
|
229
|
-
=> {"assignedUser"=> {"id"=>14, "username"=>"AlfredQHacker", "health"=>"Fantastic"}}
|
230
|
-
</code></pre>
|
231
|
-
|
232
|
-
However, we may not be interested in the entire assigned user entity, we may
|
233
|
-
want to get just the id of the assigned user:
|
234
|
-
|
235
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">an_api_service.object_mask("mask[assignedUser.id]").getObject
|
236
|
-
=> {"assignedUser"=>{"id"=>14}}
|
237
|
-
</code></pre>
|
238
|
-
|
239
|
-
We can identify a particular set of attributes we are interested in by combining Object Mask forms:
|
240
|
-
|
241
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">an_api_service.object_mask("mask[assignedUser[id,health]]").getObject # retrieving multiple properties
|
242
|
-
=> {"assignedUser"=>{"id"=>14, "health"=>"Fantastic"}}
|
243
|
-
</code></pre>
|
244
|
-
|
245
|
-
Object masks are sent to the server and applied on the server side. Errors in the object mask format will lead to exceptions being thrown by the SoftLayer API. By carefully choosing an Object Mask, you can limit amount of information transferred from the server which may improve bandwidth and processing time.
|
246
|
-
|
247
|
-
You @object_with_id@ should only be called once in any calling sequence. You may call @object_mask@ multiple times, but the server may generate a warning if the Object Masks ask for duplicate properties of some object.
|
248
|
-
|
249
|
-
h2. Examples
|
250
|
-
|
251
|
-
Here are some examples that demonstrate using the SoftLayer API Ruby Client. The authentication information, of course, is left as an exercise for the reader. The first example uses the @getObject@ method of the "SoftLayer_Account":http://sldn.softlayer.com/reference/services service:
|
252
|
-
|
253
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">require 'rubygems'
|
254
|
-
require 'softlayer_api'
|
255
|
-
require 'pp'
|
256
|
-
|
257
|
-
begin
|
258
|
-
# use an account service to get a list of the open tickets and print their IDs and titles
|
259
|
-
client = SoftLayer::Client.new(
|
260
|
-
:username => "joecustomer", # enter your username here
|
261
|
-
:api_key => "feeddeadbeefbadf00d...") # enter your api key here
|
262
|
-
|
263
|
-
account_service = client['Account']
|
264
|
-
account = account_service.getObject
|
265
|
-
pp account
|
266
|
-
rescue Exception => exception
|
267
|
-
puts "Unable to retrieve account information: #{exception}"
|
268
|
-
end
|
269
|
-
</code></pre>
|
270
|
-
|
271
|
-
This second example retrieves some of the information in a support ticket then adds and update to that ticket. It uses an object_with_id to create an object
|
272
|
-
that references a ticket with a particular ID and reuses that reference later to refer to the same ticket. It combines that reference with an @object_mask@ to limit the amount of information transferred from the server.
|
273
|
-
|
274
|
-
<pre style="border:1pt solid black;background:#eee;padding:0.5em;margin:0.5em"><code style="font-family:Menlo,Monaco,monospace;font-size:9pt">require 'rubygems'
|
275
|
-
require 'softlayer_api'
|
276
|
-
require 'pp'
|
277
|
-
|
278
|
-
client = SoftLayer::Client.new()
|
279
|
-
:username => "joecustomer", # enter your username here
|
280
|
-
:api_key => "feeddeadbeefbadf00d...") # enter your api key here
|
281
|
-
|
282
|
-
ticket_service = client.service_named('Ticket')
|
283
|
-
|
284
|
-
begin
|
285
|
-
# this creates an alias to the ticket service bound to the ticket with the id 123456
|
286
|
-
ticket_ref = ticket_service.object_with_id(123456) # you'll have to substitute your own ticket ID
|
287
|
-
|
288
|
-
ticket = ticket_ref.object_mask("mask[updates[entry,createDate],assignedUserId,attachedHardware.datacenter]").getObject
|
289
|
-
pp ticket
|
290
|
-
rescue Exception => exception
|
291
|
-
puts "Unable to retrieve the ticket"
|
292
|
-
end
|
293
|
-
|
294
|
-
# update the ticket
|
295
|
-
begin
|
296
|
-
updates = ticket_ref.addUpdate({"entry" => "An update from the Ruby client!"})
|
297
|
-
puts "Update ticket 123456. The new update's id is #{updates[0]['id']}"
|
298
|
-
rescue Exception => exception
|
299
|
-
puts "Unable to update the ticket: #{exception}"
|
300
|
-
end
|
301
|
-
</code></pre>
|
302
|
-
|
303
|
-
h2. Author
|
304
|
-
|
305
|
-
This software is written by the SoftLayer Development Team <"sldn@softlayer.com":mailto:sldn@softlayer.com>.
|
306
|
-
|
307
|
-
Please join us in the "SoftLayer Developer Network forums":http://forums.softlayer.com/forum/softlayer-developer-network
|
308
|
-
|
309
|
-
h2. Copyright
|
310
|
-
|
311
|
-
This software is Copyright (c) 2010-2014 "SoftLayer Technologies, Inc":http://www.softlayer.com/. See the bundled LICENSE.textile file for more information.
|