UCSAPI 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,14 @@
1
+ === 0.0.1 2010-10-01
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
5
+
6
+ === 0.0.2 2010-10-01
7
+
8
+ * 2 gem push/yank fun and games
9
+ * no code changes
10
+
11
+ === 0.0.3 2010-10-01
12
+
13
+ * Added RDOC
14
+ * no code changes
data/Manifest.txt ADDED
@@ -0,0 +1,10 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ Rakefile
5
+ lib/UCSAPI.rb
6
+ script/console
7
+ script/destroy
8
+ script/generate
9
+ test/test_UCSAPI.rb
10
+ test/test_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ For more information on UCSAPI, see http://ciscoucs.rubyforge.org
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/UCSAPI'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.spec 'UCSAPI' do
14
+ self.description = 'A simple ruby interface to the Cisco UCS XMLAPI'
15
+ self.url = 'http://ciscoucs.rubyforge.org'
16
+ self.developer 'Steve Chambers', 'stevie_chambers @nospam@ viewyonder.com'
17
+ self.post_install_message = 'PostInstall.txt'
18
+ self.rubyforge_name = 'ciscoucs'
19
+ self.extra_deps << ['rubygems-update']
20
+ self.extra_deps << ['rest-client']
21
+ self.readme_file = 'README.rdoc'
22
+ self.rubyforge_name = 'ciscoucs'
23
+ end
24
+
25
+ require 'newgem/tasks'
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # remove_task :default
30
+ # task :default => [:spec, :features]
data/lib/UCSAPI.rb ADDED
@@ -0,0 +1,541 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ #= UCSAPI
5
+ #
6
+ #== What on earth do I do with this?
7
+ #The main UCSAPI module that you must _require_ into your Ruby script.
8
+ #If you _include_ the module in your classes, you can drop the UCSAPI:: prefix when using it.
9
+ #Here's a sample invocation that you could put at the top of your script
10
+ # require 'UCSAPI'
11
+ # include UCSAPI
12
+ # myucs = UCSM.new( :url => 'http://myucs', :inName => 'viewyonder', :inPassword => 'secret')
13
+ #
14
+ #== Unofficial, Unsupported simple interface to the UCSAPI
15
+ #
16
+ #This is a continual work in progress by stevie_chambers @nospam@ viewyonder.com
17
+ #to produce a simple interface to the powerful UCS XMLAPI.
18
+ #
19
+ #Things you can do with this UCSAPI code:
20
+ #* Get "raw" access to the XMLAPI methods like configResolveDn
21
+ #* Get friendly decorators to the raw methods, like "chassis" returning all chassis
22
+ #
23
+ #Future honorouable intentions:
24
+ #* Add more methods to get more objects, set configs, listen for events
25
+ #* Allow simple get/export of data in both raw and friendly formats (think interface stats and RRDtoo)
26
+ #* Add more backends that UCS, such as Nexus1000v and VMware.
27
+ #* Put a Rails front end on it so we have a GUI
28
+ #
29
+ #Author and Copyright (c) 2010 Steve Chambers
30
+ #http://viewyonder.com
31
+ #
32
+ #== License
33
+ #
34
+ #This work is licensed under the Creative Commons Attribution-ShareAlike license
35
+ #See it at: http://creativecommons.org/licenses/by-sa/3.0/
36
+ #
37
+ #You are free to share and remix as long as you
38
+ #* *Attribute* Steve Chambers and Cisco as the original authors
39
+ #* *Share* *Alike* by distributing derivative works under the same license terms.
40
+ #* *Notice* should be shown in reuse/distribution by linking to the license web page above
41
+ #
42
+ #These conditions can be waived if you get permission from Steve Chambers and Cisco.
43
+ #
44
+
45
+ module UCSAPI
46
+ require 'rubygems'
47
+ require 'rexml/document'
48
+ require 'rest_client'
49
+ require 'logger'
50
+ require 'ostruct'
51
+ VERSION = '0.0.6'
52
+
53
+ #At the moment this is one big class with lots of methods. Refactoring due later :)
54
+ class UCSM
55
+
56
+ #Allow public read-only access to the user OpenStruct which contains session details
57
+ attr_reader :user
58
+
59
+ #Set up the _logger_ and initialize the _user_ ostruct based on paramters in opts[]
60
+ #Example call:
61
+ # UCSM.new( :url => 'http://ucs/nuova', :inName => 'jbloggs', :inPassword => 'secret', :logging => 'info')
62
+ def initialize(opts={})
63
+ # FIXME: NEED TO ADD OPTION CHECKING INC SECURITY
64
+ @log = Logger.new(STDOUT)
65
+ @log.level = case opts[:logging]
66
+ when 'info'
67
+ Logger::INFO
68
+ else
69
+ Logger::ERROR
70
+ end
71
+ @log.progname = "CiscoUCS:UCSM"
72
+ @user = OpenStruct.new
73
+ @user.url = opts[:url]
74
+ @user.inName = opts[:inName] || opts[:name]
75
+ @user.inPassword = opts[:inPassword] || opts[:password]
76
+ @user.session = nil
77
+ @log.info("initialized")
78
+ end
79
+
80
+ #Build an send the <aaaLogin /> method to UCS
81
+ #Returns *user.session* which is an OpenStruct
82
+ #* Build the XMLAPI call from the opts parameters
83
+ #* Send the XMLAPI object to dispatch, get an XML object back
84
+ #* Create a new OpenStruct from the response and store in @user
85
+ def login
86
+ @log.info("login @url=" + @user.url + ", @name=" + @user.inName + ", @password=" + @user.inPassword)
87
+
88
+ request = REXML::Document.new('<aaaLogin />')
89
+ request.root.add_attribute("inName",@user.inName)
90
+ request.root.add_attribute("inPassword",@user.inPassword)
91
+
92
+ response = dispatch(request)
93
+
94
+ attrs = Hash.new
95
+ response.attributes.each { | key, value | attrs[key]=value }
96
+ @user.session = OpenStruct.new(attrs)
97
+
98
+ if @user.session.response = "yes" and @user.session.outStatus = "success"
99
+ @log.info("login SUCCESS response = " + @user.session.to_s)
100
+ @user.session
101
+ else
102
+ @log.info("login FAIL response = " + @user.session.to_s)
103
+ @user.session
104
+ end
105
+ end
106
+
107
+ #Reuse an existing session, identified by the _@cookie_
108
+ #Returns *user.session* which is an OpenStruct
109
+ #* Build the XMLAPI call from the opts parameters
110
+ #* Send the XMLAPI object to dispatch, get an XML object back
111
+ #* Create a new OpenStruct from the response and store in @user
112
+ def refresh
113
+ @log.info("@url=" + @user.url + ", @cookie=" + @user.session.outCookie)
114
+
115
+ request = REXML::Document.new('<aaaRefresh />')
116
+ request.root.add_attribute("inCookie",@user.session.outCookie)
117
+
118
+ response = dispatch(request)
119
+
120
+ attrs = Hash.new
121
+ response.attributes.each { | key, value | attrs[key]=value }
122
+ @user.session = OpenStruct.new(attrs)
123
+
124
+ if @user.session.response = "yes" and @user.session.outStatus = "success"
125
+ @log.info("refresh SUCCESS response = " + @user.session.to_s)
126
+ @user.session
127
+ else
128
+ @log.info("refresh FAIL response = " + @user.session.to_s)
129
+ @user.session
130
+ end
131
+ end
132
+
133
+ #Logout / kill the UCS session with the _@cookie_
134
+ #Returns *user.session* which is an OpenStruct
135
+ #* Build the XMLAPI call from the opts parameters
136
+ #* Send the XMLAPI object to dispatch, get an XML object back
137
+ #* Create a new OpenStruct from the response and store in @user
138
+ def logout
139
+ @log.info("logout @url=" + @user.url + ", @cookie=" + @user.session.outCookie)
140
+
141
+ request = REXML::Document.new('<aaaLogout />')
142
+ request.root.add_attribute("inCookie",@user.session.outCookie)
143
+
144
+ response = dispatch(request)
145
+
146
+ attrs = Hash.new
147
+ response.attributes.each { | key, value | attrs[key]=value }
148
+ @user.session = OpenStruct.new(attrs)
149
+
150
+ if @user.session.response = "yes" and @user.session.outStatus = "success"
151
+ @log.info("logout SUCCESS response = " + @user.session.to_s)
152
+ @user.session
153
+ else
154
+ @log.info("logout FAIL response = " + @user.session.to_s)
155
+ @user.session
156
+ end
157
+ end
158
+
159
+ #Get an xml object containing API code, turn into text and HTTP POST it to _@user.url_
160
+ #Returns the root REXML::Element of the UCS XMLAPI response document
161
+ #* The caller will send a REXML object with the XMLAPI command in it
162
+ #* Send the XMLAPI call to UCS and catch any exceptions (log and quit if we do)
163
+ def dispatch(xml)
164
+ @log.info("UCSAPI::Session.dispatch sending " + xml.to_s)
165
+
166
+ # The RestClient.post method expects text, not a REXML object
167
+ post = xml.to_s
168
+
169
+ # FIXME: RestClient timeout is broken and default wait is 75s #dontaskmewhy
170
+ begin
171
+ response = RestClient.post @user.url, post, :content_type => 'text/xml'
172
+ rescue => e
173
+ @log.error "dispatch EXCEPTION " + e.class.to_s + " = " + e.to_s
174
+ exit
175
+ end
176
+
177
+ @log.info("dispatch received " + response.to_s)
178
+ REXML::Document.new(response).root
179
+ end
180
+
181
+ #Build an XMLAPI call to find an object via distinguished name
182
+ #Returns an *Array* of found objects
183
+ #* Build the XMLAPI call from the opts parameters
184
+ #* Send the XMLAPI object to dispatch, get an XML object back
185
+ #If the response XML has objects under <outConfig> then
186
+ #* get each element and
187
+ #* build an OpenStruct with attributes from the XML attributes
188
+ #* add each OpenStruct to an array, which is returned to the method caller outConfig = response.root.elements[1]
189
+ def configResolveDn(opts={})
190
+ @log.info("configResolveDn started")
191
+
192
+ inHierarchical = opts[:inHierarchical] || "false"
193
+ if opts[:dn] then
194
+ request = REXML::Document.new('<configResolveDn />')
195
+ request.root.add_attribute("inHierarchical",inHierarchical)
196
+ request.root.add_attribute("dn",opts[:dn])
197
+
198
+ response = dispatch(request)
199
+
200
+ outConfig = response.root.elements[1]
201
+ if outConfig.has_elements? then
202
+ found = Array.new
203
+ outConfig.elements.each do |element|
204
+ attrs = Hash.new
205
+ attrs["classId"] = element.name
206
+ element.attributes.each { | key, value | attrs[key]=value }
207
+ found << OpenStruct.new(attrs)
208
+ end
209
+
210
+ @log.info "configResolveDn returning " + found.size.to_s + " objects"
211
+ else
212
+ @log.error "configResolveDn ERROR No items found for dn = " + opts[:dn]
213
+ end
214
+ else
215
+ @log.error "configResolveDn ERROR Please supply a :dn option like configResolveDn( :dn => 'sys/chassis-1' )" unless opts[:dn]
216
+ end
217
+
218
+ @log.info("configResolveDn ended")
219
+ found
220
+ end
221
+
222
+ #Build an XMLAPI call to find an object(s) via the class name
223
+ #Returns an *Array* of found objects
224
+ #* Build the XMLAPI call from the opts parameters
225
+ #* Send the XMLAPI object to dispatch, get an XML object back
226
+ #If the response XML has objects under <outConfig> then
227
+ #* get each element and
228
+ #* build an OpenStruct with attributes from the XML attributes
229
+ #* add each OpenStruct to an array, which is returned to the method caller
230
+ def configResolveClass(opts={})
231
+ @log.info("configResolveClass started")
232
+
233
+ inHierarchical = opts[:inHierarchical] || "false"
234
+ if opts[:classId] then
235
+ request = REXML::Document.new('<configResolveClass />')
236
+ request.root.add_attribute("inHierarchical",inHierarchical)
237
+ request.root.add_attribute("classId",opts[:classId])
238
+
239
+ response = dispatch(request)
240
+
241
+ outConfig = response.root.elements[1]
242
+ if outConfig.has_elements? then
243
+ found = Array.new
244
+ outConfig.elements.each do |element|
245
+ attrs = Hash.new
246
+ attrs["classId"] = element.name
247
+ element.attributes.each { | key, value | attrs[key]=value }
248
+ found << OpenStruct.new(attrs)
249
+ end
250
+
251
+ @log.info "configResolveClass returning " + found.size.to_s + " objects"
252
+ else
253
+ @log.error "configResolveClass ERROR No items found for classId = " + opts[:classId]
254
+ end
255
+ else
256
+ @log.error "configResolveClass ERROR Please supply a :classId option like configResolveClass( :classId => 'equipmentChassis' )" unless opts[:classId]
257
+ end
258
+
259
+ @log.info("configResolveClass ended")
260
+ found
261
+ end
262
+
263
+ #Build an XMLAPI call to find objects of a specified class under a specified distinguished name
264
+ #Returns an *Array* of found objects
265
+ #* Build the XMLAPI call from the opts parameters
266
+ #* Send the XMLAPI object to dispatch, get an XML object back
267
+ #If the response XML has objects under <outConfig> then
268
+ #* get each element and
269
+ #* build an OpenStruct with attributes from the XML attributes
270
+ #* add each OpenStruct to an array, which is returned to the method caller
271
+ def configResolveChildren(opts={})
272
+ @log.info("configResolveChildren started")
273
+
274
+ inHierarchical = opts[:inHierarchical] || "false"
275
+ request = REXML::Document.new('<configResolveChildren />')
276
+ request.root.add_attribute("inHierarchical",inHierarchical)
277
+ request.root.add_attribute("classId",opts[:classId])
278
+ request.root.add_attribute("inDn",opts[:inDn])
279
+
280
+ response = dispatch(request)
281
+
282
+ outConfig = response.root.elements[1]
283
+ if outConfig.has_elements? then
284
+ found = Array.new
285
+ outConfig.elements.each do |element|
286
+ attrs = Hash.new
287
+ attrs["classId"] = element.name
288
+ element.attributes.each { | key, value | attrs[key]=value }
289
+ found << OpenStruct.new(attrs)
290
+ end
291
+ @log.info "configResolveChildren returning " + found.size.to_s + " objects"
292
+ else
293
+ @log.error "configResolveChildren ERROR No items found for classId = " + opts[:classId]
294
+ end
295
+
296
+ @log.info("configResolveChildren ended")
297
+ found
298
+ end
299
+
300
+ #Build an XMLAPI call to find distinguished names in a specified class
301
+ #Returns an *Array* of found objects
302
+ #* Build the XMLAPI call from the opts parameters
303
+ #* Send the XMLAPI object to dispatch, get an XML object back
304
+ #If the response XML has objects under <outConfig> then
305
+ #* get each element and
306
+ #* build an OpenStruct with attributes from the XML attributes
307
+ #* add each OpenStruct to an array, which is returned to the method caller
308
+ def configScope(opts={})
309
+ @log.info("configScope started")
310
+
311
+ inHierarchical = opts[:inHierarchical] || "false"
312
+ inRecursive = opts[:inRecursive] || "false"
313
+ request = REXML::Document.new('<configScope />')
314
+ request.root.add_attribute("inHierarchical",inHierarchical)
315
+ request.root.add_attribute("inClass",opts[:inClass])
316
+ request.root.add_attribute("dn",opts[:dn])
317
+
318
+ response = dispatch(request)
319
+
320
+ outConfig = response.root.elements[1]
321
+ if outConfig.has_elements? then
322
+ found = Array.new
323
+ outConfig.elements.each do |element|
324
+ attrs = Hash.new
325
+ attrs["classId"] = element.name
326
+ element.attributes.each { | key, value | attrs[key]=value }
327
+ found << OpenStruct.new(attrs)
328
+ end
329
+ @log.info "configScope returning " + found.size.to_s + " objects"
330
+ else
331
+ @log.error "configScope ERROR No items found for classId = " + opts[:classId]
332
+ end
333
+
334
+ @log.info("configScope ended")
335
+ found
336
+ end
337
+
338
+ #Adapter pattern method to make finding fabric objects easier
339
+ #Returns an *Array* of found objects
340
+ #Logic is simple:
341
+ #* If you give us a dn, we get that and we're done
342
+ #* If you provide a text ID, we build a dn and get that
343
+ #* If you provide nothing, we get both fabrics
344
+ def fabric(opts={})
345
+ @log.info("fabric started")
346
+
347
+ found = Array.new
348
+ classId = 'networkElement'
349
+
350
+ if opts[:dn]
351
+ found = configResolveDn( :dn => opts[:dn] )
352
+ elsif opts[:id] then
353
+ dn = 'sys/switch-' + opts[:id]
354
+ @log.info("fabric find by dn = " + dn)
355
+ found = configResolveDn( :dn => dn)
356
+ else
357
+ @log.info("fabric find by class = " + classId)
358
+ found = configResolveClass( :classId => classId)
359
+ end
360
+
361
+ @log.info("fabric ended")
362
+ found
363
+ end
364
+
365
+ #Adapter pattern method to make finding chassis objects easier
366
+ #Returns an *Array* of found objects
367
+ #Logic is simple:
368
+ #* If you give us a dn, we get that and we're done
369
+ #* If you provide a numeric/text ID, we build a dn and get that
370
+ #* If you provide nothing, we get all chassis
371
+ def chassis(opts={})
372
+ @log.info("chassis started")
373
+
374
+ classId = 'equipmentChassis'
375
+ found = Array.new
376
+
377
+ if opts[:dn]
378
+ found = configResolveDn( :dn => opts[:dn] )
379
+ elsif opts[:id] then
380
+ dn = 'sys/chassis-' + opts[:id].to_s
381
+ found = configResolveDn( :dn => dn)
382
+ else
383
+ found = configResolveClass( :classId => classId)
384
+ end
385
+
386
+ @log.info("chassis ended")
387
+ found
388
+ end
389
+
390
+ #Adapter pattern method to make finding blades easier
391
+ #Returns an *Array* of found objects
392
+ #Logic is simple here:
393
+ #* You can just provide a dn, we just get that and we're done
394
+ #* If you provide only a :chassis, we get all blades in that chassis
395
+ #* If you provide a :chassis and a :blade it's like a full dn
396
+ #* If you provide nothing, we get all blades
397
+ def blade(opts={})
398
+ @log.info("blade started")
399
+
400
+ classId = 'computeBlade'
401
+ found = Array.new
402
+
403
+ if opts[:dn]
404
+ found = configResolveDn( :dn => opts[:dn] )
405
+ elsif opts[:chassis] then
406
+ chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
407
+ if opts[:blade] then
408
+ dn = chassis_dn + '/blade-' + opts[:blade].to_s
409
+ found = configResolveDn( :dn => dn)
410
+ else
411
+ configResolveChildren( :classId => classId, :inDn => chassis_dn )
412
+ end
413
+ else
414
+ found = configResolveClass( :classId => classId)
415
+ end
416
+
417
+ @log.info("chassis ended")
418
+ found
419
+ end
420
+
421
+ #Adapter pattern method to make finding PSUs easier
422
+ #Returns an *Array* of found objects
423
+ #The logic works like this:
424
+ #* You can just provide a dn, we just get that and we're done
425
+ #* You can provide *either* a :chassis or a :fabric, but not both
426
+ #* If you only provide a :chassis we get all that :chassis's PSUs \
427
+ # or you can provide a :chassis and a :psu, which is like a full dn
428
+ #* If you only provide a :fabric we get all that :fabric's PSUs
429
+ # or you can provide a :fabric and a :psu, which is like a full dn
430
+ #* If you provide nothing, we get all PSUs
431
+ def psu(opts={})
432
+ @log.info("psu started")
433
+
434
+ classId = 'equipmentPsu'
435
+
436
+ if opts[:dn]
437
+ found = configResolveDn( :dn => opts[:dn] )
438
+ elsif opts[:chassis] and opts[:fabric]
439
+ @log.error("Only provide either :chassis => number OR :fabric => A|B")
440
+ elsif opts[:chassis] or opts[:fabric]
441
+ found = Array.new
442
+ if opts[:chassis]
443
+ chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
444
+ if opts[:psu]
445
+ full_dn = chassis_dn + '/psu-' + opts[:psu].to_s
446
+ found = configResolveDn( :inDn => full_dn )
447
+ else
448
+ found = configResolveChildren( :classId => classId, :inDn => chassis_dn )
449
+ end
450
+ elsif opts[:fabric]
451
+ fabric_dn = 'sys/switch-' + opts[:fabric].to_s
452
+ if opts[:psu]
453
+ full_dn = fabric_dn + '/psu-' + opts[:psu].to_s
454
+ found = configResolveDn( :inDn => full_dn )
455
+ else
456
+ found = configResolveChildren( :classId => classId, :inDn => fabric_dn )
457
+ end
458
+ end
459
+ else
460
+ found = configResolveClass( :classId => classId)
461
+ end
462
+
463
+ @log.info("psu ended")
464
+ found
465
+ end
466
+
467
+ #Adapter pattern method to make finding Fans easier
468
+ #Returns an *Array* of found objects
469
+ #The logic works like this:
470
+ #* You can just provide a dn, we just get that and we're done
471
+ #* You can provide *either* a :chassis or a :fabric, but not both
472
+ #* If you provide a :chassis you have to provide a :module
473
+ #* If you provide no parameters, we get all fans
474
+ def fan(opts={})
475
+ @log.info("fan started")
476
+
477
+ classId = 'equipmentFan'
478
+
479
+ if opts[:dn]
480
+ found = configResolveDn( :dn => opts[:dn] )
481
+ elsif opts[:chassis] and opts[:fabric]
482
+ @log.error("Only provide either :chassis => number OR :fabric => A|B")
483
+ elsif opts[:chassis] or opts[:fabric]
484
+ found = Array.new
485
+ if opts[:chassis]
486
+ chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
487
+ if opts[:module]
488
+ module_dn = chassis_dn + '/fan-module-' + opts[:module]
489
+ if opts[:fan]
490
+ full_dn = module_dn + '/fan-' + opts[:fan].to_s
491
+ found = configResolveDn( :inDn => full_dn )
492
+ else
493
+ found = configResolveChildren( :classId => classId, :inDn => module_dn )
494
+ end
495
+ else
496
+ @log.error "UCSM.fan Missing :module parameter"
497
+ end
498
+ elsif opts[:fabric]
499
+ fabric_dn = 'sys/switch-' + opts[:fabric].to_s
500
+ if opts[:fan]
501
+ full_dn = fabric_dn + '/fan-' + opts[:fan].to_s
502
+ found = configResolveDn( :inDn => full_dn )
503
+ else
504
+ found = configResolveChildren( :classId => classId, :inDn => fabric_dn )
505
+ end
506
+ end
507
+ else
508
+ found = configResolveClass( :classId => classId)
509
+ end
510
+
511
+ @log.info("fan ended")
512
+ found
513
+ end
514
+
515
+ def configResolveClasses
516
+ @log.error("Not implemented yet")
517
+ end
518
+
519
+ def configFindDnsByClassId
520
+ @log.error("Not implemented yet")
521
+ end
522
+
523
+ def configResolveParent
524
+ @log.error("Not implemented yet")
525
+ end
526
+
527
+ def help
528
+ @log.error("Not implemented yet")
529
+ end
530
+
531
+ def usage
532
+ @log.error("Not implemented yet")
533
+ end
534
+
535
+ def man
536
+ @log.error("Not implemented yet")
537
+ end
538
+
539
+ end
540
+
541
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/UCSAPI.rb'}"
9
+ puts "Loading UCSAPI gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestUCSAPI < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/UCSAPI'
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: UCSAPI
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 6
10
+ version: 0.0.6
11
+ platform: ruby
12
+ authors:
13
+ - Steve Chambers
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-01 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rubygems-update
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rest-client
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rubyforge
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 7
58
+ segments:
59
+ - 2
60
+ - 0
61
+ - 4
62
+ version: 2.0.4
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: hoe
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 19
74
+ segments:
75
+ - 2
76
+ - 6
77
+ - 2
78
+ version: 2.6.2
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: A simple ruby interface to the Cisco UCS XMLAPI
82
+ email:
83
+ - stevie_chambers @nospam@ viewyonder.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files:
89
+ - History.txt
90
+ - Manifest.txt
91
+ - PostInstall.txt
92
+ files:
93
+ - History.txt
94
+ - Manifest.txt
95
+ - PostInstall.txt
96
+ - Rakefile
97
+ - lib/UCSAPI.rb
98
+ - script/console
99
+ - script/destroy
100
+ - script/generate
101
+ - test/test_UCSAPI.rb
102
+ - test/test_helper.rb
103
+ has_rdoc: true
104
+ homepage: http://ciscoucs.rubyforge.org
105
+ licenses: []
106
+
107
+ post_install_message: PostInstall.txt
108
+ rdoc_options:
109
+ - --main
110
+ - README.rdoc
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project: ciscoucs
134
+ rubygems_version: 1.3.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Simple Ruby interface to the UCS XMLAPI
138
+ test_files:
139
+ - test/test_helper.rb
140
+ - test/test_UCSAPI.rb