UCSAPI 0.0.7 → 0.0.8
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/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"
|