softlayer_api 1.0.8 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.textile +116 -66
- data/examples/{accountInformation.rb → account_info.rb} +6 -4
- data/examples/{createTicket.rb → create_ticket.rb} +6 -3
- data/examples/{openTickets.rb → open_tickets.rb} +6 -4
- data/examples/ticket_info.rb +8 -8
- data/lib/softlayer/APIParameterFilter.rb +131 -0
- data/lib/softlayer/Client.rb +100 -0
- data/lib/softlayer/Config.rb +77 -0
- data/lib/softlayer/ObjectFilter.rb +232 -0
- data/lib/softlayer/Service.rb +321 -0
- data/lib/softlayer/base.rb +11 -7
- data/lib/softlayer/object_mask_helpers.rb +60 -13
- data/lib/softlayer_api.rb +6 -1
- metadata +21 -17
- data/lib/softlayer/service.rb +0 -467
data/lib/softlayer_api.rb
CHANGED
@@ -22,4 +22,9 @@
|
|
22
22
|
|
23
23
|
require 'softlayer/base'
|
24
24
|
require 'softlayer/object_mask_helpers'
|
25
|
-
require 'softlayer/
|
25
|
+
require 'softlayer/APIParameterFilter'
|
26
|
+
require 'softlayer/ObjectFilter'
|
27
|
+
require 'softlayer/Config'
|
28
|
+
|
29
|
+
require 'softlayer/Client'
|
30
|
+
require 'softlayer/Service'
|
metadata
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: softlayer_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
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-
|
11
|
+
date: 2014-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.8'
|
20
|
-
- -
|
20
|
+
- - '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.8.1
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1.8'
|
30
|
-
- -
|
30
|
+
- - '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.8.1
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - '>='
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
description: The softlayer_api gem offers a convenient mechanism for invoking the
|
@@ -51,16 +51,20 @@ executables: []
|
|
51
51
|
extensions: []
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
|
-
- LICENSE.textile
|
55
54
|
- README.textile
|
56
|
-
-
|
57
|
-
-
|
58
|
-
- examples/openTickets.rb
|
59
|
-
- examples/ticket_info.rb
|
55
|
+
- LICENSE.textile
|
56
|
+
- lib/softlayer/APIParameterFilter.rb
|
60
57
|
- lib/softlayer/base.rb
|
58
|
+
- lib/softlayer/Client.rb
|
59
|
+
- lib/softlayer/Config.rb
|
61
60
|
- lib/softlayer/object_mask_helpers.rb
|
62
|
-
- lib/softlayer/
|
61
|
+
- lib/softlayer/ObjectFilter.rb
|
62
|
+
- lib/softlayer/Service.rb
|
63
63
|
- lib/softlayer_api.rb
|
64
|
+
- examples/account_info.rb
|
65
|
+
- examples/create_ticket.rb
|
66
|
+
- examples/open_tickets.rb
|
67
|
+
- examples/ticket_info.rb
|
64
68
|
homepage: http://sldn.softlayer.com/
|
65
69
|
licenses:
|
66
70
|
- MIT
|
@@ -71,17 +75,17 @@ require_paths:
|
|
71
75
|
- lib
|
72
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
77
|
requirements:
|
74
|
-
- -
|
78
|
+
- - '>='
|
75
79
|
- !ruby/object:Gem::Version
|
76
80
|
version: '0'
|
77
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
82
|
requirements:
|
79
|
-
- -
|
83
|
+
- - '>='
|
80
84
|
- !ruby/object:Gem::Version
|
81
85
|
version: '0'
|
82
86
|
requirements: []
|
83
87
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.
|
88
|
+
rubygems_version: 2.0.14
|
85
89
|
signing_key:
|
86
90
|
specification_version: 4
|
87
91
|
summary: Library for accessing the SoftLayer portal API
|
data/lib/softlayer/service.rb
DELETED
@@ -1,467 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
-
# of this software and associated documentation files (the "Software"), to deal
|
6
|
-
# in the Software without restriction, including without limitation the rights
|
7
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
-
# copies of the Software, and to permit persons to whom the Software is
|
9
|
-
# furnished to do so, subject to the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be included in
|
12
|
-
# all copies or substantial portions of the Software.
|
13
|
-
#
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
-
# THE SOFTWARE.
|
21
|
-
#
|
22
|
-
|
23
|
-
require 'rubygems'
|
24
|
-
require 'net/https'
|
25
|
-
require 'json/add/core'
|
26
|
-
|
27
|
-
module SoftLayer
|
28
|
-
# A subclass of Exception with nothing new provided. This simply provides
|
29
|
-
# a unique type for exceptions from the SoftLayer API
|
30
|
-
class SoftLayerAPIException < RuntimeError
|
31
|
-
end
|
32
|
-
|
33
|
-
# An APIParameterFilter is an intermediary object that understands how
|
34
|
-
# to accept the other API parameter filters and carry their values to
|
35
|
-
# method_missing in Service. Instances of this class are created
|
36
|
-
# internally by the Service in it's handling of a method call and you
|
37
|
-
# should not have to create instances of this class directly.
|
38
|
-
#
|
39
|
-
# Instead, to use an API filter, you add a filter method to the call
|
40
|
-
# chain when you call a method through a SoftLayer::Service
|
41
|
-
#
|
42
|
-
# For example, given a SoftLayer::Service instance called "account_service"
|
43
|
-
# you could take advantage of the API filter that identifies a particular
|
44
|
-
# object known to that service using the 'object_with_id" method :
|
45
|
-
#
|
46
|
-
# account_service.object_with_id(91234).getSomeAttribute
|
47
|
-
#
|
48
|
-
# The invocation of object_with_id will cause an instance of this
|
49
|
-
# class to be instantiated with the service as its target.
|
50
|
-
#
|
51
|
-
class APIParameterFilter
|
52
|
-
attr_accessor :target
|
53
|
-
attr_accessor :parameters
|
54
|
-
|
55
|
-
def initialize
|
56
|
-
@parameters = {}
|
57
|
-
end
|
58
|
-
|
59
|
-
def server_object_id
|
60
|
-
self.parameters[:server_object_id]
|
61
|
-
end
|
62
|
-
|
63
|
-
def server_object_mask
|
64
|
-
self.parameters[:object_mask]
|
65
|
-
end
|
66
|
-
|
67
|
-
def object_with_id(value)
|
68
|
-
merged_object = APIParameterFilter.new;
|
69
|
-
merged_object.target = self.target
|
70
|
-
merged_object.parameters = @parameters.merge({ :server_object_id => value })
|
71
|
-
merged_object
|
72
|
-
end
|
73
|
-
|
74
|
-
def object_mask(*args)
|
75
|
-
merged_object = APIParameterFilter.new;
|
76
|
-
merged_object.target = self.target
|
77
|
-
merged_object.parameters = @parameters.merge({ :object_mask => args }) if args && !args.empty?
|
78
|
-
merged_object
|
79
|
-
end
|
80
|
-
|
81
|
-
def result_limit(limit)
|
82
|
-
merged_object = APIParameterFilter.new;
|
83
|
-
merged_object.target = self.target
|
84
|
-
merged_object.parameters = @parameters.merge({ :result_limit => limit })
|
85
|
-
merged_object
|
86
|
-
end
|
87
|
-
|
88
|
-
def server_result_limit
|
89
|
-
self.parameters[:result_limit]
|
90
|
-
end
|
91
|
-
|
92
|
-
def result_offset(offset)
|
93
|
-
self.parameters[:result_offset] = offset
|
94
|
-
self
|
95
|
-
end
|
96
|
-
|
97
|
-
def server_result_offset
|
98
|
-
self.parameters[:result_offset]
|
99
|
-
end
|
100
|
-
|
101
|
-
def method_missing(method_name, *args, &block)
|
102
|
-
return @target.call_softlayer_api_with_params(method_name, self, args, &block)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# = SoftLayer API Service
|
107
|
-
#
|
108
|
-
# Instances of this class represent services in the SoftLayer API.
|
109
|
-
#
|
110
|
-
# You create a service with the name of one of the SoftLayer services
|
111
|
-
# (documented on the http://sldn.softlayer.com web site). Once created
|
112
|
-
# you can use the service to make method calls to the SoftLayer API.
|
113
|
-
#
|
114
|
-
# A typical use might look something like
|
115
|
-
#
|
116
|
-
# account_service = SoftLayer::Service("SoftLayer_Account", :username=>"<your user name here>" :api_key=>"<your api key here>")
|
117
|
-
#
|
118
|
-
# then to invoke a method simply call the service:
|
119
|
-
#
|
120
|
-
# account_service.getOpenTickets
|
121
|
-
# => {... lots of information here representing the list of open tickets ...}
|
122
|
-
#
|
123
|
-
class Service
|
124
|
-
# The name of the service that this object calls. Cannot be emtpy or nil.
|
125
|
-
attr_accessor :service_name
|
126
|
-
|
127
|
-
# A username passed as authentication for each request. Cannot be emtpy or nil.
|
128
|
-
attr_accessor :username
|
129
|
-
|
130
|
-
# An API key passed as part of the authentication of each request. Cannot be emtpy or nil.
|
131
|
-
attr_accessor :api_key
|
132
|
-
|
133
|
-
# The base URL for requests that are passed to the server. Cannot be emtpy or nil.
|
134
|
-
attr_accessor :endpoint_url
|
135
|
-
|
136
|
-
# The User-Agent header sent to SoftLayer API.
|
137
|
-
attr_accessor :user_agent
|
138
|
-
|
139
|
-
# Initialize an instance of the Client class. You pass in the service name
|
140
|
-
# and optionally hash arguments specifying how the client should access the
|
141
|
-
# SoftLayer API.
|
142
|
-
#
|
143
|
-
# The following symbols can be used as hash arguments to pass options to the constructor:
|
144
|
-
# - <tt>:username</tt> - a non-empty string providing the username to use for requests to the service
|
145
|
-
# - <tt>:api_key</tt> - a non-empty string providing the api key to use for requests to the service
|
146
|
-
# - <tt>:endpoint_url</tt> - a non-empty string providing the endpoint URL to use for requests to the service
|
147
|
-
#
|
148
|
-
# If any of the options above are missing then the constructor will try to use the corresponding
|
149
|
-
# global variable declared in the SoftLayer Module:
|
150
|
-
# - <tt>$SL_API_USERNAME</tt>
|
151
|
-
# - <tt>$SL_API_KEY</tt>
|
152
|
-
# - <tt>$SL_API_BASE_URL</tt>
|
153
|
-
#
|
154
|
-
def initialize(service_name, options = {})
|
155
|
-
raise SoftLayerAPIException.new("Please provide a service name") if service_name.nil? || service_name.empty?
|
156
|
-
self.service_name = service_name;
|
157
|
-
|
158
|
-
# pick up the username provided in options or the default one from the *globals*
|
159
|
-
self.username = options[:username] || $SL_API_USERNAME || ""
|
160
|
-
|
161
|
-
# pick up the api_key provided in options or the default one from the globals
|
162
|
-
self.api_key = options[:api_key] || $SL_API_KEY || ""
|
163
|
-
|
164
|
-
# pick up the url endpoint from options or the default one in the globals OR the
|
165
|
-
# public endpoint
|
166
|
-
self.endpoint_url = options[:endpoint_url] || $SL_API_BASE_URL || API_PUBLIC_ENDPOINT
|
167
|
-
|
168
|
-
@user_agent = {"User-Agent" => options[:user_agent] || "SoftLayer API Ruby Client #{SoftLayer::VERSION}"}
|
169
|
-
|
170
|
-
if($DEBUG)
|
171
|
-
@method_missing_call_depth = 0
|
172
|
-
end
|
173
|
-
end #initalize
|
174
|
-
|
175
|
-
# Use this to set the user agent string for this API client.
|
176
|
-
def user_agent=(set)
|
177
|
-
self.user_agent['User-Agent'] = set
|
178
|
-
end
|
179
|
-
|
180
|
-
# Use this as part of a method call chain to identify a particular
|
181
|
-
# object as the target of the request. The parameter is the SoftLayer
|
182
|
-
# object identifier you are interested in. For example, this call
|
183
|
-
# would return the ticket whose ID is 35212
|
184
|
-
#
|
185
|
-
# ticket_service.object_with_id(35212).getObject
|
186
|
-
#
|
187
|
-
def object_with_id(object_of_interest)
|
188
|
-
proxy = APIParameterFilter.new
|
189
|
-
proxy.target = self
|
190
|
-
|
191
|
-
return proxy.object_with_id(object_of_interest)
|
192
|
-
end
|
193
|
-
|
194
|
-
# Use this as part of a method call chain to add an object mask to
|
195
|
-
# the request.The arguments to object mask should be the strings
|
196
|
-
# that are the keys of the mask:
|
197
|
-
#
|
198
|
-
# ticket_service.object_mask("createDate", "modifyDate").getObject
|
199
|
-
#
|
200
|
-
# Before being used, the string passed will be url-encoded by this
|
201
|
-
# routine. (i.e. there is no need to url-encode the strings beforehand)
|
202
|
-
#
|
203
|
-
# As an implementation detail, the object_mask becomes part of the
|
204
|
-
# query on the url sent to the API server
|
205
|
-
#
|
206
|
-
def object_mask(*args)
|
207
|
-
proxy = APIParameterFilter.new
|
208
|
-
proxy.target = self
|
209
|
-
|
210
|
-
return proxy.object_mask(*args)
|
211
|
-
end
|
212
|
-
|
213
|
-
def result_limit(limit)
|
214
|
-
proxy = APIParameterFilter.new
|
215
|
-
proxy.target = self
|
216
|
-
return proxy.result_limit(limit)
|
217
|
-
end
|
218
|
-
|
219
|
-
def result_offset(offset)
|
220
|
-
proxy = APIParameterFilter.new
|
221
|
-
proxy.target = self
|
222
|
-
return proxy.result_offset(offset)
|
223
|
-
end
|
224
|
-
|
225
|
-
# This is the primary mechanism by which requests are made. If you call
|
226
|
-
# the service with a method it doesn't understand, it will send a call to
|
227
|
-
# the endpoint for a method of the same name.
|
228
|
-
#
|
229
|
-
def method_missing(method_name, *args, &block)
|
230
|
-
# During development, if you end up with a stray name in some
|
231
|
-
# code, you can end up in an infinite recursive loop as method_missing
|
232
|
-
# tries to resolve that name (believe me... it happens).
|
233
|
-
# This mechanism looks for what it considers to be an unreasonable call
|
234
|
-
# depth and kills the loop quickly.
|
235
|
-
if($DEBUG)
|
236
|
-
@method_missing_call_depth += 1
|
237
|
-
if @method_missing_call_depth > 3 # 3 is somewhat arbitrary... really the call depth should only ever be 1
|
238
|
-
@method_missing_call_depth = 0
|
239
|
-
raise "stop infinite recursion #{method_name}, #{args.inspect}"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# if we're in debug mode, we put out a little helpful information
|
244
|
-
puts "SoftLayer::Service#method_missing called #{method_name}, #{args.inspect}" if $DEBUG
|
245
|
-
|
246
|
-
result = call_softlayer_api_with_params(method_name, nil, args, &block);
|
247
|
-
|
248
|
-
if($DEBUG)
|
249
|
-
@method_missing_call_depth -= 1
|
250
|
-
end
|
251
|
-
|
252
|
-
return result
|
253
|
-
end
|
254
|
-
|
255
|
-
# Issue an HTTP request to call the given method from the SoftLayer API with
|
256
|
-
# the parameters and arguments given.
|
257
|
-
#
|
258
|
-
# Parameters are information _about_ the call, the object mask or the
|
259
|
-
# particular object in the SoftLayer API you are calling.
|
260
|
-
#
|
261
|
-
# Arguments are the arguments to the SoftLayer method that you wish to
|
262
|
-
# invoke.
|
263
|
-
#
|
264
|
-
# This is intended to be used in the internal
|
265
|
-
# processing of method_missing and need not be called directly.
|
266
|
-
def call_softlayer_api_with_params(method_name, parameters, args, &block)
|
267
|
-
# find out what URL will invoke the method (with the given parameters)
|
268
|
-
request_url = url_to_call_method(method_name, parameters)
|
269
|
-
|
270
|
-
# marshall the arguments into the http_request
|
271
|
-
request_body = marshall_arguments_for_call(args)
|
272
|
-
|
273
|
-
# construct an HTTP request for that method with the given URL
|
274
|
-
http_request = http_request_for_method(method_name, request_url, request_body);
|
275
|
-
http_request.basic_auth(self.username, self.api_key)
|
276
|
-
|
277
|
-
# Send the url request and recover the results. Parse the response (if any)
|
278
|
-
# as JSON
|
279
|
-
json_results = issue_http_request(request_url, http_request, &block)
|
280
|
-
if json_results
|
281
|
-
# The JSON parser for Ruby parses JSON "Text" according to RFC 4627, but
|
282
|
-
# not JSON values. As a result, 'JSON.parse("true")' yields a parsing
|
283
|
-
# exception. To work around this, we force the result JSON text by
|
284
|
-
# including it in Array markers, then take the first element of the
|
285
|
-
# resulting array as the result of the parsing. This should allow values
|
286
|
-
# like true, false, null, and numbers to parse the same way they would in
|
287
|
-
# a browser.
|
288
|
-
parsed_json = JSON.parse("[ #{json_results} ]")[0]
|
289
|
-
|
290
|
-
# if the results indicate an error, convert it into an exception
|
291
|
-
if parsed_json.kind_of?(Hash) && parsed_json['error']
|
292
|
-
raise SoftLayerAPIException.new(parsed_json['error'])
|
293
|
-
end
|
294
|
-
else
|
295
|
-
parsed_json = nil
|
296
|
-
end
|
297
|
-
|
298
|
-
# return the results, if any
|
299
|
-
return parsed_json
|
300
|
-
end
|
301
|
-
|
302
|
-
# Marshall the arguments into a JSON string suitable for the body of
|
303
|
-
# an HTTP message. This is intended to be used in the internal
|
304
|
-
# processing of method_missing and need not be called directly.
|
305
|
-
def marshall_arguments_for_call(args)
|
306
|
-
request_body = nil;
|
307
|
-
|
308
|
-
if(args && !args.empty?)
|
309
|
-
request_body = {"parameters" => args}.to_json
|
310
|
-
end
|
311
|
-
|
312
|
-
return request_body
|
313
|
-
end
|
314
|
-
|
315
|
-
# Given a method name, determine the appropriate HTTP mechanism
|
316
|
-
# for sending a request to execute that method to the server.
|
317
|
-
# and create a Net::HTTP request of that type. This is intended
|
318
|
-
# to be used in the internal processing of method_missing and
|
319
|
-
# need not be called directly.
|
320
|
-
def http_request_for_method(method_name, method_url, request_body = nil)
|
321
|
-
content_type_header = {"Content-Type" => "application/json"}
|
322
|
-
|
323
|
-
# This is a workaround for a potential problem that arises from mis-using the
|
324
|
-
# API. If you call SoftLayer_Virtual_Guest and you call the getObject method
|
325
|
-
# but pass a virtual guest as a parameter, what happens is the getObject method
|
326
|
-
# is called through an HTTP POST verb and the API creates a new CCI that is a copy
|
327
|
-
# of the one you passed in.
|
328
|
-
#
|
329
|
-
# The counter-intuitive creation of a new CCI is unexpected and, even worse,
|
330
|
-
# is something you can be billed for. To prevent that, we ignore the request
|
331
|
-
# body on a "getObject" call and print out a warning.
|
332
|
-
if (method_name == :getObject) && (nil != request_body) then
|
333
|
-
$stderr.puts "Warning - The getObject method takes no parameters. The parameters you have provided will be ignored."
|
334
|
-
request_body = nil
|
335
|
-
end
|
336
|
-
|
337
|
-
if request_body && !request_body.empty?
|
338
|
-
url_request = Net::HTTP::Post.new(method_url.request_uri(), content_type_header.merge(self.user_agent))
|
339
|
-
else
|
340
|
-
url_request = Net::HTTP::Get.new(method_url.request_uri(), self.user_agent)
|
341
|
-
end
|
342
|
-
|
343
|
-
# This warning should be obsolete as we should be using POST if the user
|
344
|
-
# has provided parameters. I'm going to leave it in, however, on the off
|
345
|
-
# chance that it catches a case we aren't expecting.
|
346
|
-
if request_body && !url_request.request_body_permitted?
|
347
|
-
$stderr.puts("Warning - The HTTP request for #{method_name} does not allow arguments to be passed to the server")
|
348
|
-
else
|
349
|
-
# Otherwise, add the arguments as the body of the request
|
350
|
-
url_request.body = request_body
|
351
|
-
end
|
352
|
-
|
353
|
-
url_request
|
354
|
-
end
|
355
|
-
|
356
|
-
# Connect to the network and request the content of the resource
|
357
|
-
# specified. This is used to do the actual work of connecting
|
358
|
-
# to the SoftLayer servers and exchange data. This is intended
|
359
|
-
# to be used in the internal processing of method_missing and
|
360
|
-
# need not be called directly.
|
361
|
-
def issue_http_request(request_url, http_request, &block)
|
362
|
-
# create and run an SSL request
|
363
|
-
https = Net::HTTP.new(request_url.host, request_url.port)
|
364
|
-
https.use_ssl = (request_url.scheme == "https")
|
365
|
-
|
366
|
-
# This line silences an annoying warning message if you're in debug mode
|
367
|
-
https.verify_mode = OpenSSL::SSL::VERIFY_NONE if $DEBUG
|
368
|
-
|
369
|
-
https.start do |http|
|
370
|
-
|
371
|
-
puts "SoftLayer API issuing an HTTP request for #{request_url}" if $DEBUG
|
372
|
-
|
373
|
-
response = https.request(http_request)
|
374
|
-
|
375
|
-
case response
|
376
|
-
when Net::HTTPSuccess
|
377
|
-
return response.body
|
378
|
-
else
|
379
|
-
# We have an error. It might have a meaningful error message
|
380
|
-
# from the server. Check to see if there is a body and whether
|
381
|
-
# or not that body parses as JSON. If it does, then we return
|
382
|
-
# that as a result (assuming it's an error)
|
383
|
-
json_parses = false
|
384
|
-
body = response.body
|
385
|
-
|
386
|
-
begin
|
387
|
-
if body
|
388
|
-
JSON.parse(body)
|
389
|
-
json_parses = true
|
390
|
-
end
|
391
|
-
rescue => json_parse_exception
|
392
|
-
json_parses = false;
|
393
|
-
end
|
394
|
-
|
395
|
-
# Let the HTTP library generate and raise an exception if
|
396
|
-
# the body was empty or could not be parsed as JSON
|
397
|
-
response.value() if !json_parses
|
398
|
-
|
399
|
-
return body
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
# Construct a URL for calling the given method on this endpoint and
|
405
|
-
# expecting a JSON response. This is intended to be used in the internal
|
406
|
-
# processing of method_missing and need not be called directly.
|
407
|
-
def url_to_call_method(method_name, parameters)
|
408
|
-
method_path = method_name.to_s
|
409
|
-
|
410
|
-
# if there's an object ID on the parameters, add that to the URL
|
411
|
-
if(parameters && parameters.server_object_id)
|
412
|
-
method_path = parameters.server_object_id.to_s + "/" + method_path
|
413
|
-
end
|
414
|
-
|
415
|
-
# tag ".json" onto the method path (if it's not already there)
|
416
|
-
method_path.sub!(%r|(\.json){0,1}$|, ".json")
|
417
|
-
|
418
|
-
# put the whole thing together into a URL
|
419
|
-
# (reusing a variation on the clever regular expression above. This one appends a "slash"
|
420
|
-
# to the service name if theres not already one there otherwise. Without it URI.join
|
421
|
-
# doesn't do the right thing)
|
422
|
-
uri = URI.join(self.endpoint_url, self.service_name.sub(%r{/*$},"/"), method_path)
|
423
|
-
|
424
|
-
query_string = nil
|
425
|
-
|
426
|
-
if(parameters && parameters.server_object_mask)
|
427
|
-
mask_value = parameters.server_object_mask.to_sl_object_mask.map { |mask_key| URI.encode(mask_key.to_s.strip) }.join(";")
|
428
|
-
query_string = "objectMask=#{mask_value}"
|
429
|
-
end
|
430
|
-
|
431
|
-
if (parameters && parameters.server_result_limit)
|
432
|
-
resultLimit = parameters.server_result_limit
|
433
|
-
resultOffset = parameters.server_result_offset
|
434
|
-
resultOffset = 0 if resultOffset.nil?
|
435
|
-
limit_string = "resultLimit=#{resultOffset},#{resultLimit}"
|
436
|
-
if query_string.nil?
|
437
|
-
query_string = limit_string
|
438
|
-
else
|
439
|
-
query_string << "&#{limit_string}"
|
440
|
-
end
|
441
|
-
end
|
442
|
-
|
443
|
-
uri.query = query_string
|
444
|
-
|
445
|
-
return uri
|
446
|
-
end
|
447
|
-
|
448
|
-
# Change the username. The username cannot be nil or the empty string.
|
449
|
-
def username= (name)
|
450
|
-
raise SoftLayerAPIException.new("Please provide a username") if name.nil? || name.empty?
|
451
|
-
@username = name.strip
|
452
|
-
end
|
453
|
-
|
454
|
-
# Change the api_key. It cannot be nil or the empty string.
|
455
|
-
def api_key= (new_key)
|
456
|
-
raise SoftLayerAPIException.new("Please provide an api_key") if new_key.nil? || new_key.empty?
|
457
|
-
@api_key = new_key.strip
|
458
|
-
end
|
459
|
-
|
460
|
-
# Change the endpoint_url. It cannot be nil or the empty string.
|
461
|
-
def endpoint_url= (new_url)
|
462
|
-
raise SoftLayerAPIException.new("The endpoint url cannot be nil or empty") if new_url.nil? || new_url.empty?
|
463
|
-
@endpoint_url = new_url.strip
|
464
|
-
end
|
465
|
-
end # class Service
|
466
|
-
end # module SoftLayer
|
467
|
-
|