jamesn-softlayer-ruby 0.5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +26 -0
- data/README +61 -0
- data/lib/softlayer.rb +298 -0
- data/sample/billingreport.rb +94 -0
- data/sample/nascapacity.rb +59 -0
- data/sample/objectmask.rb +56 -0
- metadata +68 -0
data/LICENSE
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2009, James Nuckolls. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
* Redistributions of source code must retain the above copyright notice,
|
7
|
+
this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
9
|
+
this list of conditions and the following disclaimer in the documentation
|
10
|
+
and/or other materials provided with the distribution.
|
11
|
+
* Neither "James Nuckolls" nor the names of any contributors may
|
12
|
+
be used to endorse or promote products derived from this software without
|
13
|
+
specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
18
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
19
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
20
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
21
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
22
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
23
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
24
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
25
|
+
POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
|
data/README
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
This is a module and class factory for SoftLayer's customer portal API (http://sldn.softlayer.com/). See the rdoc documentation and the sample directory for usage details.
|
2
|
+
|
3
|
+
The factory creates classes as they are declared. As a group:
|
4
|
+
|
5
|
+
SLAPICLASSES = [ 'SoftLayer::Account' ]
|
6
|
+
SLAPISERVICES = [ 'SoftLayer_Billing_Item', 'SoftLayer_Network_Storage' ]
|
7
|
+
SoftLayer::declareClasses(:ruby => SLAPICLASSES, :soap => SLAPISERVICES)
|
8
|
+
|
9
|
+
Or one at a time:
|
10
|
+
|
11
|
+
SoftLayer::ClassFactory(:class => 'SoftLayer::Account')
|
12
|
+
|
13
|
+
Objects are then created and used like normal Ruby objects:
|
14
|
+
|
15
|
+
account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
|
16
|
+
puts account.getBalance
|
17
|
+
|
18
|
+
The object's associated Type is available like a hash:
|
19
|
+
|
20
|
+
puts account['email']
|
21
|
+
|
22
|
+
Object Masks:
|
23
|
+
|
24
|
+
account.objectMask = { 'allBillingItems' => nil }
|
25
|
+
pp account['allBillingItems]
|
26
|
+
|
27
|
+
|
28
|
+
API user and key is cached after first use (but can be overridden on a per object basis):
|
29
|
+
|
30
|
+
SLAPISERVICES = [ 'SoftLayer_Account', 'SoftLayer_Billing_Item', 'SoftLayer_Network_Storage' ]
|
31
|
+
SoftLayer::declareClasses(:soap => SLAPISERVICES)
|
32
|
+
|
33
|
+
account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
|
34
|
+
account.objectMask={ 'allBillingItems' => nil, 'nasNetworkStorage' => nil }
|
35
|
+
account['allBillingItems'].each do |bi|
|
36
|
+
billingItem = SoftLayer::Billing::Item.new(:initParam => bi['id'])
|
37
|
+
pp billingItem.getLocation['longName']
|
38
|
+
end
|
39
|
+
|
40
|
+
account['nasNetworkStorage'].each do |n|
|
41
|
+
nas = SoftLayer::Network::Storage(:user => OTHER_AUTH_USER, :key => OTHER_AUTH_KEY, :initParam => n['id'])
|
42
|
+
pp nas.capacityGb
|
43
|
+
end
|
44
|
+
|
45
|
+
ToDo:
|
46
|
+
|
47
|
+
Result Limits. Can be done now as a parameter to any method, but should be integrated such that this does the right thing:
|
48
|
+
|
49
|
+
account.getAllBillingItems(:limit => [X,Y]) do |o,bia|
|
50
|
+
( blah )
|
51
|
+
end
|
52
|
+
|
53
|
+
Such that is +o+ is the offset and +bia+ is an array containing X or fewer elements (or a single element if :limit[0] == 1);
|
54
|
+
blah executes on each batch until it's done.
|
55
|
+
|
56
|
+
Without a block, should return the 5 elements offset from Y:
|
57
|
+
|
58
|
+
bia = account.getAllBillingItems(:limit => [5,Y])
|
59
|
+
bia.size <= 5
|
60
|
+
|
61
|
+
|
data/lib/softlayer.rb
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# softlayer
|
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
|
+
#
|
32
|
+
#= ToDo
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'rubygems' rescue LoadError
|
36
|
+
gem 'soap4r'
|
37
|
+
require 'soap/header/simplehandler'
|
38
|
+
require 'soap/wsdlDriver'
|
39
|
+
|
40
|
+
|
41
|
+
module SoftLayer
|
42
|
+
|
43
|
+
# Declare SLAPI clases. Args take class names in two forms:
|
44
|
+
# +soap+:: Service names in SOAP format (example: SoftLayer_Account)
|
45
|
+
# +ruby+:: Class names in Ruby format (example: SoftLayer::Account)
|
46
|
+
# Creates the class, and retrieves and caches the endpoint WSDL.
|
47
|
+
def SoftLayer::declareClasses(args)
|
48
|
+
classes = args[:ruby]
|
49
|
+
services = args[:soap]
|
50
|
+
|
51
|
+
unless (services.nil? || services.empty?)
|
52
|
+
services.each do |s|
|
53
|
+
c = s.gsub(/_/,'::')
|
54
|
+
classes.push(c)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
classes.each do |cstr|
|
59
|
+
k = SoftLayer::ClassFactory(:class => cstr)
|
60
|
+
k.cacheWSDL
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Derive a Class from a SOAP::Mapping::Object
|
65
|
+
# +obj+:: The object to derive a class from.
|
66
|
+
# Returns a new object with +obj+ as the cached object. (obj['id'] == :initParam)
|
67
|
+
#
|
68
|
+
# XXX: We should use the SOAP mapping registry to avoid doing this, but what the hell.
|
69
|
+
# Also, there's no guartinee there's a class here to be created, so the assumption is
|
70
|
+
# that you know what you're doing when you use this (much like everything else).
|
71
|
+
def SoftLayer::deriveClass(args)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create a Ruby class to match an SLAPI WSDL endpoint.
|
75
|
+
# Args:
|
76
|
+
# +class+:: The name of the class to create in Ruby format.
|
77
|
+
# +parent+:: The parent namespace to add the class to (this should be somewere in SoftLayer; optional).
|
78
|
+
# This recursively walks up +class+ creating them as needed, so SoftLayer::Dns::Domain will create
|
79
|
+
# classes for Dns and Domain (even though the Dns class will never be used).
|
80
|
+
def SoftLayer::ClassFactory(args)
|
81
|
+
cname = args[:class]
|
82
|
+
parent = args[:parent] unless args[:parent].nil?
|
83
|
+
|
84
|
+
cary = cname.split('::')
|
85
|
+
parent = const_get(cary.shift) if parent.nil? # This should always be SoftLayer, but maybe not...
|
86
|
+
cur = cary.shift
|
87
|
+
newclass = nil
|
88
|
+
unless parent.const_defined?(cur)
|
89
|
+
newclass = SoftLayer::makeSLAPIKlass(:class => cur, :parent => parent)
|
90
|
+
else
|
91
|
+
newclass = parent.const_get(cur)
|
92
|
+
end
|
93
|
+
return newclass if cary.empty?
|
94
|
+
|
95
|
+
left = cary.join('::')
|
96
|
+
k = SoftLayer::ClassFactory(:class => left, :parent => newclass)
|
97
|
+
return k
|
98
|
+
end
|
99
|
+
|
100
|
+
# This really creates the class.
|
101
|
+
# +class+:: The name of the class to create in Ruby format.
|
102
|
+
# +parent+:: The parent namespace to add the class to (this should be somewhere in SoftLayer, not optional).
|
103
|
+
def SoftLayer::makeSLAPIKlass(args)
|
104
|
+
cname = args[:class]
|
105
|
+
parent = args[:parent]
|
106
|
+
realKlassName = "#{cname}"
|
107
|
+
klass = Class.new SoftLayer::BaseClass do
|
108
|
+
|
109
|
+
end
|
110
|
+
parent.const_set realKlassName, klass
|
111
|
+
return klass
|
112
|
+
end
|
113
|
+
|
114
|
+
# A class to old Paramaters.
|
115
|
+
class ParamHeader < SOAP::Header::SimpleHandler
|
116
|
+
def initialize(tag, out)
|
117
|
+
@out = out
|
118
|
+
super(XSD::QName.new(nil, tag))
|
119
|
+
end
|
120
|
+
|
121
|
+
def on_simple_outbound
|
122
|
+
@out
|
123
|
+
end
|
124
|
+
|
125
|
+
def [](k)
|
126
|
+
return @out[k]
|
127
|
+
end
|
128
|
+
|
129
|
+
def []=(k,v)
|
130
|
+
@out[k]=v
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# A class to hold the object mask.
|
135
|
+
class ObjectMaskHeader < SOAP::Header::SimpleHandler
|
136
|
+
def initialize(tag, out)
|
137
|
+
@out = out
|
138
|
+
super(XSD::QName.new(nil, tag))
|
139
|
+
end
|
140
|
+
|
141
|
+
def on_simple_outbound
|
142
|
+
{ 'mask' => @out }
|
143
|
+
end
|
144
|
+
|
145
|
+
def [](k)
|
146
|
+
@out[k]
|
147
|
+
end
|
148
|
+
|
149
|
+
def []=(k,v)
|
150
|
+
@out[k]=v
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
# The Base class for our generated class.
|
156
|
+
class BaseClass
|
157
|
+
|
158
|
+
WSDLBASE='http://api.service.softlayer.com/soap/v3'
|
159
|
+
WSDLPARAM='?wsdl'
|
160
|
+
|
161
|
+
@@wsdl = { }
|
162
|
+
@@apiUser = nil
|
163
|
+
@@apiKey = nil
|
164
|
+
|
165
|
+
# The initializer.
|
166
|
+
# Arguments:
|
167
|
+
# +user+:: The API User
|
168
|
+
# +key+:: The API Key
|
169
|
+
# +initParams+:: This object's initParam (just the key)
|
170
|
+
# +debug+:: Enable debug after driver creation. (IO handler)
|
171
|
+
#
|
172
|
+
# +user+ and +key+ are optional. The first time they're presented
|
173
|
+
# they're saved to class variables and reused later as necessary. Supplying
|
174
|
+
# +user+ and +key+ later does not overwrite the class variables. +initParams+ is
|
175
|
+
# required where the api requires it.
|
176
|
+
def initialize(args)
|
177
|
+
@apiUser = args[:user] unless args[:user].nil?
|
178
|
+
@apiKey = args[:key] unless args[:key].nil?
|
179
|
+
@initParam = args[:initParam]
|
180
|
+
|
181
|
+
@@apiUser = args[:user] unless (args[:user].nil? || !@@apiUser.nil?)
|
182
|
+
@@apiKey = args[:key] unless (args[:key].nil? || !@@apiKey.nil?)
|
183
|
+
@apiUser = @@apiUser unless (@@apiUser.nil? || !@apiUser.nil?)
|
184
|
+
@apiKey = @@apiKey unless (@@apiKey.nil? || !@apiKey.nil?)
|
185
|
+
|
186
|
+
self.class.cacheWSDL
|
187
|
+
@slapi = @@wsdl[self.soapClass].create_rpc_driver
|
188
|
+
self.debug=args[:debug] unless args[:debug].nil?
|
189
|
+
end
|
190
|
+
|
191
|
+
# Return this's object's matching SLAPI SOAP Class.
|
192
|
+
def soapClass
|
193
|
+
return self.class.to_s.gsub(/::/, '_')
|
194
|
+
end
|
195
|
+
|
196
|
+
# This returns key values from this Service's associated Type (retrieved using #getObject).
|
197
|
+
def [](key)
|
198
|
+
@slapiObject = self.getObject if @slapiobject.nil?
|
199
|
+
return @slapiObject[key.to_s]
|
200
|
+
end
|
201
|
+
|
202
|
+
def setObject(obj)
|
203
|
+
@slapiObject = obj
|
204
|
+
end
|
205
|
+
|
206
|
+
# Set the object mask which ia passed as a hash of optional hashes (otherwise the hash elements should have a nil value).
|
207
|
+
# Using the example from the wiki:
|
208
|
+
# <SoftLayer_AccountObjectMask xsi:type="v3:SoftLayer_AccountObjectMask">
|
209
|
+
# <mask xsi:type="slt:SoftLayer_Account" xmlns:slt="http://api.service.softlayer.com/soap/v3/SLTypes/">
|
210
|
+
# <domains>
|
211
|
+
# <resourceRecords />
|
212
|
+
# </domains>
|
213
|
+
# <openTickets>
|
214
|
+
# <assignedUser />
|
215
|
+
# <attachedHardware />
|
216
|
+
# <updates />
|
217
|
+
# </openTickets>
|
218
|
+
# <userCount />
|
219
|
+
# </mask>
|
220
|
+
# </SoftLayer_AccountObjectMask>
|
221
|
+
#
|
222
|
+
# { 'domains' => { 'resourceRecords' => nil }, 'openTicket' => { 'assignedUser' => nil, 'attachedHardware' => nil, 'updates' => nil },
|
223
|
+
# userCount => nil }
|
224
|
+
# Changing this resets the cached object used by #[]
|
225
|
+
def objectMask=(mask)
|
226
|
+
if mask.class == ObjectMaskHeader
|
227
|
+
@objectMask = mask
|
228
|
+
else
|
229
|
+
@objectMask = ObjectMaskHeader.new("#{self.soapClass}ObjectMask", mask)
|
230
|
+
end
|
231
|
+
@slapiObject = nil
|
232
|
+
end
|
233
|
+
|
234
|
+
def objectMask
|
235
|
+
return @objectMask
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
# Make a direct api call. Paramaters are a hash where the key is passed to ParamHeader as the tag, and the value
|
240
|
+
# is passed as the tag content, unless it's a magic paramater.
|
241
|
+
# Magic Paramaters:
|
242
|
+
# +initParam+:: Initialization paramater for this call (just the key). Otherwise @initParam is used.
|
243
|
+
#
|
244
|
+
# Aliased to #method_missing.
|
245
|
+
def slapiCall(method, args = { })
|
246
|
+
initParam = args[:initParam] unless args[:initParam].nil?
|
247
|
+
args.delete(:initParam) unless args[:initParam].nil?
|
248
|
+
initParam = @initParam if initParam.nil?
|
249
|
+
|
250
|
+
@slapi.headerhandler << ParamHeader.new('authenticate', {'username' => @apiUser, 'apiKey' => @apiKey})
|
251
|
+
unless args.nil?
|
252
|
+
args.each do |k,v|
|
253
|
+
@slapi.headerhandler << ParamHeader.new(k.to_s,v)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
@slapi.headerhandler << ParamHeader.new("#{self.soapClass}InitParameters", { 'id' => initParam})
|
257
|
+
@slapi.headerhandler << @objectMask unless @objectMask.nil?
|
258
|
+
return @slapi.call(method.to_s)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Alias the above call method to #method_missing.
|
262
|
+
alias_method :method_missing, :slapiCall
|
263
|
+
|
264
|
+
# Enable (or disable) debug. (paramater is the IO handler to write to)
|
265
|
+
def debug=(dev)
|
266
|
+
@slapi.wiredump_dev=(dev)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Get the WSDL, parse it, and save it to a Class level hash.
|
270
|
+
# Returns false of we couldn't parse the WSDL.
|
271
|
+
def self.cacheWSDL
|
272
|
+
return unless @@wsdl[self.soapClass].nil?
|
273
|
+
|
274
|
+
begin
|
275
|
+
@@wsdl[self.soapClass] = SOAP::WSDLDriverFactory.new(self.wsdlUrl)
|
276
|
+
return true
|
277
|
+
rescue => e
|
278
|
+
return false
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
# Return this Class's WSDL.
|
283
|
+
def self.wsdl
|
284
|
+
return @@wsdl[self.soapClass]
|
285
|
+
end
|
286
|
+
|
287
|
+
# Return this Class's WSDL URL.
|
288
|
+
def self.wsdlUrl
|
289
|
+
return URI.parse("#{WSDLBASE}/#{self.soapClass}#{WSDLPARAM}")
|
290
|
+
end
|
291
|
+
|
292
|
+
# Returns this Class's SOAP Class.
|
293
|
+
def self.soapClass
|
294
|
+
self.name.to_s.gsub(/::/, '_')
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# billingreport
|
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 'pp'
|
38
|
+
require 'softlayer'
|
39
|
+
|
40
|
+
AUTH_USER = ARGV[0]
|
41
|
+
AUTH_KEY = ARGV[2]
|
42
|
+
ACCT_ID = ARGV[1]
|
43
|
+
|
44
|
+
SLAPICLASSES = [ 'SoftLayer::Account' ]
|
45
|
+
SoftLayer::declareClasses(:ruby => SLAPICLASSES)
|
46
|
+
|
47
|
+
account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
|
48
|
+
account.objectMask={ 'allBillingItems' => nil }
|
49
|
+
|
50
|
+
rtotal = rtax = 0
|
51
|
+
ottotal = ottax = 0
|
52
|
+
lftotal = lftax = 0
|
53
|
+
sftotal = sftax = 0
|
54
|
+
account['allBillingItems'].each do |b|
|
55
|
+
if b['cancellationDate'].nil?
|
56
|
+
rtotal = rtotal + rf = b['recurringFee'].to_f
|
57
|
+
ottotal = ottotal + ot = b['oneTimeFee'].to_f
|
58
|
+
lftotal = lftotal + lf = b['laborFee'].to_f
|
59
|
+
sftotal = sftotal + sf = b['setupFee'].to_f
|
60
|
+
rt = rf * rtr = b['recurringFeeTaxRate'].to_f
|
61
|
+
ott = ot * otr = b['oneTimeFeeTaxRate'].to_f
|
62
|
+
lft = lf * lfr = b['laborFeeTaxRate'].to_f
|
63
|
+
sft = sf * sfr = b['setupFeeTaxRate'].to_f
|
64
|
+
rtax = rtax + rt
|
65
|
+
ottax = ottax + ott
|
66
|
+
lftax = lftax + lft
|
67
|
+
sftax = sftax + sft
|
68
|
+
|
69
|
+
puts "Item Id #{b['id']}"
|
70
|
+
puts "Description #{b['description']}"
|
71
|
+
puts "Recurring Fee #{"$%.2f" % rf}"
|
72
|
+
puts "Recurring Tax #{"$%.2f" % rt} (#{rtr * 100}%)"
|
73
|
+
puts "One Time Fee #{"$%.2f" % ot}" unless ot == 0
|
74
|
+
puts "One Time Tax #{"$%.2f" % ott} (#{otr * 100}%)" unless ot == 0
|
75
|
+
puts "Labor Fee #{"$%.2f" % lf}" unless lf == 0
|
76
|
+
puts "Labor Fee Tax #{"$%.2f" % lft} (#{lfr * 100}%)" unless lf == 0
|
77
|
+
puts "Setup Fee #{"$%.2f" % sf}" unless sf == 0
|
78
|
+
puts "Setup Fee Tax #{"$%.2f" % sft} (#{sfr * 100}%)" unless sf == 0
|
79
|
+
puts "Recurring Months #{b['recurringMonths']}"
|
80
|
+
puts "Last Bill Date #{b['lastBillDate'].strftime("%b %d, %Y %X")}"
|
81
|
+
puts "Next Bill Date #{b['nextBillDate'].strftime("%b %d, %Y %X")}"
|
82
|
+
puts "Modify Date #{b['modifyDate'].strftime("%b %d, %Y %X")}"
|
83
|
+
puts "Create Date #{b['createDate'].strftime("%b %d, %Y %X")}"
|
84
|
+
puts "Associated Billing Item Id #{b['associatedBillingItemId']}" unless b['associatedBillingItemId'].nil?
|
85
|
+
puts "=================================="
|
86
|
+
# pp b
|
87
|
+
end
|
88
|
+
end
|
89
|
+
puts ""
|
90
|
+
puts "Totals:"
|
91
|
+
puts "\tRecurring: #{"$%.2f" % rtotal} Tax: #{"$%.2f" % rtax} == #{"$%.2f" % (rtotal + rtax)}"
|
92
|
+
puts "\tOne Time : #{"$%.2f" % ottotal} Tax: #{"$%.2f" % ottax} == #{"$%.2f" % (ottotal + ottax)}" unless ottotal == 0
|
93
|
+
puts "\tLabor : #{"$%.2f" % lftotal} Tax: #{"$%.2f" % lftax} == #{"$%.2f" % (lftotal + lftax)}" unless lftotal == 0
|
94
|
+
puts "\tSetup : #{"$%.2f" % sftotal} Tax: #{"$%.2f" % sftax} == #{"$%.2f" % (sftotal + sftax)}" unless sftotal == 0
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# nascapacity
|
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
|
+
# Prints a list of all StorageLater objects and their capacity.
|
32
|
+
#= ToDo
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'rubygems' rescue LoadError
|
36
|
+
require 'pp'
|
37
|
+
require 'softlayer'
|
38
|
+
|
39
|
+
require 'soap/header/simplehandler'
|
40
|
+
require 'soap/wsdlDriver'
|
41
|
+
|
42
|
+
AUTH_USER = ARGV[0]
|
43
|
+
AUTH_KEY = ARGV[2]
|
44
|
+
ACCT_ID = ARGV[1]
|
45
|
+
|
46
|
+
SLAPICLASSES = [ 'SoftLayer::Account', 'SoftLayer::Network::Storage' ]
|
47
|
+
SoftLayer::declareClasses(:ruby => SLAPICLASSES)
|
48
|
+
|
49
|
+
account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
|
50
|
+
account.objectMask={ 'networkStorage' => { 'serviceResource' => nil } }
|
51
|
+
|
52
|
+
nas = account['networkStorage'].each do |nas|
|
53
|
+
# pp nas
|
54
|
+
type = nas['nasType']
|
55
|
+
puts "//#{nas['serviceResource']['backendIpAddress']}/#{nas['username']} -- #{nas['capacityGb']}G" if (type == 'NAS' || type == 'LOCKBOX')
|
56
|
+
puts "#{nas['username']}@#{nas['serviceResource']['backendIpAddress']} -- #{nas['capacityGb']}G" if (type == 'EVAULT' || type == 'ISCSI')
|
57
|
+
puts "CloudLayer: #{nas['username']} -- #{nas['capacityGb']}G" if (type == 'HUB')
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# objectmask
|
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
|
+
# Fun with Object Masks.
|
32
|
+
#= ToDo
|
33
|
+
#
|
34
|
+
|
35
|
+
require 'rubygems' rescue LoadError
|
36
|
+
require 'pp'
|
37
|
+
require 'softlayer'
|
38
|
+
|
39
|
+
AUTH_USER = ARGV[0]
|
40
|
+
AUTH_KEY = ARGV[2]
|
41
|
+
ACCT_ID = ARGV[1]
|
42
|
+
|
43
|
+
SLAPICLASSES = [ 'SoftLayer::Account' ]
|
44
|
+
SoftLayer::declareClasses(:ruby => SLAPICLASSES)
|
45
|
+
|
46
|
+
puts "Before: "
|
47
|
+
account = SoftLayer::Account.new(:user => AUTH_USER, :key => AUTH_KEY, :initParam => ACCT_ID)
|
48
|
+
account.objectMask={ 'allRecurringTopLevelBillingItems' => nil }
|
49
|
+
pp account['allRecurringTopLevelBillingItems']
|
50
|
+
puts "=================================="
|
51
|
+
|
52
|
+
puts ""
|
53
|
+
puts "After: "
|
54
|
+
account.objectMask['allRecurringTopLevelBillingItems'] = { 'associatedChildren' => nil }
|
55
|
+
# account.debug=STDOUT
|
56
|
+
pp account['allRecurringTopLevelBillingItems']
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jamesn-softlayer-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Nuckolls
|
8
|
+
autorequire: softlayer
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-11 22:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: soap4r
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.5.0
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: jamesn@what.net
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
- LICENSE
|
34
|
+
files:
|
35
|
+
- lib/softlayer.rb
|
36
|
+
- sample/nascapacity.rb
|
37
|
+
- sample/billingreport.rb
|
38
|
+
- sample/objectmask.rb
|
39
|
+
- README
|
40
|
+
- LICENSE
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/jamesn/softlayer-ruby
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.2.0
|
64
|
+
signing_key:
|
65
|
+
specification_version: 2
|
66
|
+
summary: A module and class factory for SoftLayer's customer portal API
|
67
|
+
test_files: []
|
68
|
+
|