UCSAPI 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/UCSAPI.rb +82 -582
- metadata +3 -10
data/lib/UCSAPI.rb
CHANGED
@@ -1,612 +1,112 @@
|
|
1
|
-
|
2
|
-
|
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
|
1
|
+
# == Synopsis
|
2
|
+
# Main Ruby interface with help methods for UCS API
|
28
3
|
#
|
29
|
-
#
|
30
|
-
#
|
4
|
+
# == Examples
|
5
|
+
# ucs = UCS.new(options) where options is hash containing :url, :inName, :inPassword..
|
6
|
+
# ucs.login - will use the Nuova library which is like the "raw" interface to UCS
|
7
|
+
# ucs.fabric (or another object) - use a helper method to retrieve UCS objects from API
|
8
|
+
# ucs.logout - end session on UCS
|
31
9
|
#
|
32
|
-
|
10
|
+
# == Methods
|
11
|
+
# new(hash)
|
12
|
+
# login
|
13
|
+
# fabric with optional hash containing either :id or :dn
|
14
|
+
# logout
|
33
15
|
#
|
34
|
-
#
|
35
|
-
#
|
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
|
16
|
+
# == Author
|
17
|
+
# Steve Chambers, Cisco
|
18
|
+
# Blogger at http://viewyonder.com
|
41
19
|
#
|
42
|
-
#
|
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.7'
|
20
|
+
# == Copyright
|
21
|
+
# Copyright (c) 2010 Steve Chambers. Licensed under the Create Commons Unported
|
22
|
+
# http://creativecommons.org/licenses/by/3.0/
|
52
23
|
|
53
|
-
|
54
|
-
|
24
|
+
# TO DO - replace license link with viewyonder link
|
25
|
+
# TO DO - get a singleton logger
|
55
26
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
27
|
+
module UCSAPI
|
28
|
+
|
29
|
+
require 'rubygems'
|
30
|
+
require 'rexml/document'
|
31
|
+
require 'rest_client'
|
32
|
+
require 'ostruct'
|
33
|
+
require 'logger'
|
34
|
+
require_relative 'Nuova'
|
35
|
+
require_relative 'UCSMO'
|
36
|
+
|
37
|
+
VERSION = '0.0.8'
|
38
|
+
|
39
|
+
class UCS
|
40
|
+
|
41
|
+
include Nuova
|
42
|
+
include UCSMO
|
43
|
+
|
44
|
+
attr_reader :api
|
45
|
+
|
62
46
|
def initialize(opts={})
|
63
|
-
|
47
|
+
|
48
|
+
raise "No parameters" if opts == nil
|
64
49
|
@log = Logger.new(STDOUT)
|
65
|
-
@log.level =
|
66
|
-
|
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)
|
50
|
+
@log.level = Logger::ERROR
|
51
|
+
@log.progname = self.class.to_s
|
149
52
|
|
150
|
-
|
151
|
-
|
152
|
-
|
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("dispatch starting")
|
165
|
-
@log.info("dispatch called with " + xml.to_s)
|
166
|
-
|
167
|
-
# The RestClient.post method expects text, not a REXML object
|
168
|
-
post = xml.to_s
|
169
|
-
|
170
|
-
# FIXME: RestClient timeout is broken and default wait is 75s #dontaskmewhy
|
171
|
-
begin
|
172
|
-
response = RestClient.post @user.url, post, :content_type => 'text/xml'
|
173
|
-
rescue => e
|
174
|
-
@log.error "dispatch EXCEPTION " + e.class.to_s + " = " + e.to_s
|
175
|
-
exit
|
176
|
-
end
|
177
|
-
|
178
|
-
@log.info("dispatch received " + response.to_s)
|
179
|
-
REXML::Document.new(response).root
|
53
|
+
@log.info("initialize starting")
|
54
|
+
@api = API.new(opts)
|
55
|
+
@log.info("initialize ending")
|
180
56
|
end
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
#* Build the XMLAPI call from the opts parameters
|
185
|
-
#* Send the XMLAPI object to dispatch, get an XML object back
|
186
|
-
#If the response XML has objects under <outConfig> then
|
187
|
-
#* get each element and
|
188
|
-
#* build an OpenStruct with attributes from the XML attributes
|
189
|
-
#* add each OpenStruct to an array, which is returned to the method caller outConfig = response.root.elements[1]
|
190
|
-
def configResolveDn(opts={})
|
191
|
-
@log.info("configResolveDn started")
|
192
|
-
|
193
|
-
inHierarchical = opts[:inHierarchical] || "false"
|
194
|
-
if opts[:dn] then
|
195
|
-
request = REXML::Document.new('<configResolveDn />')
|
196
|
-
request.root.add_attribute("inHierarchical",inHierarchical)
|
197
|
-
request.root.add_attribute("dn",opts[:dn])
|
198
|
-
|
199
|
-
response = dispatch(request)
|
200
|
-
|
201
|
-
outConfig = response.root.elements[1]
|
202
|
-
if outConfig.has_elements? then
|
203
|
-
found = Array.new
|
204
|
-
outConfig.elements.each do |element|
|
205
|
-
attrs = Hash.new
|
206
|
-
attrs["classId"] = element.name
|
207
|
-
element.attributes.each { | key, value | attrs[key]=value }
|
208
|
-
found << OpenStruct.new(attrs)
|
209
|
-
end
|
210
|
-
|
211
|
-
@log.info "configResolveDn returning " + found.size.to_s + " objects"
|
212
|
-
else
|
213
|
-
@log.error "configResolveDn ERROR No items found for dn = " + opts[:dn]
|
214
|
-
end
|
215
|
-
else
|
216
|
-
@log.error "configResolveDn ERROR Please supply a :dn option like configResolveDn( :dn => 'sys/chassis-1' )" unless opts[:dn]
|
217
|
-
end
|
218
|
-
|
219
|
-
@log.info("configResolveDn ended")
|
220
|
-
found
|
57
|
+
|
58
|
+
def login
|
59
|
+
@api.login if @api.session.cookie = ""
|
221
60
|
end
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
#Returns an *Array* of found objects
|
226
|
-
#* Build the XMLAPI call from the opts parameters
|
227
|
-
#* Send the XMLAPI object to dispatch, get an XML object back
|
228
|
-
#If the response XML has objects under <outConfig> then
|
229
|
-
#* get each element and
|
230
|
-
#* build an OpenStruct with attributes from the XML attributes
|
231
|
-
#* add each OpenStruct to an array, which is returned to the method caller
|
232
|
-
def configResolveClass(opts={})
|
233
|
-
@log.info("configResolveClass started")
|
234
|
-
|
235
|
-
inHierarchical = opts[:inHierarchical] || "false"
|
236
|
-
if opts[:classId] then
|
237
|
-
request = REXML::Document.new('<configResolveClass />')
|
238
|
-
request.root.add_attribute("inHierarchical",inHierarchical)
|
239
|
-
request.root.add_attribute("classId",opts[:classId])
|
240
|
-
if opts[:inFilter]
|
241
|
-
filterHash = opts[:inFilter]
|
242
|
-
filterType = filterHash["type"]
|
243
|
-
filterProperty = filterHash["property"]
|
244
|
-
filterValue = filterHash["value"]
|
245
|
-
inFilter = request.root.add_element("inFilter")
|
246
|
-
inFilter.add_element(filterType, { "class" => opts[:classId], "property" => filterProperty, "value" => filterValue})
|
247
|
-
end
|
248
|
-
|
249
|
-
puts request.to_s
|
250
|
-
|
251
|
-
response = dispatch(request)
|
252
|
-
|
253
|
-
outConfig = response.root.elements[1]
|
254
|
-
if outConfig.has_elements? then
|
255
|
-
found = Array.new
|
256
|
-
outConfig.elements.each do |element|
|
257
|
-
attrs = Hash.new
|
258
|
-
attrs["classId"] = element.name
|
259
|
-
element.attributes.each { | key, value | attrs[key]=value }
|
260
|
-
found << OpenStruct.new(attrs)
|
261
|
-
end
|
262
|
-
|
263
|
-
@log.info "configResolveClass returning " + found.size.to_s + " objects"
|
264
|
-
else
|
265
|
-
@log.error "configResolveClass ERROR No items found for classId = " + opts[:classId] + " with filter: " + opts[:inFilter].to_s
|
266
|
-
end
|
267
|
-
else
|
268
|
-
@log.error "configResolveClass ERROR Please supply a :classId option like configResolveClass( :classId => 'equipmentChassis' )" unless opts[:classId]
|
269
|
-
end
|
270
|
-
|
271
|
-
@log.info("configResolveClass ended")
|
272
|
-
found
|
61
|
+
|
62
|
+
def api
|
63
|
+
@api
|
273
64
|
end
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
#* Build the XMLAPI call from the opts parameters
|
278
|
-
#* Send the XMLAPI object to dispatch, get an XML object back
|
279
|
-
#If the response XML has objects under <outConfig> then
|
280
|
-
#* get each element and
|
281
|
-
#* build an OpenStruct with attributes from the XML attributes
|
282
|
-
#* add each OpenStruct to an array, which is returned to the method caller
|
283
|
-
def configResolveChildren(opts={})
|
284
|
-
@log.info("configResolveChildren started")
|
285
|
-
|
286
|
-
inHierarchical = opts[:inHierarchical] || "false"
|
287
|
-
request = REXML::Document.new('<configResolveChildren />')
|
288
|
-
request.root.add_attribute("inHierarchical",inHierarchical)
|
289
|
-
request.root.add_attribute("classId",opts[:classId])
|
290
|
-
request.root.add_attribute("inDn",opts[:inDn])
|
291
|
-
|
292
|
-
response = dispatch(request)
|
293
|
-
|
294
|
-
outConfig = response.root.elements[1]
|
295
|
-
if outConfig.has_elements? then
|
296
|
-
found = Array.new
|
297
|
-
outConfig.elements.each do |element|
|
298
|
-
attrs = Hash.new
|
299
|
-
attrs["classId"] = element.name
|
300
|
-
element.attributes.each { | key, value | attrs[key]=value }
|
301
|
-
found << OpenStruct.new(attrs)
|
302
|
-
end
|
303
|
-
@log.info "configResolveChildren returning " + found.size.to_s + " objects"
|
304
|
-
else
|
305
|
-
@log.error "configResolveChildren ERROR No items found for classId = " + opts[:classId]
|
306
|
-
end
|
307
|
-
|
308
|
-
@log.info("configResolveChildren ended")
|
309
|
-
found
|
65
|
+
|
66
|
+
def session
|
67
|
+
@api.session
|
310
68
|
end
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
#* Build the XMLAPI call from the opts parameters
|
315
|
-
#* Send the XMLAPI object to dispatch, get an XML object back
|
316
|
-
#If the response XML has objects under <outConfig> then
|
317
|
-
#* get each element and
|
318
|
-
#* build an OpenStruct with attributes from the XML attributes
|
319
|
-
#* add each OpenStruct to an array, which is returned to the method caller
|
320
|
-
def configScope(opts={})
|
321
|
-
@log.info("configScope started")
|
322
|
-
|
323
|
-
inHierarchical = opts[:inHierarchical] || "false"
|
324
|
-
inRecursive = opts[:inRecursive] || "false"
|
325
|
-
request = REXML::Document.new('<configScope />')
|
326
|
-
request.root.add_attribute("inHierarchical",inHierarchical)
|
327
|
-
request.root.add_attribute("inClass",opts[:inClass])
|
328
|
-
request.root.add_attribute("dn",opts[:dn])
|
329
|
-
|
330
|
-
response = dispatch(request)
|
331
|
-
|
332
|
-
outConfig = response.root.elements[1]
|
333
|
-
if outConfig.has_elements? then
|
334
|
-
found = Array.new
|
335
|
-
outConfig.elements.each do |element|
|
336
|
-
attrs = Hash.new
|
337
|
-
attrs["classId"] = element.name
|
338
|
-
element.attributes.each { | key, value | attrs[key]=value }
|
339
|
-
found << OpenStruct.new(attrs)
|
340
|
-
end
|
341
|
-
@log.info "configScope returning " + found.size.to_s + " objects"
|
342
|
-
else
|
343
|
-
@log.error "configScope ERROR No items found for classId = " + opts[:classId]
|
344
|
-
end
|
345
|
-
|
346
|
-
@log.info("configScope ended")
|
347
|
-
found
|
69
|
+
|
70
|
+
def logout
|
71
|
+
@api.logout
|
348
72
|
end
|
349
|
-
|
350
|
-
#Adapter pattern method to make finding fabric objects easier
|
351
|
-
#Returns an *Array* of found objects
|
73
|
+
|
352
74
|
#Logic is simple:
|
353
|
-
#* If you give us a dn,
|
354
|
-
#* If you provide a text ID,
|
355
|
-
#* If you provide nothing,
|
75
|
+
#* If you give us a dn, return one Fabric
|
76
|
+
#* If you provide a text ID, return one Fabric
|
77
|
+
#* If you provide nothing, return FabricArray
|
356
78
|
def fabric(opts={})
|
357
79
|
@log.info("fabric started")
|
358
80
|
|
359
|
-
found = Array.new
|
360
81
|
classId = 'networkElement'
|
361
|
-
|
362
82
|
if opts[:dn]
|
363
|
-
|
83
|
+
element = @api.configResolveDn( :dn => dn)
|
84
|
+
found = Fabric.create(@api,element)
|
364
85
|
elsif opts[:id] then
|
365
86
|
dn = 'sys/switch-' + opts[:id]
|
366
|
-
@
|
367
|
-
found =
|
87
|
+
element = @api.configResolveDn( :dn => dn )
|
88
|
+
found = Fabric.create(@api,element)
|
368
89
|
else
|
369
|
-
|
370
|
-
|
90
|
+
classId = 'networkElement'
|
91
|
+
elements = @api.configResolveClass( :classId => classId)
|
92
|
+
found = FabricArray.create(@api,elements)
|
371
93
|
end
|
372
|
-
|
373
|
-
@log.info
|
374
|
-
found
|
375
|
-
end
|
376
|
-
|
377
|
-
#Adapter pattern method to make finding chassis objects easier
|
378
|
-
#Returns an *Array* of found objects
|
379
|
-
#Logic is simple:
|
380
|
-
#* If you give us a dn, we get that and we're done
|
381
|
-
#* If you provide a numeric/text ID, we build a dn and get that
|
382
|
-
#* If you provide nothing, we get all chassis
|
383
|
-
def chassis(opts={})
|
384
|
-
@log.info("chassis started")
|
385
|
-
|
386
|
-
classId = 'equipmentChassis'
|
387
|
-
found = Array.new
|
388
|
-
|
389
|
-
if opts[:dn]
|
390
|
-
found = configResolveDn( :dn => opts[:dn] )
|
391
|
-
elsif opts[:id] then
|
392
|
-
dn = 'sys/chassis-' + opts[:id].to_s
|
393
|
-
found = configResolveDn( :dn => dn)
|
394
|
-
else
|
395
|
-
found = configResolveClass( :classId => classId)
|
396
|
-
end
|
397
|
-
|
398
|
-
@log.info("chassis ended")
|
399
|
-
found
|
400
|
-
end
|
401
|
-
|
402
|
-
#Adapter pattern method to make finding blades easier
|
403
|
-
#Returns an *Array* of found objects
|
404
|
-
#Logic is simple here:
|
405
|
-
#* You can just provide a dn, we just get that and we're done
|
406
|
-
#* If you provide only a :chassis, we get all blades in that chassis
|
407
|
-
#* If you provide a :chassis and a :blade it's like a full dn
|
408
|
-
#* If you provide nothing, we get all blades
|
409
|
-
def blade(opts={})
|
410
|
-
@log.info("blade started")
|
411
|
-
|
412
|
-
classId = 'computeBlade'
|
413
|
-
found = Array.new
|
414
|
-
|
415
|
-
if opts[:dn]
|
416
|
-
found = configResolveDn( :dn => opts[:dn] )
|
417
|
-
elsif opts[:chassis] then
|
418
|
-
chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
|
419
|
-
if opts[:blade] then
|
420
|
-
dn = chassis_dn + '/blade-' + opts[:blade].to_s
|
421
|
-
found = configResolveDn( :dn => dn)
|
422
|
-
else
|
423
|
-
configResolveChildren( :classId => classId, :inDn => chassis_dn )
|
424
|
-
end
|
425
|
-
else
|
426
|
-
found = configResolveClass( :classId => classId)
|
427
|
-
end
|
428
|
-
|
429
|
-
@log.info("blade ended")
|
430
|
-
found
|
431
|
-
end
|
432
|
-
|
433
|
-
#Adapter pattern method to make finding service profiles easier
|
434
|
-
#Returns an *Array* of found objects
|
435
|
-
#Logic is simple here:
|
436
|
-
#* You can just provide a dn, we just get that and we're done
|
437
|
-
#* If you provide a :name, then we treat it as a wildcard and search that field
|
438
|
-
#* If you provide an :org, we get all the profiles under that
|
439
|
-
#* If you provide only a :chassis, we get all service profiles associated to blades in that chassis
|
440
|
-
#* If you provide a :chassis and a :blade we get the associated service profile
|
441
|
-
#* If you provide a :pnDn then it's the same as :chassis and :blade
|
442
|
-
#* If you provide a :inFilter hash with "type", "property", and "value" in it, we'll send on the search
|
443
|
-
#* If you provide a :uuid we'll get that profile
|
444
|
-
#* If you provide a :template name, we'll get all profiles based on that template
|
445
|
-
#* If you provide nothing, we get all blades
|
446
|
-
def server(opts={})
|
447
|
-
@log.info("server started")
|
448
|
-
|
449
|
-
classId = 'lsServer'
|
450
|
-
found = Array.new
|
451
|
-
|
452
|
-
if opts[:dn]
|
453
|
-
found = configResolveDn( :dn => opts[:dn] )
|
454
|
-
elsif opts[:name]
|
455
|
-
inFilter = { "type" => "wcard", "property" => "name", "value" => opts[:name] }
|
456
|
-
found = configResolveClass( :classId => classId, :inFilter => inFilter)
|
457
|
-
elsif opts[:org]
|
458
|
-
found = configResolveChildren( :inDn => 'org-'+opts[:org], :classId => classId )
|
459
|
-
elsif opts[:uuid]
|
460
|
-
inFilter = { "type" => "wcard", "property" => "uuid", "value" => opts[:uuid] }
|
461
|
-
found = configResolveClass( :classId => classId, :inFilter => inFilter)
|
462
|
-
elsif opts[:template]
|
463
|
-
inFilter = { "type" => "wcard", "property" => "srcTemplName", "value" => opts[:template] }
|
464
|
-
found = configResolveClass( :classId => classId, :inFilter => inFilter)
|
465
|
-
elsif opts[:chassis]
|
466
|
-
if opts[:chassis] =~ /chassis-/
|
467
|
-
pnDn = opts[:chassis]
|
468
|
-
else
|
469
|
-
pnDn = 'chassis-' + opts[:chassis]
|
470
|
-
end
|
471
|
-
if opts[:blade]
|
472
|
-
pnDn << "/"
|
473
|
-
if opts[:blade] =~ /blade-/
|
474
|
-
pnDn << opts[:blade]
|
475
|
-
else
|
476
|
-
pnDn << 'blade-' + opts[:blade]
|
477
|
-
end
|
478
|
-
end
|
479
|
-
inFilter = { "type" => "wcard", "property" => "pnDn", "value" => pnDn }
|
480
|
-
found = configResolveClass( :classId => classId, :inFilter => inFilter)
|
481
|
-
elsif opts[:inFilter]
|
482
|
-
@log.error ":inFilter must be a hash of type, property, value" unless opts[:inFilter].class == Hash
|
483
|
-
found = configResolveClass( :classId => classId, :inFilter => opts[:inFilter])
|
484
|
-
else
|
485
|
-
found = configResolveClass( :classId => classId)
|
486
|
-
end
|
487
|
-
|
488
|
-
@log.info("server ended")
|
489
|
-
found
|
94
|
+
|
95
|
+
@log.info "fabric ended"
|
96
|
+
found
|
490
97
|
end
|
491
98
|
|
492
|
-
|
493
|
-
|
494
|
-
#The logic works like this:
|
495
|
-
#* You can just provide a dn, we just get that and we're done
|
496
|
-
#* You can provide *either* a :chassis or a :fabric, but not both
|
497
|
-
#* If you only provide a :chassis we get all that :chassis's PSUs \
|
498
|
-
# or you can provide a :chassis and a :psu, which is like a full dn
|
499
|
-
#* If you only provide a :fabric we get all that :fabric's PSUs
|
500
|
-
# or you can provide a :fabric and a :psu, which is like a full dn
|
501
|
-
#* If you provide nothing, we get all PSUs
|
502
|
-
def psu(opts={})
|
503
|
-
@log.info("psu started")
|
504
|
-
|
505
|
-
classId = 'equipmentPsu'
|
506
|
-
|
507
|
-
if opts[:dn]
|
508
|
-
found = configResolveDn( :dn => opts[:dn] )
|
509
|
-
elsif opts[:chassis] and opts[:fabric]
|
510
|
-
@log.error("Only provide either :chassis => number OR :fabric => A|B")
|
511
|
-
elsif opts[:chassis] or opts[:fabric]
|
512
|
-
found = Array.new
|
513
|
-
if opts[:chassis]
|
514
|
-
chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
|
515
|
-
if opts[:psu]
|
516
|
-
full_dn = chassis_dn + '/psu-' + opts[:psu].to_s
|
517
|
-
found = configResolveDn( :inDn => full_dn )
|
518
|
-
else
|
519
|
-
found = configResolveChildren( :classId => classId, :inDn => chassis_dn )
|
520
|
-
end
|
521
|
-
elsif opts[:fabric]
|
522
|
-
fabric_dn = 'sys/switch-' + opts[:fabric].to_s
|
523
|
-
if opts[:psu]
|
524
|
-
full_dn = fabric_dn + '/psu-' + opts[:psu].to_s
|
525
|
-
found = configResolveDn( :inDn => full_dn )
|
526
|
-
else
|
527
|
-
found = configResolveChildren( :classId => classId, :inDn => fabric_dn )
|
528
|
-
end
|
529
|
-
end
|
530
|
-
else
|
531
|
-
found = configResolveClass( :classId => classId)
|
532
|
-
end
|
533
|
-
|
534
|
-
@log.info("psu ended")
|
535
|
-
found
|
536
|
-
end
|
537
|
-
|
538
|
-
#Adapter pattern method to make finding Fans easier
|
539
|
-
#Returns an *Array* of found objects
|
540
|
-
#The logic works like this:
|
541
|
-
#* You can just provide a dn, we just get that and we're done
|
542
|
-
#* You can provide *either* a :chassis or a :fabric, but not both
|
543
|
-
#* If you provide a :chassis you have to provide a :module
|
544
|
-
#* If you provide no parameters, we get all fans
|
545
|
-
def fan(opts={})
|
546
|
-
@log.info("fan started")
|
547
|
-
|
548
|
-
classId = 'equipmentFan'
|
549
|
-
|
550
|
-
if opts[:dn]
|
551
|
-
found = configResolveDn( :dn => opts[:dn] )
|
552
|
-
elsif opts[:chassis] and opts[:fabric]
|
553
|
-
@log.error("Only provide either :chassis => number OR :fabric => A|B")
|
554
|
-
elsif opts[:chassis] or opts[:fabric]
|
555
|
-
found = Array.new
|
556
|
-
if opts[:chassis]
|
557
|
-
chassis_dn = 'sys/chassis-' + opts[:chassis].to_s
|
558
|
-
if opts[:module]
|
559
|
-
module_dn = chassis_dn + '/fan-module-' + opts[:module]
|
560
|
-
if opts[:fan]
|
561
|
-
full_dn = module_dn + '/fan-' + opts[:fan].to_s
|
562
|
-
found = configResolveDn( :inDn => full_dn )
|
563
|
-
else
|
564
|
-
found = configResolveChildren( :classId => classId, :inDn => module_dn )
|
565
|
-
end
|
566
|
-
else
|
567
|
-
@log.error "Missing :module parameter"
|
568
|
-
end
|
569
|
-
elsif opts[:fabric]
|
570
|
-
fabric_dn = 'sys/switch-' + opts[:fabric].to_s
|
571
|
-
if opts[:fan]
|
572
|
-
full_dn = fabric_dn + '/fan-' + opts[:fan].to_s
|
573
|
-
found = configResolveDn( :inDn => full_dn )
|
574
|
-
else
|
575
|
-
found = configResolveChildren( :classId => classId, :inDn => fabric_dn )
|
576
|
-
end
|
577
|
-
end
|
578
|
-
else
|
579
|
-
found = configResolveClass( :classId => classId)
|
580
|
-
end
|
99
|
+
def fabrics
|
100
|
+
@log.info("fabrics started")
|
581
101
|
|
582
|
-
|
102
|
+
classId = 'networkElement'
|
103
|
+
elements = @api.configResolveClass( :classId => classId)
|
104
|
+
found = FabricArray.create(@api,elements)
|
105
|
+
|
106
|
+
@log.info("fabrics ended")
|
583
107
|
found
|
584
108
|
end
|
585
|
-
|
586
|
-
def configResolveClasses
|
587
|
-
@log.error("Not implemented yet")
|
588
|
-
end
|
589
|
-
|
590
|
-
def configFindDnsByClassId
|
591
|
-
@log.error("Not implemented yet")
|
592
|
-
end
|
593
|
-
|
594
|
-
def configResolveParent
|
595
|
-
@log.error("Not implemented yet")
|
596
|
-
end
|
597
|
-
|
598
|
-
def help
|
599
|
-
@log.error("Not implemented yet")
|
600
|
-
end
|
601
|
-
|
602
|
-
def usage
|
603
|
-
@log.error("Not implemented yet")
|
604
|
-
end
|
605
|
-
|
606
|
-
def man
|
607
|
-
@log.error("Not implemented yet")
|
608
|
-
end
|
609
|
-
|
109
|
+
|
610
110
|
end
|
611
|
-
|
612
|
-
end
|
111
|
+
|
112
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: UCSAPI
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 17
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
8
|
+
- 8
|
9
|
+
version: 0.0.8
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Steve Chambers
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-08 00:00:00 +01:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,7 +25,6 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
28
|
segments:
|
31
29
|
- 0
|
32
30
|
version: "0"
|
@@ -40,7 +38,6 @@ dependencies:
|
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 3
|
44
41
|
segments:
|
45
42
|
- 0
|
46
43
|
version: "0"
|
@@ -54,7 +51,6 @@ dependencies:
|
|
54
51
|
requirements:
|
55
52
|
- - ">="
|
56
53
|
- !ruby/object:Gem::Version
|
57
|
-
hash: 7
|
58
54
|
segments:
|
59
55
|
- 2
|
60
56
|
- 0
|
@@ -70,7 +66,6 @@ dependencies:
|
|
70
66
|
requirements:
|
71
67
|
- - ">="
|
72
68
|
- !ruby/object:Gem::Version
|
73
|
-
hash: 19
|
74
69
|
segments:
|
75
70
|
- 2
|
76
71
|
- 6
|
@@ -115,7 +110,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
110
|
requirements:
|
116
111
|
- - ">="
|
117
112
|
- !ruby/object:Gem::Version
|
118
|
-
hash: 3
|
119
113
|
segments:
|
120
114
|
- 0
|
121
115
|
version: "0"
|
@@ -124,7 +118,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
118
|
requirements:
|
125
119
|
- - ">="
|
126
120
|
- !ruby/object:Gem::Version
|
127
|
-
hash: 3
|
128
121
|
segments:
|
129
122
|
- 0
|
130
123
|
version: "0"
|