jamesn-softlayer-ruby 0.6.3.0 → 0.7.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changes CHANGED
@@ -1,4 +1,14 @@
1
1
 
2
+ Changes since 0.6.3
3
+
4
+
5
+ Added a CDNLayer sample
6
+ Refactor slapiCall and realCall to clean up a bit of a mess, fix method parameter handling, and cleans up header handling. There's a bit of an api change here.
7
+ Clean up initParamater handling (so that it actually works again)
8
+ Allow the base class to be replaced with another.
9
+ Split softlayer.rb into three files, one containing just the base class, another containing
10
+ the header and exception classes.
11
+
2
12
  Change since 0.6.1
3
13
 
4
14
  Silenced the name space warning (I think this is a bug in soap4r)
data/lib/softlayer.rb CHANGED
@@ -37,16 +37,23 @@ gem 'soap4r'
37
37
  require 'soap/header/simplehandler'
38
38
  require 'soap/wsdlDriver'
39
39
 
40
+ require 'softlayer/baseclass'
41
+ require 'softlayer/util'
42
+
40
43
 
41
44
  module SoftLayer
42
45
 
46
+ DEFAULTBASE=SoftLayer::BaseClass
47
+
43
48
  # Declare SLAPI clases. Args take class names in two forms:
44
49
  # +soap+:: Service names in SOAP format (example: SoftLayer_Account)
45
50
  # +ruby+:: Class names in Ruby format (example: SoftLayer::Account)
51
+ # +base+:: A substitute base class (otherwise SoftLayer::Base)
46
52
  # Creates the class, and retrieves and caches the endpoint WSDL.
47
53
  def SoftLayer::declareClasses(args)
48
54
  classes = args[:ruby]
49
55
  services = args[:soap]
56
+ base = args[:base]
50
57
 
51
58
  unless (services.nil? || services.empty?)
52
59
  services.each do |s|
@@ -56,7 +63,7 @@ module SoftLayer
56
63
  end
57
64
 
58
65
  classes.each do |cstr|
59
- k = SoftLayer::ClassFactory(:class => cstr)
66
+ k = SoftLayer::ClassFactory(:class => cstr, :base => base)
60
67
  k.cacheWSDL
61
68
  end
62
69
  end
@@ -65,338 +72,42 @@ module SoftLayer
65
72
  # Args:
66
73
  # +class+:: The name of the class to create in Ruby format.
67
74
  # +parent+:: The parent namespace to add the class to (this should be somewere in SoftLayer; optional).
75
+ # +base+:: A substitute base class (otherwise SoftLayer::Base)
68
76
  # This recursively walks up +class+ creating them as needed, so SoftLayer::Dns::Domain will create
69
77
  # classes for Dns and Domain (even though the Dns class will never be used).
70
78
  def SoftLayer::ClassFactory(args)
71
79
  cname = args[:class]
72
80
  parent = args[:parent] unless args[:parent].nil?
81
+ base = args[:base]
82
+ base = DEFAULTBASE if base.nil?
73
83
 
74
84
  cary = cname.split('::')
75
85
  parent = const_get(cary.shift) if parent.nil? # This should always be SoftLayer, but maybe not...
76
86
  cur = cary.shift
77
87
  newclass = nil
78
88
  unless parent.const_defined?(cur)
79
- newclass = SoftLayer::makeSLAPIKlass(:class => cur, :parent => parent)
89
+ newclass = SoftLayer::makeSLAPIKlass(:class => cur, :parent => parent, :base => base)
80
90
  else
81
91
  newclass = parent.const_get(cur)
82
92
  end
83
93
  return newclass if cary.empty?
84
94
 
85
95
  left = cary.join('::')
86
- k = SoftLayer::ClassFactory(:class => left, :parent => newclass)
96
+ k = SoftLayer::ClassFactory(:class => left, :parent => newclass, :base => base)
87
97
  return k
88
98
  end
89
99
 
90
100
  # This really creates the class.
91
101
  # +class+:: The name of the class to create in Ruby format.
92
102
  # +parent+:: The parent namespace to add the class to (this should be somewhere in SoftLayer, not optional).
103
+ # +base+:: A substitute base class (otherwise SoftLayer::Base)
93
104
  def SoftLayer::makeSLAPIKlass(args)
94
105
  cname = args[:class]
95
106
  parent = args[:parent]
107
+ base = args[:base]
96
108
  realKlassName = "#{cname}"
97
- klass = Class.new SoftLayer::BaseClass do
98
-
99
- end
109
+ klass = Class.new base do ; end
100
110
  parent.const_set realKlassName, klass
101
111
  return klass
102
112
  end
103
-
104
- # A class to old Paramaters.
105
- class Param < SOAP::Header::SimpleHandler
106
- def initialize(tag, out)
107
- @out = out
108
- super(XSD::QName.new(nil, tag))
109
- end
110
-
111
- def on_simple_outbound
112
- @out
113
- end
114
-
115
- def [](k)
116
- return @out[k]
117
- end
118
-
119
- def []=(k,v)
120
- @out[k]=v
121
- end
122
- end
123
-
124
- # A class to hold the object mask.
125
- class ObjectMask < SOAP::Header::SimpleHandler
126
-
127
- def initialize(tag, out)
128
- @out = out
129
- super(XSD::QName.new(nil, tag))
130
- end
131
-
132
- def on_simple_outbound
133
- { 'mask' => @out }
134
- end
135
-
136
- def [](k)
137
- @out[k]
138
- end
139
-
140
- def []=(k,v)
141
- @out[k]=v
142
- end
143
- end
144
-
145
- class ResultLimit < SOAP::Header::SimpleHandler
146
- attr_accessor :limit, :offset
147
-
148
- # limit should be an array of two elements; limit and offset.
149
- def initialize(tag, limit)
150
- @limit = limit[0]
151
- @offset = limit[1]
152
- super(XSD::QName.new(nil, tag))
153
- end
154
-
155
- def on_simple_outbound
156
- { 'limit' => @limit, 'offset' => @offset }
157
- end
158
- end
159
-
160
-
161
- # An Exception proxy class
162
- # This doesn't do anything yet, but it probably
163
- # will at some point.
164
- class Exception < RuntimeError
165
-
166
- def initialize(args)
167
- e = args[:exception]
168
- message = args[:message] unless args[:message].nil?
169
- message = e.message unless e.nil?
170
- super(message)
171
-
172
- @realException = e unless e.nil?
173
- @realException = self if @realException.nil?
174
- end
175
- end
176
-
177
- # The Base class for our generated class.
178
- class BaseClass
179
-
180
- WSDLBASE='http://api.service.softlayer.com/soap/v3'
181
- WSDLPARAM='?wsdl'
182
-
183
- @@wsdl = { }
184
- @@apiUser = nil
185
- @@apiKey = nil
186
-
187
- # The initializer.
188
- # Arguments:
189
- # +user+:: The API User
190
- # +key+:: The API Key
191
- # +initParams+:: This object's initParam (just the key)
192
- # +debug+:: Enable debug after driver creation. (IO handler)
193
- #
194
- # +user+ and +key+ are optional. The first time they're presented
195
- # they're saved to class variables and reused later as necessary. Supplying
196
- # +user+ and +key+ later does not overwrite the class variables. +initParams+ is
197
- # required where the api requires it.
198
- def initialize(args)
199
- @apiUser = args[:user] unless args[:user].nil?
200
- @apiKey = args[:key] unless args[:key].nil?
201
- @initParam = args[:initParam]
202
-
203
- @@apiUser = args[:user] unless (args[:user].nil? || !@@apiUser.nil?)
204
- @@apiKey = args[:key] unless (args[:key].nil? || !@@apiKey.nil?)
205
- @apiUser = @@apiUser unless (@@apiUser.nil? || !@apiUser.nil?)
206
- @apiKey = @@apiKey unless (@@apiKey.nil? || !@apiKey.nil?)
207
- @authHeader = Param.new('authenticate', {'username' => @apiUser, 'apiKey' => @apiKey})
208
-
209
- self.class.cacheWSDL
210
- @slapi = @@wsdl[self.soapClass].create_rpc_driver unless @@wsdl[self.soapClass].nil?
211
- raise SoftLayer::Exception.new(:message => 'WSDL endpoint not available.') if @slapi.nil?
212
-
213
- self.debug=args[:debug] unless args[:debug].nil?
214
- end
215
-
216
- # Return this object's matching SLAPI SOAP Class.
217
- def soapClass
218
- return self.class.to_s.gsub(/::/, '_')
219
- end
220
-
221
- # This returns key values from this Service's associated Type (retrieved using #getObject).
222
- def [](key)
223
- @slapiObject = self.getObject if @slapiobject.nil?
224
- return @slapiObject[key.to_s]
225
- end
226
-
227
- def setObject(obj)
228
- @slapiObject = obj
229
- end
230
-
231
- # Set the object mask which ia passed as a hash of optional hashes (otherwise the hash elements should have a nil value).
232
- # Using the example from the wiki:
233
- # <SoftLayer_AccountObjectMask xsi:type="v3:SoftLayer_AccountObjectMask">
234
- # <mask xsi:type="slt:SoftLayer_Account" xmlns:slt="http://api.service.softlayer.com/soap/v3/SLTypes/">
235
- # <domains>
236
- # <resourceRecords />
237
- # </domains>
238
- # <openTickets>
239
- # <assignedUser />
240
- # <attachedHardware />
241
- # <updates />
242
- # </openTickets>
243
- # <userCount />
244
- # </mask>
245
- # </SoftLayer_AccountObjectMask>
246
- #
247
- # { 'domains' => { 'resourceRecords' => nil }, 'openTicket' => { 'assignedUser' => nil, 'attachedHardware' => nil, 'updates' => nil },
248
- # userCount => nil }
249
- # Changing this resets the cached object used by #[]
250
- def objectMask=(mask)
251
- if mask.class == ObjectMask
252
- @objectMask = mask
253
- else
254
- @objectMask = ObjectMask.new("#{self.soapClass}ObjectMask", mask)
255
- end
256
- @slapiObject = nil
257
- end
258
-
259
- def objectMask
260
- return @objectMask
261
- end
262
-
263
- # Set an object wide result set (or clear it)
264
- # arg can be one of three things:
265
- # * nil clears the resultLimit
266
- # * A Result Limit array of two elements range and offset.
267
- # * An existing ResultLimit object
268
- def resultLimit=(arg)
269
- case arg.class
270
- when NilClass
271
- @resultLimit = nil
272
- when Array
273
- @resultLimit = ResultLimit.new('resultLimit',arg)
274
- when ResultLimit
275
- @resultLimit = arg
276
- end
277
- end
278
-
279
- def resultLimit
280
- return @resultLimit
281
- end
282
-
283
-
284
- # Make a direct api call. Paramaters are a hash where the key is passed to ParamHeader as the tag, and the value
285
- # is passed as the tag content, unless it's a magic paramater.
286
- # Magic Paramaters:
287
- # +initParam+:: Initialization paramater for this call (just the key), therwise @initParam is used.
288
- # +limit+:: A Result Limit array of two elements range and offset. If @resultLimit is set it's used
289
- # if +limit+ is not and if neither is set, no limit is applied.
290
- #
291
- # If a block is provided, the limit's range (or fewer) elements will yield to the block until the dataset
292
- # is exhausted. If no limit is provided with the block a limit of [1,0] is assumed initially.
293
- # Aliased to #method_missing.
294
- def slapiCall(method, args = { }, &block)
295
-
296
- initParam = args[:initParam] unless args[:initParam].nil?
297
- args.delete(:initParam) unless args[:initParam].nil?
298
- initParam = Param.new("#{self.soapClass}InitParameters", { 'id' => initParam }) unless initParam.nil?
299
- initParam = @initParam if initParam.nil?
300
- resultLimit = ResultLimit.new('resultLimit', args[:limit]) unless args[:limit].nil?
301
- args.delete(:limit) unless args[:limit].nil?
302
- resultLimit = @resultLimit if resultLimit.nil?
303
-
304
- @slapi.headerhandler << @authHeader unless @slapi.headerhandler.include?(@authHeader)
305
- paramHeaders = []
306
- unless args.nil?
307
- args.each do |k,v|
308
- p = Param.new(k.to_s,v)
309
- paramHeaders.push(p)
310
- @slapi.headerhandler << p
311
- end
312
- end
313
- @slapi.headerhandler << initParam unless @slapi.headerhandler.include?(@authHeader)
314
- @slapi.headerhandler << @objectMask unless @objectMask.nil?
315
- @slapi.headerhandler << resultLimit unless resultLimit.nil?
316
-
317
- if block_given?
318
- go=true
319
- resultLimit = ResultLimit.new('resultLimit', [1,0]) if resultLimit.nil? # this is broken.
320
- @slapi.headerhandler << resultLimit unless @slapi.headerhandler.include?(resultLimit)
321
- while(go) do
322
- res = realCall(method.to_s)
323
- yield(res) unless (res.nil? || (res.respond_to?(:empty) && res.empty?))
324
- go = false if res.nil?
325
- go = false if (res.respond_to?(:size) && (res.size < resultLimit.limit))
326
- resultLimit.offset=resultLimit.offset + resultLimit.limit
327
- end
328
- headerClean(resultLimit,paramHeaders)
329
- return true
330
- else
331
- res = realCall(method.to_s)
332
- headerClean(resultLimit,paramHeaders)
333
- return res
334
- end
335
- end
336
-
337
- # Alias the above slapiCall to #method_missing.
338
- alias_method :method_missing, :slapiCall
339
- # Alias slapiCall to #call specifically because of it's special paramter list.
340
- alias_method :call, :slapiCall
341
-
342
- # Enable (or disable) debug. (paramater is the IO handler to write to)
343
- def debug=(dev)
344
- @slapi.wiredump_dev=(dev)
345
- end
346
-
347
- # Get the WSDL, parse it, and save it to a Class level hash.
348
- # Returns false of we couldn't parse the WSDL.
349
- def self.cacheWSDL
350
- return unless @@wsdl[self.soapClass].nil?
351
-
352
- begin
353
- # XXX: Silence soap4r's bogus use of Kernel#warn
354
- v = $VERBOSE
355
- $VERBOSE=nil
356
- @@wsdl[self.soapClass] = SOAP::WSDLDriverFactory.new(self.wsdlUrl)
357
- $VERBOSE = v
358
- return true
359
- rescue => e
360
- return SoftLayer::Exception.new(:exception => e)
361
- end
362
- end
363
-
364
- # Return this Class's WSDL.
365
- def self.wsdl
366
- return @@wsdl[self.soapClass]
367
- end
368
-
369
- # Return this Class's WSDL URL.
370
- def self.wsdlUrl
371
- return URI.parse("#{WSDLBASE}/#{self.soapClass}#{WSDLPARAM}")
372
- end
373
-
374
- # Returns this Class's SOAP Class.
375
- def self.soapClass
376
- self.name.to_s.gsub(/::/, '_')
377
- end
378
-
379
- private
380
-
381
- # Clean the headers out of the driver.
382
- def headerClean(rl,ha)
383
- @slapi.headerhandler.delete(rl)
384
- ha.each { |h| @slapi.headerhandler.delete(h) }
385
- end
386
-
387
- # This really calls the soap method.
388
- # This catches all exceptions, creates a copy of our exception proxy class
389
- # and copies the message. This insures exceptions make it up to user code
390
- # as opposed to soap4r's tendancy to just exit when there's a soap exception.
391
- # todo: Add header processing/clean up.
392
- def realCall(m)
393
- begin
394
- return @slapi.call(m)
395
- rescue => e
396
- re = SoftLayer::Exception.new(:exception => e)
397
- raise re
398
- end
399
- end
400
-
401
- end
402
113
  end
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env ruby
2
+ # baseclass
3
+ #
4
+ # Author:: James Nuckolls
5
+ # Copyright:: Copyright (c) 2009 SoftLayer. All rights reserved.
6
+ #
7
+ #= Description
8
+ #
9
+ #= ToDo
10
+ #
11
+
12
+ require 'rubygems' rescue LoadError
13
+ gem 'soap4r'
14
+ require 'soap/wsdlDriver'
15
+
16
+ require 'softlayer'
17
+ require 'softlayer/util'
18
+
19
+
20
+ module SoftLayer
21
+ # The Base class for our generated class.
22
+ class BaseClass
23
+ attr_reader :slapi, :initParam
24
+
25
+ WSDLBASE='http://api.service.softlayer.com/soap/v3'
26
+ WSDLPARAM='?wsdl'
27
+
28
+ @@wsdl = { }
29
+ @@apiUser = nil
30
+ @@apiKey = nil
31
+
32
+ # The initializer.
33
+ # Arguments:
34
+ # +user+:: The API User
35
+ # +key+:: The API Key
36
+ # +initParams+:: This object's initParam (just the key)
37
+ # +debug+:: Enable debug after driver creation. (IO handler)
38
+ #
39
+ # +user+ and +key+ are optional. The first time they're presented
40
+ # they're saved to class variables and reused later as necessary. Supplying
41
+ # +user+ and +key+ later does not overwrite the class variables. +initParams+ is
42
+ # required where the api requires it.
43
+ def initialize(args)
44
+ @apiUser = args[:user] unless args[:user].nil?
45
+ @apiKey = args[:key] unless args[:key].nil?
46
+ @initParam = args[:initParam]
47
+ @initParam = Param.new("#{self.soapClass}InitParameters", { 'id' => args[:initParam] }) unless args[:initParam].nil?
48
+
49
+ @@apiUser = args[:user] unless (args[:user].nil? || !@@apiUser.nil?)
50
+ @@apiKey = args[:key] unless (args[:key].nil? || !@@apiKey.nil?)
51
+ @apiUser = @@apiUser unless (@@apiUser.nil? || !@apiUser.nil?)
52
+ @apiKey = @@apiKey unless (@@apiKey.nil? || !@apiKey.nil?)
53
+ @authHeader = Param.new('authenticate', {'username' => @apiUser, 'apiKey' => @apiKey})
54
+
55
+ self.class.cacheWSDL
56
+ @slapi = @@wsdl[self.soapClass].create_rpc_driver unless @@wsdl[self.soapClass].nil?
57
+ raise SoftLayer::Exception.new(:message => 'WSDL endpoint not available.') if @slapi.nil?
58
+
59
+ self.debug=args[:debug] unless args[:debug].nil?
60
+ end
61
+
62
+ # Return this object's matching SLAPI SOAP Class.
63
+ def soapClass
64
+ return self.class.to_s.gsub(/::/, '_')
65
+ end
66
+
67
+ # This returns key values from this Service's associated Type (retrieved using #getObject).
68
+ def [](key)
69
+ @slapiObject = self.getObject if @slapiobject.nil?
70
+ return @slapiObject[key.to_s]
71
+ end
72
+
73
+ def setObject(obj)
74
+ @slapiObject = obj
75
+ end
76
+
77
+ # Set the object mask which ia passed as a hash of optional hashes (otherwise the hash elements should have a nil value).
78
+ # Using the example from the wiki:
79
+ # <SoftLayer_AccountObjectMask xsi:type="v3:SoftLayer_AccountObjectMask">
80
+ # <mask xsi:type="slt:SoftLayer_Account" xmlns:slt="http://api.service.softlayer.com/soap/v3/SLTypes/">
81
+ # <domains>
82
+ # <resourceRecords />
83
+ # </domains>
84
+ # <openTickets>
85
+ # <assignedUser />
86
+ # <attachedHardware />
87
+ # <updates />
88
+ # </openTickets>
89
+ # <userCount />
90
+ # </mask>
91
+ # </SoftLayer_AccountObjectMask>
92
+ #
93
+ # { 'domains' => { 'resourceRecords' => nil }, 'openTicket' => { 'assignedUser' => nil, 'attachedHardware' => nil, 'updates' => nil },
94
+ # userCount => nil }
95
+ # Changing this resets the cached object used by #[]
96
+ def objectMask=(mask)
97
+ if mask.class == ObjectMask
98
+ @objectMask = mask
99
+ else
100
+ @objectMask = ObjectMask.new("#{self.soapClass}ObjectMask", mask)
101
+ end
102
+ @slapiObject = nil
103
+ end
104
+
105
+ def objectMask
106
+ return @objectMask
107
+ end
108
+
109
+ # Set an object wide result set (or clear it)
110
+ # arg can be one of three things:
111
+ # * nil clears the resultLimit
112
+ # * A Result Limit array of two elements range and offset.
113
+ # * An existing ResultLimit object
114
+ def resultLimit=(arg)
115
+ case arg.class
116
+ when NilClass
117
+ @resultLimit = nil
118
+ when Array
119
+ @resultLimit = ResultLimit.new('resultLimit',arg)
120
+ when ResultLimit
121
+ @resultLimit = arg
122
+ end
123
+ end
124
+
125
+ def resultLimit
126
+ return @resultLimit
127
+ end
128
+
129
+
130
+ # Make a direct api call. The values of the paramaters are passed to the method
131
+ # (the keys generally are not), unless it's a magic paramater.
132
+ # Magic Paramaters:
133
+ # +initParam+:: Initialization paramater for this call (just the key), therwise @initParam is used.
134
+ # +limit+:: A Result Limit array of two elements range and offset. If @resultLimit is set it's used \
135
+ # if +limit+ is not and if neither is set, no limit is applied.
136
+ # +header+:: Extra headers to pass to the method in an array.
137
+ #
138
+ # If a block is provided, the limit's range (or fewer) elements will yield to the block until the dataset
139
+ # is exhausted. If no limit is provided with the block a limit of [1,0] is assumed initially (sorta).
140
+ # Aliased to #method_missing.
141
+ def slapiCall(method, args = {}, &block)
142
+ initParam = args[:initParam] unless args[:initParam].nil?
143
+ args.delete(:initParam) unless args[:initParam].nil?
144
+ initParam = Param.new("#{self.soapClass}InitParameters", { 'id' => initParam }) unless initParam.nil?
145
+ initParam = @initParam if initParam.nil?
146
+ resultLimit = ResultLimit.new('resultLimit', args[:limit]) unless args[:limit].nil?
147
+ args.delete(:limit) unless args[:limit].nil?
148
+ resultLimit = @resultLimit if resultLimit.nil?
149
+ unroll = true if resultLimit.nil? && block_given?
150
+ resultLimit = ResultLimit.new('resultLimit', [5,0]) if resultLimit.nil? && block_given?
151
+ headers = args[:header]
152
+ args.delete(:header) unless args[:header].nil?
153
+
154
+ headers = [] if headers.nil?
155
+ headers << initParam unless @slapi.headerhandler.include?(initParam)
156
+ headers << @objectMask unless @objectMask.nil?
157
+ headers << resultLimit unless resultLimit.nil?
158
+ argshash = { :method => method, :headers => headers, :args => args }
159
+ argshash[:yield] = true if block_given?
160
+ catch :done do
161
+ while true do
162
+ res = realCall(argshash)
163
+ return res unless block_given?
164
+ return res if res.nil?
165
+ res.each { |e| yield(e) } if unroll && res.respond_to?(:each)
166
+ yield(res) unless unroll || (res.respond_to?(:empty) && res.empty?)
167
+ throw :done if (res.respond_to?(:size) && (res.size < resultLimit.limit))
168
+ resultLimit.offset=resultLimit.offset + resultLimit.limit
169
+ end
170
+ end
171
+ headerClean(headers) if argshash[:yield]
172
+ end
173
+
174
+ # Alias the above slapiCall to #method_missing.
175
+ alias_method :method_missing, :slapiCall
176
+ # Alias slapiCall to #call specifically because of it's special paramter list.
177
+ alias_method :call, :slapiCall
178
+
179
+ # Enable (or disable) debug. (paramater is the IO handler to write to)
180
+ def debug=(dev)
181
+ @slapi.wiredump_dev=(dev)
182
+ end
183
+
184
+ # Get the WSDL, parse it, and save it to a Class level hash.
185
+ # Returns false of we couldn't parse the WSDL.
186
+ def self.cacheWSDL
187
+ return unless @@wsdl[self.soapClass].nil?
188
+
189
+ begin
190
+ # XXX: Silence soap4r's bogus use of Kernel#warn
191
+ v = $VERBOSE
192
+ $VERBOSE=nil
193
+ @@wsdl[self.soapClass] = SOAP::WSDLDriverFactory.new(self.wsdlUrl)
194
+ $VERBOSE = v
195
+ return true
196
+ rescue => e
197
+ return SoftLayer::Exception.new(:exception => e)
198
+ end
199
+ end
200
+
201
+ # Return this Class's WSDL.
202
+ def self.wsdl
203
+ return @@wsdl[self.soapClass]
204
+ end
205
+
206
+ # Return this Class's WSDL URL.
207
+ def self.wsdlUrl
208
+ return URI.parse("#{WSDLBASE}/#{self.soapClass}#{WSDLPARAM}")
209
+ end
210
+
211
+ # Returns this Class's SOAP Class.
212
+ def self.soapClass
213
+ self.name.to_s.gsub(/::/, '_')
214
+ end
215
+
216
+ private
217
+
218
+ # Clean the headers out of the driver.
219
+ def headerClean(ha)
220
+ ha.each { |h| @slapi.headerhandler.delete(h) }
221
+ end
222
+
223
+ # This really calls the soap method.
224
+ # This catches all exceptions, creates a copy of our exception proxy class
225
+ # and copies the message. This insures exceptions make it up to user code
226
+ # as opposed to soap4r's tendancy to just exit when there's a soap exception.
227
+ # todo: Add header processing/clean up.
228
+ def realCall(args)
229
+ m = args[:method]
230
+ h = args[:headers]
231
+ a = args[:args]
232
+ y = args[:yield]
233
+ @slapi.headerhandler << @authHeader unless @slapi.headerhandler.include?(@authHeader)
234
+ h.each {|e| @slapi.headerhandler << e }
235
+ args = []
236
+ a.each { |k,v| args.push(v) }
237
+ begin
238
+ return @slapi.call(m.to_s, *args)
239
+ rescue => e
240
+ re = SoftLayer::Exception.new(:exception => e)
241
+ raise re
242
+ ensure
243
+ headerClean(h) unless y
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+ # util
3
+ #
4
+ # Author:: James Nuckolls
5
+ # Copyright:: Copyright (c) 2009 SoftLayer. All rights reserved.
6
+ #
7
+ #= Description
8
+ #
9
+ #= ToDo
10
+ #
11
+
12
+ require 'rubygems' rescue LoadError
13
+ gem 'soap4r'
14
+ require 'soap/header/simplehandler'
15
+
16
+
17
+ module SoftLayer
18
+ # A class to old Paramaters.
19
+ class Param < SOAP::Header::SimpleHandler
20
+ def initialize(tag, out)
21
+ @out = out
22
+ super(XSD::QName.new(nil, tag))
23
+ end
24
+
25
+ def on_simple_outbound
26
+ @out
27
+ end
28
+
29
+ def [](k)
30
+ return @out[k]
31
+ end
32
+
33
+ def []=(k,v)
34
+ @out[k]=v
35
+ end
36
+ end
37
+
38
+ # A class to hold the object mask.
39
+ class ObjectMask < SOAP::Header::SimpleHandler
40
+
41
+ def initialize(tag, out)
42
+ @out = out
43
+ super(XSD::QName.new(nil, tag))
44
+ end
45
+
46
+ def on_simple_outbound
47
+ { 'mask' => @out }
48
+ end
49
+
50
+ def [](k)
51
+ @out[k]
52
+ end
53
+
54
+ def []=(k,v)
55
+ @out[k]=v
56
+ end
57
+ end
58
+
59
+ class ResultLimit < SOAP::Header::SimpleHandler
60
+ attr_accessor :limit, :offset
61
+
62
+ # limit should be an array of two elements; limit and offset.
63
+ def initialize(tag, limit)
64
+ @limit = limit[0]
65
+ @offset = limit[1]
66
+ super(XSD::QName.new(nil, tag))
67
+ end
68
+
69
+ def on_simple_outbound
70
+ { 'limit' => @limit, 'offset' => @offset }
71
+ end
72
+ end
73
+
74
+
75
+ # An Exception proxy class
76
+ # Not every exception soap4r returns decends from RuntimeError.
77
+ class Exception < RuntimeError
78
+
79
+ def initialize(args)
80
+ e = args[:exception]
81
+ message = args[:message] unless args[:message].nil?
82
+ message = e.message unless e.nil?
83
+ super(message)
84
+
85
+ @realException = e unless e.nil?
86
+ @realException = self if @realException.nil?
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+ # cdnlayerupload
3
+ #
4
+ # Copyright (c) 2009, James Nuckolls. All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ # * Neither "James Nuckolls" nor the names of any contributors may
15
+ # be used to endorse or promote products derived from this software without
16
+ # specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ # POSSIBILITY OF SUCH DAMAGE.
29
+ #
30
+ #= Description
31
+ # Retrieves the current Account's BillingItems using an objectMask and outputs a report of the
32
+ # current (not-canceled) items.
33
+ #= ToDo
34
+ #
35
+
36
+ require 'rubygems' rescue LoadError
37
+ require 'ftools'
38
+ require 'pp'
39
+ require 'softlayer'
40
+
41
+ AUTH_USER = ARGV[0]
42
+ AUTH_KEY = ARGV[4]
43
+ ACCT_ID = ARGV[1]
44
+ CDN_ACCT = ARGV[2]
45
+ INFILE = ARGV[3]
46
+
47
+ SLAPICLASSES = [ 'SoftLayer::Account', 'SoftLayer::Network::ContentDelivery::Account' ]
48
+ SoftLayer::declareClasses(:ruby => SLAPICLASSES)
49
+ account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
50
+ account.objectMask={'cdnAccountName' => nil}
51
+ cdnacct = nil
52
+
53
+ # Get the accout number by matching the name that was in ARGV[2]
54
+ account.getCdnAccounts.each do |c|
55
+ # pp c
56
+ cdnacct = SoftLayer::Network::ContentDelivery::Account.new(:initParam => c['id']) if c['cdnAccountName'] == CDN_ACCT
57
+ end
58
+
59
+ cdnacct.getPopNames
60
+
61
+ fname = File.basename(INFILE)
62
+ # base64 encode the file
63
+ b64 = [IO.read(INFILE)].pack("m")
64
+ # cdnacct.debug=STDOUT
65
+ ret = cdnacct.uploadStream(:source => { 'data' => b64, 'filename' => fname}, :target => "/media/http/test")
66
+ pp ret
67
+
68
+
@@ -46,6 +46,7 @@ SoftLayer::declareClasses(:ruby => SLAPICLASSES)
46
46
  range = 5
47
47
  offset = 0
48
48
  account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
49
+
49
50
  # account.debug=STDOUT
50
51
  bia = account.getAllBillingItems(:limit => [range,offset])
51
52
  pp bia
@@ -61,11 +62,13 @@ account.getAllBillingItems(:limit => [range,offset]) do |bi|
61
62
  offset = range + offset
62
63
  end
63
64
 
64
- range = 5
65
+ range = 1
65
66
  offset = 0
66
- # account.debug=STDOUT
67
- account.getInvoices(:limit => [range,offset]) do |bi|
67
+ account.getInvoices do |bi|
68
68
  pp bi
69
69
  puts "================== #{offset}"
70
70
  offset = offset + range
71
71
  end
72
+
73
+ exit 0
74
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jamesn-softlayer-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3.0
4
+ version: 0.7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Nuckolls
@@ -9,7 +9,7 @@ autorequire: softlayer
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-19 21:00:00 -07:00
12
+ date: 2009-04-27 22:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,10 +34,13 @@ extra_rdoc_files:
34
34
  - Changes
35
35
  files:
36
36
  - lib/softlayer.rb
37
+ - lib/softlayer/baseclass.rb
38
+ - lib/softlayer/util.rb
37
39
  - sample/nascapacity.rb
38
40
  - sample/billingreport.rb
39
41
  - sample/objectmask.rb
40
42
  - sample/resultlimit.rb
43
+ - sample/cdnlayerupload.rb
41
44
  - README
42
45
  - LICENSE
43
46
  - Changes