spectools 1.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/CHANGELOG.txt +1 -0
- data/Manifest.txt +80 -0
- data/README.txt +33 -0
- data/README.vnmsh.txt +39 -0
- data/Rakefile +42 -0
- data/TODO +5 -0
- data/lib/spectools.rb +588 -0
- data/lib/spectools/version.rb +9 -0
- data/lib/vnmsh.rb +1930 -0
- data/test/data/connect.success +8 -0
- data/test/data/create.alarm +2 -0
- data/test/data/create.association +1 -0
- data/test/data/create.model +1 -0
- data/test/data/create.model.ip +1 -0
- data/test/data/destroy.alarm +1 -0
- data/test/data/destroy.association +1 -0
- data/test/data/destroy.model +9 -0
- data/test/data/seek +2 -0
- data/test/data/seek.-s +17 -0
- data/test/data/show.alarms +10 -0
- data/test/data/show.alarms-a +11 -0
- data/test/data/show.alarms-a-x +22 -0
- data/test/data/show.alarms-x +20 -0
- data/test/data/show.alarms.mh +1 -0
- data/test/data/show.associations +160 -0
- data/test/data/show.attributes +909 -0
- data/test/data/show.attributes.attr +2 -0
- data/test/data/show.attributes.attriid +2 -0
- data/test/data/show.attributes.attrname +6 -0
- data/test/data/show.attributes.attrr +14 -0
- data/test/data/show.attributes.enum +2 -0
- data/test/data/show.attributes.flags +16 -0
- data/test/data/show.attributes.mth +242 -0
- data/test/data/show.attributes.mth.attrr +12 -0
- data/test/data/show.children +47 -0
- data/test/data/show.children.rel +14 -0
- data/test/data/show.devices +21 -0
- data/test/data/show.enumerations +142383 -0
- data/test/data/show.enumerations.attr +4 -0
- data/test/data/show.enumerations.mth +149 -0
- data/test/data/show.events +2001 -0
- data/test/data/show.events-a +10001 -0
- data/test/data/show.events-n5 +6 -0
- data/test/data/show.events-x-n5 +21 -0
- data/test/data/show.inheritance +12 -0
- data/test/data/show.landscapes +3 -0
- data/test/data/show.models +2252 -0
- data/test/data/show.models.mhr +18 -0
- data/test/data/show.models.mname +4 -0
- data/test/data/show.models.mth +4 -0
- data/test/data/show.parents +6 -0
- data/test/data/show.relations +151 -0
- data/test/data/show.rules +5838 -0
- data/test/data/show.types +4210 -0
- data/test/data/show.types.flags +3137 -0
- data/test/data/show.types.mthr +55 -0
- data/test/data/show.types.mtname +2 -0
- data/test/data/show.watch +9 -0
- data/test/data/test.reconnect +1 -0
- data/test/data/update.alarm +1 -0
- data/test/data/update.model +3 -0
- data/test/test_helper.rb +2 -0
- data/test/test_spectools.rb +403 -0
- data/test/test_vnmsh.rb +1537 -0
- data/test/testcmds/ack +1 -0
- data/test/testcmds/connect +32 -0
- data/test/testcmds/create +34 -0
- data/test/testcmds/destroy +36 -0
- data/test/testcmds/disconnect +7 -0
- data/test/testcmds/seek +18 -0
- data/test/testcmds/show +243 -0
- data/test/testcmds/update +12 -0
- data/test/vnmsh/ack +1 -0
- data/test/vnmsh/connect +5 -0
- data/test/vnmsh/create +1 -0
- data/test/vnmsh/destroy +1 -0
- data/test/vnmsh/disconnect +1 -0
- data/test/vnmsh/seek +3 -0
- data/test/vnmsh/show +1 -0
- data/test/vnmsh/update +1 -0
- metadata +134 -0
data/lib/vnmsh.rb
ADDED
@@ -0,0 +1,1930 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
include SpecTools
|
4
|
+
|
5
|
+
if defined?(SpecTools::Attr)
|
6
|
+
class SpecTools::Attr
|
7
|
+
#Take a line of CLI <tt>show attributes mh=</tt> output and populate a new Attr object
|
8
|
+
def self.cli_parse_mh(line)
|
9
|
+
specattr = Attr.new()
|
10
|
+
#Because the instance identifier may not fit into the column space allocated, we can't reliably use unpack
|
11
|
+
#to parse the data. Instead, we'll use a regex. This means that the attr name can't contain whitespace,
|
12
|
+
#but it should be okay.
|
13
|
+
if line.chomp =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(.+)$/
|
14
|
+
specattr.id = $1
|
15
|
+
specattr.name = $2
|
16
|
+
specattr.list = true
|
17
|
+
specattr.value_table[$3] = $4
|
18
|
+
elsif line.chomp =~ /^(\S+)\s+(\S+)\s+(.+)$/
|
19
|
+
specattr.id = $1
|
20
|
+
specattr.name = $2
|
21
|
+
specattr.value = $3
|
22
|
+
end
|
23
|
+
return specattr
|
24
|
+
end
|
25
|
+
|
26
|
+
#Take a line of CLI <tt>show attributes mth=</tt> output and populate a new Attr object
|
27
|
+
def self.cli_parse_mth(line)
|
28
|
+
attr = Attr.new
|
29
|
+
attr.id,attr.name,attr.type,flags = line.chomp.unpack('A12A33A18A23')
|
30
|
+
flags.split(/,/).each do |flag|
|
31
|
+
case flag
|
32
|
+
when 'E'
|
33
|
+
attr.external = true
|
34
|
+
when 'R'
|
35
|
+
attr.readable = true
|
36
|
+
when 'W'
|
37
|
+
attr.writeable = true
|
38
|
+
when 'S'
|
39
|
+
attr.shared = true
|
40
|
+
when 'T'
|
41
|
+
attr.list = true
|
42
|
+
when 'G'
|
43
|
+
attr.guaranteed = true
|
44
|
+
when 'O'
|
45
|
+
attr.global = true
|
46
|
+
when 'M'
|
47
|
+
attr.memory = true
|
48
|
+
when 'D'
|
49
|
+
attr.database = true
|
50
|
+
when 'P'
|
51
|
+
attr.polled = true
|
52
|
+
when 'L'
|
53
|
+
attr.logged = true
|
54
|
+
when 'V'
|
55
|
+
attr.preserve = true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return attr
|
59
|
+
end
|
60
|
+
|
61
|
+
#Use CLI to retrieve the enumerations for the Attr.
|
62
|
+
#Returns a new hash of enumerations.
|
63
|
+
def cli_get_enums(session=nil)
|
64
|
+
unless self.id.hex?
|
65
|
+
raise ArgumentError, 'To enumerate this Attr, the Attr must have a valid id.'
|
66
|
+
end
|
67
|
+
enums = Hash.new
|
68
|
+
session = VNMSH.get_session(session)
|
69
|
+
enum_output = session.show_enumerations(:attr,self)
|
70
|
+
if enum_output != nil
|
71
|
+
enum_output.each do |line|
|
72
|
+
line.chomp!
|
73
|
+
id,str,val = line.unpack('A12A34A12')
|
74
|
+
val.sub!(/\s+/, '')
|
75
|
+
str.sub!(/\s+$/, '')
|
76
|
+
enums[val] = str
|
77
|
+
end
|
78
|
+
else
|
79
|
+
return nil
|
80
|
+
end
|
81
|
+
return enums
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
#Execute cli_get_enums and modify the Attr object in place.
|
86
|
+
def cli_get_enums!(session=nil)
|
87
|
+
new_enums = cli_get_enums(session)
|
88
|
+
self.enums = new_enums
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
else
|
93
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
94
|
+
end
|
95
|
+
|
96
|
+
if defined?(SpecTools::MType)
|
97
|
+
class SpecTools::MType
|
98
|
+
#Take a line of CLI <tt>show types</tt> output and populate a new MType object.
|
99
|
+
def self.cli_parse(line)
|
100
|
+
handle,name,flags = line.unpack('A12A1025A11')
|
101
|
+
type = MType.new(handle,name)
|
102
|
+
flags.chomp.split(/,/).each do |flag|
|
103
|
+
case flag
|
104
|
+
when 'V'
|
105
|
+
type.visible = true
|
106
|
+
when 'I'
|
107
|
+
type.instantiable = true
|
108
|
+
when 'D'
|
109
|
+
type.derivable = true
|
110
|
+
when 'N'
|
111
|
+
type.destroyable = false
|
112
|
+
when 'U'
|
113
|
+
type.unique = true
|
114
|
+
when 'R'
|
115
|
+
type.required = true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
return type
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
#Take a line of CLI <tt>show inheritance</tt> output and populate a new MType object.
|
123
|
+
def self.cli_parse_inheritance(line)
|
124
|
+
handle,name,flags,inheritance = line.chomp.unpack('A12A18A13A10')
|
125
|
+
type = MType.new(handle,name)
|
126
|
+
type.inheritance = inheritance
|
127
|
+
flags.split(/,/).each do |flag|
|
128
|
+
|
129
|
+
case flag
|
130
|
+
when 'V'
|
131
|
+
type.visible = true
|
132
|
+
when 'I'
|
133
|
+
type.instantiable = true
|
134
|
+
when 'D'
|
135
|
+
type.derivable = true
|
136
|
+
when 'N'
|
137
|
+
type.destroyable = false
|
138
|
+
when 'U'
|
139
|
+
type.unique = true
|
140
|
+
when 'R'
|
141
|
+
type.required = true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
return type
|
145
|
+
end
|
146
|
+
|
147
|
+
#Use CLI to locate Model Types. Returns an array of MType objects.
|
148
|
+
#
|
149
|
+
#<tt>filter</tt> is a hash of filter types and thier values.
|
150
|
+
#
|
151
|
+
#If no filter is passed, returns all MTypes for the connected Landscape.
|
152
|
+
#Filter options:
|
153
|
+
#
|
154
|
+
#* <tt>:flag</tt> - filters on the provided flag
|
155
|
+
# * Example: <tt>MType.cli_find({:flag,:unique})</tt>
|
156
|
+
#* <tt>:range</tt> - filters on a range of model types
|
157
|
+
# * Range can either be a single string, an Array of handles, or an Array of MTypes.
|
158
|
+
# * Example: <tt>MType.cli_find({:range,'0x400000-0x500000'})</tt>
|
159
|
+
# * Example: <tt>MType.cli_find(:range,['0x400000','0x500000']})</tt>
|
160
|
+
#* <tt>:name</tt> - filters on the model type's name (partials accepted)
|
161
|
+
# * Example: <tt>MType.cli_find({:name,'VNM'})</tt>
|
162
|
+
#* <tt>:landscape</tt> - filters on the given Landscape.
|
163
|
+
# * Example: <tt>MType.cli_find({:landscape,'0x400000'})</tt>
|
164
|
+
def self.cli_find(filter=nil,session=nil)
|
165
|
+
session = VNMSH.get_session(session)
|
166
|
+
mtypes = Array.new
|
167
|
+
if filter && filter[:flag]
|
168
|
+
filter[:flag] = case filter[:flag]
|
169
|
+
when :visible then 'V'
|
170
|
+
when :instantiable then 'I'
|
171
|
+
when :derivable then 'D'
|
172
|
+
when :nodestroy then 'N'
|
173
|
+
when :unique then 'U'
|
174
|
+
when :required then 'R'
|
175
|
+
end
|
176
|
+
end
|
177
|
+
mtype_output = session.show_types(filter)
|
178
|
+
mtype_output.each do |line|
|
179
|
+
mtypes.push(MType.parse(line))
|
180
|
+
end
|
181
|
+
return mtypes
|
182
|
+
end
|
183
|
+
|
184
|
+
#Use CLI to retrieve a hash of Attr objects for a given MType.
|
185
|
+
#
|
186
|
+
#<tt>filter</tt> is a hash of filter types and thier values.
|
187
|
+
#
|
188
|
+
#If no filter is given, all attributes are returned.
|
189
|
+
#
|
190
|
+
#Filter options.
|
191
|
+
#
|
192
|
+
#* <tt>:range</tt> - returns attributes whose ID in in the specified range.
|
193
|
+
# * Range can take a single range string, or an array of MType handles or MTypes.
|
194
|
+
# * Example: <tt>mtype.cli_get_attrs({:range,['0x10000','0x1000a])</tt>
|
195
|
+
# * Example: <tt>mtype.cli_get_attrs({:range,'0x10000-0x1000a'})</tt>
|
196
|
+
#* <tt>:name</tt> - returns attributes whose name contains the specified string.
|
197
|
+
# * Example: <tt>mtype.cli_get_attrs({:name,'Condition'})</tt>
|
198
|
+
#* <tt>:flag</tt> - returns attributes that have the specified flag set.
|
199
|
+
# * Example: <tt>mtype.cli_get_attrs({:flag,:global})</tt>
|
200
|
+
#* <tt>:landscape</tt> - returns attributes in the specified landscape.
|
201
|
+
# * landscape can be a Landscape object or a landscape handle.
|
202
|
+
# * Example: <tt>mtype.cli_get_attrs({:landscape,'0x400000'})</tt>
|
203
|
+
def cli_get_attrs(filter=nil,session=nil)
|
204
|
+
unless self.handle.hex?
|
205
|
+
raise ArgumentError, 'Must supply a valid model type handle'
|
206
|
+
end
|
207
|
+
attrs = Hash.new
|
208
|
+
session = VNMSH.get_session(session)
|
209
|
+
if filter && filter[:flag]
|
210
|
+
flag = case filter[:flag]
|
211
|
+
when :external then 'E'
|
212
|
+
when :readable then 'R'
|
213
|
+
when :writable then 'W'
|
214
|
+
when :shared then 'S'
|
215
|
+
when :list then 'T'
|
216
|
+
when :guaranteed then 'G'
|
217
|
+
when :global then 'O'
|
218
|
+
when :memory then 'M'
|
219
|
+
when :database then 'B'
|
220
|
+
when :polled then 'P'
|
221
|
+
when :logged then 'L'
|
222
|
+
when :preserve then 'V'
|
223
|
+
else
|
224
|
+
raise ArgumentError, 'Invalid flag'
|
225
|
+
end
|
226
|
+
filter[:flag] = flag
|
227
|
+
end
|
228
|
+
attr_output = session.show_attributes(:mtype,self,filter,false)
|
229
|
+
attr_output.each do |line|
|
230
|
+
tmpattr = Attr.parse_mth(line)
|
231
|
+
attrs[tmpattr.id] = tmpattr
|
232
|
+
end
|
233
|
+
return attrs
|
234
|
+
end
|
235
|
+
|
236
|
+
#Call cli_get_attrs and populate the MType's attrs attribute.
|
237
|
+
def cli_get_attrs!(filter=nil,session=nil)
|
238
|
+
attrs = self.cli_get_attrs(filter,session)
|
239
|
+
self.attrs = attrs
|
240
|
+
end
|
241
|
+
|
242
|
+
#Create a new Model via CLI for this type.
|
243
|
+
#attrs is an Array of Attr objects that you want to be set on the
|
244
|
+
#model when it is created.
|
245
|
+
def cli_create_model(attrs=nil,lh=nil,session=nil)
|
246
|
+
session = VNMSH.get_session(session)
|
247
|
+
return session.create_model(self,attrs,lh)
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
end
|
252
|
+
else
|
253
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
254
|
+
end
|
255
|
+
|
256
|
+
if defined?(SpecTools::Model)
|
257
|
+
class SpecTools::Model
|
258
|
+
#Take a line of CLI <tt>show models</tt> or <tt>seek</tt> output and populate a new Model object.
|
259
|
+
def self.cli_parse(line)
|
260
|
+
mhandle,mname,mthandle,mtname = line.chomp.unpack('A12A1025A12A20')
|
261
|
+
mtype = MType.new(mthandle,mtname)
|
262
|
+
model = Model.new(mhandle,mname,mtype)
|
263
|
+
return model
|
264
|
+
end
|
265
|
+
|
266
|
+
#Use CLI to locate Models. Returns an array of Model objects.
|
267
|
+
#
|
268
|
+
#
|
269
|
+
#<tt>filter</tt> is a hash of filter types and thier values.
|
270
|
+
#
|
271
|
+
#If no filter is passed, returns all Models for the connected Landscape.
|
272
|
+
#
|
273
|
+
#If <tt>devices</tt> is true, returns all devices. In this case,
|
274
|
+
#<tt>filter</tt> is ignored.
|
275
|
+
#
|
276
|
+
#Filter options:
|
277
|
+
#
|
278
|
+
#* <tt>:range</tt> - filters on a range of models.
|
279
|
+
# * Range can either be a single string, an Array of handles, or an Array of Models.
|
280
|
+
# * Example: <tt>Model.cli_find({:range,'0x400000-0x500000'})</tt>
|
281
|
+
# * Example: <tt>Model.cli_find(:range,['0x400000','0x500000']})</tt>
|
282
|
+
#* <tt>:name</tt> - filters on the model's name (partials accepted)
|
283
|
+
# * Example: <tt>Model.cli_find({:name,'VNM'})</tt>
|
284
|
+
#* <tt>:landscape</tt> - filters on the given Landscape.
|
285
|
+
# * Example: <tt>Model.cli_find({:landscape,'0x400000'})</tt>
|
286
|
+
#* <tt>:mtype</tt> - Returns all models of the specified type.
|
287
|
+
# * Type can either be an MType object, or a model type handle.
|
288
|
+
# * Examples:
|
289
|
+
# * <tt>Model.cli_find(:mtype, '0x13d0018')</tt>
|
290
|
+
# * <tt>Model.cli_find(:mtype, MType.new('0x13d0018'))</tt>
|
291
|
+
#
|
292
|
+
def self.cli_find(filter=nil,devices=false,session=nil)
|
293
|
+
session = VNMSH.get_session(session)
|
294
|
+
models = Array.new
|
295
|
+
if devices
|
296
|
+
if filter && filter[:landscape]
|
297
|
+
model_output = session.show_devices(filter[:landscape])
|
298
|
+
else
|
299
|
+
model_output = session.show_devices
|
300
|
+
end
|
301
|
+
else
|
302
|
+
model_output = session.show_models(filter)
|
303
|
+
end
|
304
|
+
model_output.each do |line|
|
305
|
+
models.push(Model.parse(line))
|
306
|
+
end
|
307
|
+
return models
|
308
|
+
end
|
309
|
+
|
310
|
+
#Use CLI to locate Models by attribute.
|
311
|
+
#
|
312
|
+
#<tt>specattr</tt> may be an Attr object or an attribute ID.
|
313
|
+
#If <tt>specattr</tt> is an Attr and has the value attribute set,
|
314
|
+
#<tt>value</tt> does not have to be set. However, you can override
|
315
|
+
#the Attr object's value in the search by providing your own
|
316
|
+
#<tt>value</tt>.
|
317
|
+
#
|
318
|
+
#If <tt>specattr.value</tt> is nil, or of <tt>specattr</tt> is simply
|
319
|
+
#an attribute ID, <tt>value</tt> must be set.
|
320
|
+
#
|
321
|
+
#If <tt>substring</tt> is true, a partial string match is performed.
|
322
|
+
#
|
323
|
+
#If <tt>nocase</tt> is true, case is ignored.
|
324
|
+
#
|
325
|
+
def self.cli_find_by_attr(specattr,value=nil,substring=false,nocase=false,session=nil)
|
326
|
+
session = VNMSH.get_session(session)
|
327
|
+
models = Array.new
|
328
|
+
model_output = session.seek(specattr,value,substring,nocase)
|
329
|
+
model_output.each do |line|
|
330
|
+
models.push(Model.parse(line))
|
331
|
+
end
|
332
|
+
return models
|
333
|
+
end
|
334
|
+
|
335
|
+
#Use CLI to retrieve a hash of Attr objects for a given Model.
|
336
|
+
#
|
337
|
+
#<tt>filter</tt> is a hash of filter types and thier values.
|
338
|
+
#
|
339
|
+
#If no filter is given, all attributes are returned.
|
340
|
+
#If <tt>enumerate</tt> is set to true, the values will
|
341
|
+
#be automatically enumerated.
|
342
|
+
#
|
343
|
+
#Filter options.
|
344
|
+
#
|
345
|
+
#* <tt>:id</tt> - returns the specific attribute.
|
346
|
+
# * Takes an Attr or an attribute ID.
|
347
|
+
# * Returns all instances for a list attribute.
|
348
|
+
# * Example: <tt>model.cli_get_attrs({:id,'0x10000'})</tt>
|
349
|
+
#* <tt>:instance</tt> = returns a specific instance of an attribute.
|
350
|
+
# * Takes a 2 element array.
|
351
|
+
# * The first element must be an Attr or an attribute id.
|
352
|
+
# * The second element must be an instance identifier.
|
353
|
+
# * Example: <tt>model.cli_get_attrs({:instance,['0x10000','192.168.1.1']})</tt>
|
354
|
+
#* <tt>:range</tt> - returns attributes whose ID in in the specified range.
|
355
|
+
# * Range can take a single range string, or an array of Model handles or Models.
|
356
|
+
# * Example: <tt>model.cli_get_attrs({:range,['0x10000','0x1000a])</tt>
|
357
|
+
# * Example: <tt>model.cli_get_attrs({:range,'0x10000-0x1000a'})</tt>
|
358
|
+
#* <tt>:name</tt> - returns attributes whose name contains the specified string.
|
359
|
+
# * Example: <tt>model.cli_get_attrs({:name,'Condition'})</tt>
|
360
|
+
def cli_get_attrs(filter=nil,enumerate=false,session=nil)
|
361
|
+
unless self.handle.hex?
|
362
|
+
raise ArgumentError, 'Must supply a valid model handle'
|
363
|
+
end
|
364
|
+
attrs = Hash.new
|
365
|
+
session = VNMSH.get_session(session)
|
366
|
+
|
367
|
+
attr_output = session.show_attributes(:model,self,filter,enumerate)
|
368
|
+
attr_output.each do |line|
|
369
|
+
tmpattr = Attr.parse_mh(line)
|
370
|
+
if attrs[tmpattr.id] && tmpattr.list && attrs[tmpattr.id].value_table
|
371
|
+
newiid = tmpattr.value_table.keys.first
|
372
|
+
attrs[tmpattr.id].value_table[newiid] =
|
373
|
+
tmpattr.value_table[newiid]
|
374
|
+
else
|
375
|
+
attrs[tmpattr.id] = tmpattr
|
376
|
+
end
|
377
|
+
end
|
378
|
+
return attrs
|
379
|
+
end
|
380
|
+
|
381
|
+
#Use CLI to retreive the children of the current model.
|
382
|
+
#Returns an array of Model objects.
|
383
|
+
#
|
384
|
+
#If <tt>relation</tt> is set to a Relation or a relation
|
385
|
+
#name, only parents with the given relation will be
|
386
|
+
#retrieved.
|
387
|
+
def cli_get_children(relation=nil,session=nil)
|
388
|
+
models = Array.new
|
389
|
+
session = VNMSH.get_session(session)
|
390
|
+
model_output = session.show_children(self,relation)
|
391
|
+
model_output.each do |line|
|
392
|
+
models.push(Model.parse(line))
|
393
|
+
end
|
394
|
+
return models
|
395
|
+
end
|
396
|
+
|
397
|
+
#Use CLI to retreive the parents of the current model.
|
398
|
+
#Returns an array of Model objects.
|
399
|
+
#
|
400
|
+
#If <tt>relation</tt> is set to a Relation or a relation
|
401
|
+
#name, only parents with the given relation will be
|
402
|
+
#retrieved.
|
403
|
+
def cli_get_parents(relation=nil,session=nil)
|
404
|
+
models = Array.new
|
405
|
+
session = VNMSH.get_session(session)
|
406
|
+
model_output = session.show_parents(self,relation)
|
407
|
+
model_output.each do |line|
|
408
|
+
models.push(Model.parse(line))
|
409
|
+
end
|
410
|
+
return models
|
411
|
+
end
|
412
|
+
|
413
|
+
#Use CLI to retreive the watches of the current model.
|
414
|
+
#Returns an array of Watch objects.
|
415
|
+
def cli_get_watches(session=nil)
|
416
|
+
watches = Array.new
|
417
|
+
session = VNMSH.get_session(session)
|
418
|
+
watch_output = session.show_watch(self)
|
419
|
+
watch_output.each do |line|
|
420
|
+
watches.push(SpecTools::Watch.parse(line))
|
421
|
+
end
|
422
|
+
return watches
|
423
|
+
end
|
424
|
+
|
425
|
+
#Call cli_get_attrs and populate the current Model's attrs attribute.
|
426
|
+
#Takes the same arguments as cli_get_attrs
|
427
|
+
def cli_get_attrs!(filter=nil,enumerate=false,session=nil)
|
428
|
+
attrs = self.cli_get_attrs(filter,enumerate,session)
|
429
|
+
self.attrs = attrs
|
430
|
+
end
|
431
|
+
|
432
|
+
#Use CLI to destroy a model.
|
433
|
+
#<tt>model</tt> can be either a valid Model, or a model handle.
|
434
|
+
def self.cli_destroy(model,session=nil)
|
435
|
+
session = VNMSH.get_session(session)
|
436
|
+
session.destroy_model(model)
|
437
|
+
end
|
438
|
+
|
439
|
+
#Use CLI to destroy this model.
|
440
|
+
def cli_destroy(session=nil)
|
441
|
+
self.class.destroy(self.handle,session)
|
442
|
+
end
|
443
|
+
|
444
|
+
#Use CLI to create a new model by IP.
|
445
|
+
#
|
446
|
+
#Options:
|
447
|
+
#* <tt>ip</tt> - Required. The device's IP address.
|
448
|
+
#* <tt>community</tt> - Optional. The community string.
|
449
|
+
#* <tt>timeout</tt> - Optional. The device's timeout.
|
450
|
+
#* <tt>retries</tt> - Optional. The number of times to attempt to contact the device.
|
451
|
+
#* <tt>sdm</tt> - Optional. The address of the Secure Domain Connector.
|
452
|
+
#* <tt>landscape</tt> - Optional. The landscape to creat the device on.
|
453
|
+
#
|
454
|
+
def self.cli_discover(ip,community=nil,timeout=nil,retries=nil,sdm=nil,landscape=nil,session=nil)
|
455
|
+
session = VNMSH.get_session(session)
|
456
|
+
session.discover_device(ip,community,timeout,retries,sdm,landscape)
|
457
|
+
end
|
458
|
+
|
459
|
+
#Use CLI to create a new model.
|
460
|
+
#<tt>mtype</tt> may either be a valid MType object, or a model type handle.
|
461
|
+
#<tt>attrs</tt> is an array of Attr objects that you want to be set on the
|
462
|
+
#model when it is created.
|
463
|
+
def self.cli_create(mtype,attrs=nil,lh=nil,session=nil)
|
464
|
+
session = VNMSH.get_session(session)
|
465
|
+
return session.create_model(mtype,attrs,lh)
|
466
|
+
end
|
467
|
+
|
468
|
+
#Use CLI to update a model's attributes.
|
469
|
+
#
|
470
|
+
#<tt>attrs</tt> can be a single Attr object, or an array of Attr objects.
|
471
|
+
#
|
472
|
+
#If <tt>update_model</tt> is true , the attrs of the model will be updated, as well.
|
473
|
+
def cli_update_attrs(attrs,update_model = false,session=nil)
|
474
|
+
session = VNMSH.get_session(session)
|
475
|
+
result = session.update_model(self,attrs)
|
476
|
+
if result && update_model
|
477
|
+
attrs.each do |specattr|
|
478
|
+
self.attrs[specattr.id] = specattr
|
479
|
+
end
|
480
|
+
end
|
481
|
+
return result
|
482
|
+
end
|
483
|
+
|
484
|
+
#Use CLI to associate this model with another.
|
485
|
+
#<tt>position</tt> is either <b>:left</b> or <b>:right</b>, and indicates
|
486
|
+
#which side of this assocaition the current model will
|
487
|
+
#reside.
|
488
|
+
#The <tt>model</tt> argument may be a valid Model or a model handle.
|
489
|
+
#* Example: <tt>left_model.associate(:left,right_model,relation)</tt>
|
490
|
+
def cli_associate(position,model,relation,session = nil)
|
491
|
+
session = VNMSH.get_session(session)
|
492
|
+
if position == :left
|
493
|
+
return session.create_association(relation,self,model)
|
494
|
+
elsif position == :right
|
495
|
+
return session.create_association(relation,model,self)
|
496
|
+
else
|
497
|
+
raise ArgumentError, "Valid options are :left or :right"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
else
|
503
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
504
|
+
end
|
505
|
+
|
506
|
+
if defined?(SpecTools::Relation)
|
507
|
+
class SpecTools::Relation
|
508
|
+
#Take a line of CLI <tt>show relations</tt> output and populate a new Relation object.
|
509
|
+
def self.cli_parse(line)
|
510
|
+
name,type = line.chomp.unpack('A33A15')
|
511
|
+
rel = Relation.new(name,type)
|
512
|
+
return rel
|
513
|
+
end
|
514
|
+
|
515
|
+
#Use CLI to locate Reltions. Returns an array of Relation objects.
|
516
|
+
#
|
517
|
+
#If <tt>lanscape</tt> is set to a Landscape or a landscape handle,
|
518
|
+
#will only show relations for the given landscape.
|
519
|
+
def self.cli_find(landscape=nil,session=nil)
|
520
|
+
relations = Array.new
|
521
|
+
session = VNMSH.get_session(session)
|
522
|
+
rel_output = session.show_relations(landscape)
|
523
|
+
rel_output.each do |line|
|
524
|
+
relations.push(Relation.parse(line))
|
525
|
+
end
|
526
|
+
return relations
|
527
|
+
end
|
528
|
+
|
529
|
+
#Retrieve an Array of Rules for the given Relation.
|
530
|
+
#
|
531
|
+
#If <tt>lanscape</tt> is set to a Landscape or a landscape handle,
|
532
|
+
#will only show rules for the given landscape.
|
533
|
+
def cli_get_rules(landscape=nil,session=nil)
|
534
|
+
session = VNMSH.get_session(session)
|
535
|
+
rules = Array.new
|
536
|
+
rule_output = session.show_rules(self)
|
537
|
+
rule_output.each do |line|
|
538
|
+
rules.push(Rule.parse(line))
|
539
|
+
end
|
540
|
+
return rules
|
541
|
+
end
|
542
|
+
|
543
|
+
#Use CLI to create a new Association based on this Relation.
|
544
|
+
#Model arguments may be Model objects or model handles.
|
545
|
+
def cli_associate(left_model,right_model,session=nil)
|
546
|
+
session = VNMSH.get_session(session)
|
547
|
+
return session.create_association(self,left_model,right_model)
|
548
|
+
end
|
549
|
+
|
550
|
+
end
|
551
|
+
else
|
552
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
553
|
+
end
|
554
|
+
|
555
|
+
if defined?(SpecTools::Association)
|
556
|
+
class SpecTools::Association
|
557
|
+
#Take a line of CLI <tt>show associations</tt> output and populate a new Association object
|
558
|
+
def self.parse(line)
|
559
|
+
assoc = Association.new()
|
560
|
+
lmhandle,lmname,rel,rmhandle,rmname = line.chomp.unpack('A12A1025A33A12A1024')
|
561
|
+
assoc.left_model.handle = lmhandle
|
562
|
+
assoc.left_model.name = lmname
|
563
|
+
assoc.relation.name = rel
|
564
|
+
assoc.right_model.handle = rmhandle
|
565
|
+
assoc.right_model.name = rmname
|
566
|
+
return assoc
|
567
|
+
end
|
568
|
+
|
569
|
+
#Take a line of CLI <tt>show children</tt> output and populate a new Association object
|
570
|
+
def self.parse_child(line)
|
571
|
+
mhandle,mname,mthandle,mtname,rel = line.chomp.unpack('A12A1025A12A17A31')
|
572
|
+
mtype = MType.new(mthandle,mtname)
|
573
|
+
model = Model.new(mhandle,mname,mtype)
|
574
|
+
relation = Relation.new(rel)
|
575
|
+
assoc = Association.new(nil,model,relation)
|
576
|
+
return assoc
|
577
|
+
end
|
578
|
+
|
579
|
+
#Take a line of CLI <tt>show parents</tt> output and populate a new Association object
|
580
|
+
def self.parse_parent(line)
|
581
|
+
mhandle,mname,mthandle,mtname,rel = line.chomp.unpack('A12A1025A12A17A31')
|
582
|
+
mtype = MType.new(mthandle,mtname)
|
583
|
+
model = Model.new(mhandle,mname,mtype)
|
584
|
+
relation = Relation.new(rel)
|
585
|
+
assoc = Association.new(model,nil,relation)
|
586
|
+
return assoc
|
587
|
+
end
|
588
|
+
|
589
|
+
#Use CLI to destroy a given association.
|
590
|
+
#<tt>left_model</tt> and <tt>right_model</tt> may be Model objects or model handles.
|
591
|
+
#The <tt>relation</tt> argument may be a Relation or a valid relation name.
|
592
|
+
def self.cli_destroy(left_model,right_model,relation,session=nil)
|
593
|
+
session = VNMSH.get_session(session)
|
594
|
+
session.destroy_association(relation,left_model,right_model)
|
595
|
+
end
|
596
|
+
|
597
|
+
#Use CLI to destroy this association.
|
598
|
+
def cli_destroy(session=nil)
|
599
|
+
self.class.cli_destroy(left_model,right_model,relation,session)
|
600
|
+
end
|
601
|
+
|
602
|
+
#Use CLI to create a new Association
|
603
|
+
#<tt>left_model</tt> and <tt>right_model</tt> may be Model objects or model handles.
|
604
|
+
#The <tt>relation</tt> argument may be a Relation or a valid relation name.
|
605
|
+
def self.cli_create(relation,left_model,right_model,session = nil)
|
606
|
+
session = VNMSH.get_session(session)
|
607
|
+
return session.create_association(relation,left_model,right_model)
|
608
|
+
end
|
609
|
+
|
610
|
+
|
611
|
+
end
|
612
|
+
else
|
613
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
614
|
+
end
|
615
|
+
|
616
|
+
if defined?(SpecTools::Alarm)
|
617
|
+
class SpecTools::Alarm
|
618
|
+
#Take a line of CLI <tt>show</tt> output and populate a new Alarm object
|
619
|
+
def self.cli_parse(line)
|
620
|
+
alarm = Alarm.new
|
621
|
+
#OK, here we go. Unfortunately, we have no guidelines to parse this data. It doesn't tend to be fixed-width, and
|
622
|
+
#there are no delimteres for a good regex. So, here we have to mix the 2 as best we can.
|
623
|
+
#First, we can use a regex to grab out the first few fields.
|
624
|
+
line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/
|
625
|
+
alarm.id = $1
|
626
|
+
date = $2
|
627
|
+
time = $3
|
628
|
+
alarm.causeid = $4
|
629
|
+
alarm.model.handle = $5
|
630
|
+
rest = $6
|
631
|
+
month,day,year = date.split(/\//)
|
632
|
+
hour,min,sec = time.split(/:/)
|
633
|
+
alarm.time = Time.local(year,month,day,hour,min,sec)
|
634
|
+
#Alright, now we know that the model name is 1024 characters, so I can grab that with unpack
|
635
|
+
alarm.model.name,rest = rest.unpack('A1025A8192')
|
636
|
+
#Now, we have to use a regex to extract the model type name, as it will extend and not truncate.
|
637
|
+
#We're lucky that Model type names usually don't contain whitespace.
|
638
|
+
rest =~ /^(\S+)\s+(.*)$/
|
639
|
+
alarm.model.type.name = $1
|
640
|
+
rest = $2
|
641
|
+
#Now, whether we like it or not, we have to use unpack for the rest
|
642
|
+
alarm.severity,ack,stale,alarm.assignment,alarm.status = rest.unpack('A14A4A6A25A4096')
|
643
|
+
if ack =~ /Yes/
|
644
|
+
alarm.ack = true
|
645
|
+
end
|
646
|
+
if stale =~ /Yes/
|
647
|
+
alarm.stale = true
|
648
|
+
end
|
649
|
+
return alarm
|
650
|
+
end
|
651
|
+
|
652
|
+
#Use CLI to find Alarms. Returns an array of Alarm objects.
|
653
|
+
#Available find types:
|
654
|
+
#* <tt>:standard</tt> - Retrieves the standard list of alarms.
|
655
|
+
#* <tt>:all</tt> - Retrieves all alarms, including MAINTENANCE.
|
656
|
+
#* <tt>:model</tt> - Retrieves standard alarms for a given model.
|
657
|
+
# * If set, <tt>mh_or_lh</tt> must be a valid Model or model handle.
|
658
|
+
#* <tt>:model</tt> - Identical to :model, except returns all alarms.
|
659
|
+
#* <tt>:landscape</tt> - Retrieves standards alarms for a given landscape.
|
660
|
+
# * If set, <tt>mh_or_lh</tt> must be a valid Landscape or landscape handle.
|
661
|
+
#
|
662
|
+
#Setting <tt>probcause</tt> to true will include the Probable Cause
|
663
|
+
#information in the <tt>message</tt> attribute of each Alarm.
|
664
|
+
def self.cli_find(type=:standard,mh_or_lh=nil,probcause=false,session=nil)
|
665
|
+
session = VNMSH.get_session(session)
|
666
|
+
alarms = Array.new
|
667
|
+
alarm_output = session.show_alarms(type,mh_or_lh,probcause)
|
668
|
+
causes = Hash.new
|
669
|
+
alarm_output.each do |line|
|
670
|
+
if line =~ /\d+\s+\d\d\/\d\d\/\d\d\d\d/
|
671
|
+
alarms.push(Alarm.parse(line))
|
672
|
+
elsif line =~ /^(0x[a-fA-F0-9]+)\s/
|
673
|
+
causeid = $1
|
674
|
+
causes[causeid] = line.sub(/^(0x[a-fA-F0-9]+)\s/,"")
|
675
|
+
end
|
676
|
+
end
|
677
|
+
if probcause
|
678
|
+
alarms.each do |alarm|
|
679
|
+
alarm.message = causes[alarm.causeid]
|
680
|
+
end
|
681
|
+
end
|
682
|
+
return alarms
|
683
|
+
end
|
684
|
+
|
685
|
+
#Use CLI to destroy an alarm.
|
686
|
+
def self.cli_destroy(aid,landscape=nil,session=nil)
|
687
|
+
session = VNMSH.get_session(session)
|
688
|
+
session.destroy_alarm(aid,landscape)
|
689
|
+
end
|
690
|
+
|
691
|
+
#Use CLI to destroy this alarm.
|
692
|
+
def cli_destroy(landscape=nil,session=nil)
|
693
|
+
self.class.cli_destroy(id,landscape,session)
|
694
|
+
end
|
695
|
+
|
696
|
+
#Use CLI to save all attributes of this alarm.
|
697
|
+
def cli_save(session=nil)
|
698
|
+
session = VNMSH.get_session(session)
|
699
|
+
result = true
|
700
|
+
result = session.update_alarm(id, :ticket, ticket, true) && result if ticket != nil
|
701
|
+
result = session.update_alarm(id, :assign, assignment, true) && result if assignment != nil
|
702
|
+
result = session.update_alarm(id, :status, status, true) && result if status != nil
|
703
|
+
result = session.update_alarm(id, :ack, ack) && result if ack != nil
|
704
|
+
result = session.update_alarm(id, :url, url, true) && result if url != nil
|
705
|
+
result
|
706
|
+
end
|
707
|
+
|
708
|
+
end
|
709
|
+
else
|
710
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
711
|
+
end
|
712
|
+
|
713
|
+
if defined?(SpecTools::Event)
|
714
|
+
class SpecTools::Event
|
715
|
+
#Take a line of CLI <tt>show</tt> output and populate a new Event object.
|
716
|
+
def self.cli_parse(line)
|
717
|
+
event = Event.new
|
718
|
+
date,time,type,mhandle,mname,mtname,evformat = line.chomp.unpack('A10A12A12A12A1025A15A4096')
|
719
|
+
month,day,year = date.split(/\//)
|
720
|
+
hour,min,sec = time.split(/:/)
|
721
|
+
event.time = Time.local(year,month,day,hour,min,sec)
|
722
|
+
event.type = type
|
723
|
+
event.model.handle = mhandle
|
724
|
+
event.model.name = mname
|
725
|
+
event.model.type.name = mtname
|
726
|
+
return event
|
727
|
+
end
|
728
|
+
|
729
|
+
#Use CLI to find Events. Returns an array of Event objects. Available find types:
|
730
|
+
#* <tt>:all</tt> - Retrieve all events.
|
731
|
+
#* <tt>:model</tt> - Retrieve all events for a given model.
|
732
|
+
# * If set, mh_or_lh must be a valid Model or a model handle.
|
733
|
+
#* <tt>:landscape</tt> - Retrieve all events for a given landscape.
|
734
|
+
# * If set, mh_or_lh must be a valid Landscape or a landscape handle.
|
735
|
+
#Options:
|
736
|
+
#* <tt>limit</tt> - Set the maximum number of events to retrieve.
|
737
|
+
# * Default is 2000, Setting to :all is equivalent to setting to 10000
|
738
|
+
#* <tt>evformat</tt> - If set to true, populate the Events with the event message.
|
739
|
+
def self.cli_find(type=:all,mh_or_lh=nil,limit=2000,evformat=false,session=nil)
|
740
|
+
session = VNMSH.get_session(session)
|
741
|
+
events = Array.new
|
742
|
+
event_output = session.show_events(type,mh_or_lh,limit,evformat)
|
743
|
+
event_output.each do |line|
|
744
|
+
if line =~ /^\d\d\/\d\d\/\d\d\d\d/
|
745
|
+
events.push(Event.parse(line))
|
746
|
+
else
|
747
|
+
events.last.message = events.last.message + line
|
748
|
+
end
|
749
|
+
end
|
750
|
+
return events
|
751
|
+
|
752
|
+
end
|
753
|
+
end
|
754
|
+
else
|
755
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
756
|
+
end
|
757
|
+
|
758
|
+
if defined?(SpecTools::Rule)
|
759
|
+
class SpecTools::Rule
|
760
|
+
#Take a line of CLI <tt>show rules</tt> output and populate a new Rule object.
|
761
|
+
def self.cli_parse(line)
|
762
|
+
line.chomp =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$/
|
763
|
+
#lmthandle,lmtname,rmthandle,rmtname = line.chomp.unpack('A12A18A12A18')
|
764
|
+
lmthandle = $1
|
765
|
+
lmtname = $2
|
766
|
+
rmthandle = $3
|
767
|
+
rmtname = $4
|
768
|
+
lmtype = MType.new(lmthandle,lmtname)
|
769
|
+
rmtype = MType.new(rmthandle,rmtname)
|
770
|
+
rule = Rule.new(lmtype,rmtype)
|
771
|
+
return rule
|
772
|
+
end
|
773
|
+
end
|
774
|
+
else
|
775
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
776
|
+
end
|
777
|
+
|
778
|
+
if defined?(SpecTools::Watch)
|
779
|
+
class SpecTools::Watch
|
780
|
+
#Take a line of CLI <tt>show watch</tt> output and populate a new Watch object.
|
781
|
+
def self.cli_parse(line)
|
782
|
+
id,name,type,status = line.chomp.unpack('A11A33A17A10')
|
783
|
+
watch = Watch.new(id,name,type,status)
|
784
|
+
return watch
|
785
|
+
end
|
786
|
+
end
|
787
|
+
else
|
788
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
789
|
+
end
|
790
|
+
|
791
|
+
if defined?(SpecTools::Landscape)
|
792
|
+
class SpecTools::Landscape
|
793
|
+
#Take a line of CLI <tt>show landscapes</tt> output and populate a new Landscape object.
|
794
|
+
def self.cli_parse(line)
|
795
|
+
ssname,precedence,port,service,handle = line.chomp.unpack('A33A14A8A12A10')
|
796
|
+
landscape = Landscape.new(handle,ssname,precedence,port,service )
|
797
|
+
return landscape
|
798
|
+
end
|
799
|
+
|
800
|
+
#Use CLI to retrieve all available landscapes.
|
801
|
+
def self.cli_get_landscapes(session=nil)
|
802
|
+
session = VNMSH.get_session(session)
|
803
|
+
landscapes = Array.new
|
804
|
+
lscape_output = session.show_landscapes
|
805
|
+
lscape_output.each do |line|
|
806
|
+
landscapes.push(Landscape.parse(line))
|
807
|
+
end
|
808
|
+
return landscapes
|
809
|
+
end
|
810
|
+
end
|
811
|
+
else
|
812
|
+
raise NameError, 'You must require the spectools lib in order to use VNMSH'
|
813
|
+
end
|
814
|
+
|
815
|
+
# == SpecTools::VNMSH
|
816
|
+
# Represents a CLI session to VNMSH
|
817
|
+
class VNMSH
|
818
|
+
|
819
|
+
#The ID of the connected session.
|
820
|
+
attr_reader :session_id
|
821
|
+
#The currently connected landscape.
|
822
|
+
attr_reader :current_landscape
|
823
|
+
#The number of reconncects performed before a command is considered unsuccessful.
|
824
|
+
attr_accessor :reconnect_retries
|
825
|
+
|
826
|
+
class << self
|
827
|
+
#The default session to use to execute VNMSH commands.
|
828
|
+
attr_accessor :default_session
|
829
|
+
end
|
830
|
+
|
831
|
+
#Create a new VNMSH session. <tt>specroot</tt> is accessed from the SPECROOT
|
832
|
+
#environement variable, if no <tt>specroot</tt> is passed.
|
833
|
+
def initialize(specroot = nil)
|
834
|
+
@vnmshdir = '/vnmsh/'
|
835
|
+
vnmshcommands = ['ack','connect','create','destroy','disconnect','seek','show','update']
|
836
|
+
if specroot.nil?
|
837
|
+
@specroot = ENV['SPECROOT']
|
838
|
+
else
|
839
|
+
@specroot = specroot
|
840
|
+
end
|
841
|
+
vnmshcommands.each do |vnmshcommand|
|
842
|
+
command = @specroot + @vnmshdir + vnmshcommand
|
843
|
+
unless File.exists?(command)
|
844
|
+
raise EnvironmentError, "Command #{command} is not available"
|
845
|
+
end
|
846
|
+
end
|
847
|
+
@session_id = rand(20000)
|
848
|
+
@connected = false
|
849
|
+
@reconnect_retries = 3
|
850
|
+
end
|
851
|
+
|
852
|
+
#Take a parameter check to see if either the session was explictly passed,
|
853
|
+
#or if SpecTools::VNMSH#default_session is set.
|
854
|
+
#Returns a valid VNMSH object if successful.
|
855
|
+
#Raises ArgumentError if no valid VNMSH session is found.
|
856
|
+
def self.get_session(arg)
|
857
|
+
if arg.instance_of? VNMSH
|
858
|
+
return arg
|
859
|
+
elsif VNMSH::default_session.instance_of? VNMSH
|
860
|
+
return VNMSH::default_session
|
861
|
+
else
|
862
|
+
raise ArgumentError, 'You must pass a valid session or set SpecTools::VNMSH.default_session to a valid session'
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
|
867
|
+
#Connect to the SpectroSERVER
|
868
|
+
#If successful, returns a Landscape object indicating what landscape we connected to.
|
869
|
+
#Returns a ConnectError if it fails
|
870
|
+
def connect(ss = nil, landscape = nil)
|
871
|
+
connectcmd = @specroot + '/vnmsh/connect '
|
872
|
+
unless ss.nil?
|
873
|
+
connectcmd = connectcmd + ss
|
874
|
+
end
|
875
|
+
connectcmd = connectcmd + ' 2>&1'
|
876
|
+
output = StringIO.new(`#{connectcmd}`)
|
877
|
+
result = output.readline
|
878
|
+
if result =~ /^connect: successful (.*)/
|
879
|
+
@current_landscape = Landscape.new()
|
880
|
+
@current_landscape.ss = $1
|
881
|
+
output.readline =~ /current landscape is (0x\d+)/
|
882
|
+
@current_landscape.handle = $1
|
883
|
+
@connected = true
|
884
|
+
return @current_landscape
|
885
|
+
elsif result =~ /^connect: already connected to/
|
886
|
+
return @current_landscape
|
887
|
+
else
|
888
|
+
raise ConnectError, result
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
#Disconnect from the SS. Returns true if the command succeeds,
|
893
|
+
#otherwise returns the error string of the disconnect.
|
894
|
+
#Either way, session will be marked as disconnected.
|
895
|
+
def disconnect
|
896
|
+
disconnectcmd = @specroot + '/vnmsh/disconnect 2>&1'
|
897
|
+
output = StringIO.new(`#{disconnectcmd}`)
|
898
|
+
@connected = false
|
899
|
+
result = output.readline
|
900
|
+
if result =~ /^disconnect: successful/
|
901
|
+
return true
|
902
|
+
else
|
903
|
+
return result
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
#Execute a VNMSH command.
|
908
|
+
#Returns a StringIO object with the command's output.
|
909
|
+
#Raises a NotConnectedError if the command exceeds
|
910
|
+
#<tt>reconnect_retries</tt>.
|
911
|
+
def exec_cmd(cmd)
|
912
|
+
@retries = 0
|
913
|
+
unless self.connected?
|
914
|
+
raise NotConnectedError
|
915
|
+
end
|
916
|
+
cmd = @specroot + '/vnmsh/' + cmd + ' 2>&1'
|
917
|
+
ENV['CLIMNAMEWIDTH'] = 1024.to_s
|
918
|
+
ENV['CLISESSID'] = self.session_id.to_s
|
919
|
+
begin
|
920
|
+
output = `#{cmd}`
|
921
|
+
if $?.exitstatus > 0 && StringIO.new(output).readline =~ /Please connect first/
|
922
|
+
raise NotConnectedError
|
923
|
+
else
|
924
|
+
return StringIO.new(output)
|
925
|
+
end
|
926
|
+
rescue NotConnectedError
|
927
|
+
@retries = @retries + 1
|
928
|
+
unless @retries > self.reconnect_retries
|
929
|
+
self.disconnect
|
930
|
+
self.connect
|
931
|
+
retry
|
932
|
+
else
|
933
|
+
raise
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
end
|
938
|
+
|
939
|
+
|
940
|
+
|
941
|
+
#Returns true if the session is currently connceted to a SpectroSERVER.
|
942
|
+
def connected?
|
943
|
+
return @connected
|
944
|
+
end
|
945
|
+
|
946
|
+
#Check to see if the show response returned invalid model or landscape handle.
|
947
|
+
def show_invalid_mh_or_lh?(result)
|
948
|
+
if result =~ /invalid model handle/
|
949
|
+
raise CommandError, result
|
950
|
+
elsif result =~ /invalid landscape handle/
|
951
|
+
raise CommandError, result
|
952
|
+
elsif result =~ /no current model defined/
|
953
|
+
raise CommandError, result
|
954
|
+
end
|
955
|
+
end
|
956
|
+
|
957
|
+
|
958
|
+
|
959
|
+
#Execute the <tt>show alarms</tt> command.
|
960
|
+
#
|
961
|
+
#Available show types:
|
962
|
+
#* <tt>:standard</tt> - Retrieves the standard list of alarms.
|
963
|
+
#* <tt>:all</tt> - Retrieves all alarms, including MAINTENANCE.
|
964
|
+
#* <tt>:model</tt> - Retrieves standard alarms for a given model.
|
965
|
+
# * If set, <tt>mh_or_lh</tt> must be a valid Model or model handle.
|
966
|
+
#* <tt>:model</tt> - Identical to :model, except returns all alarms.
|
967
|
+
#* <tt>:landscape</tt> - Retrieves standards alarms for a given landscape.
|
968
|
+
# * If set, <tt>mh_or_lh</tt> must be a valid Landscape or landscape handle.
|
969
|
+
#
|
970
|
+
#Setting <tt>probcause</tt> to true will include the Probable Cause
|
971
|
+
#information in the <tt>message</tt> attribute of each Alarm.
|
972
|
+
#
|
973
|
+
#Returns a StringIO with the command's ouput.
|
974
|
+
def show_alarms(type=:standard,mh_or_lh=nil,probcause=false)
|
975
|
+
valid_types = [ :standard,
|
976
|
+
:model,
|
977
|
+
:model_all,
|
978
|
+
:landscape,
|
979
|
+
:landscape_all,
|
980
|
+
:all ]
|
981
|
+
showcmd = 'show alarms '
|
982
|
+
valid_type = false
|
983
|
+
valid_types.each do |v_type|
|
984
|
+
valid_type = v_type || valid_type
|
985
|
+
end
|
986
|
+
|
987
|
+
raise ArgumentError, 'Valid show types are :standard, :all,
|
988
|
+
:model, :model_all, :landscape, or :landscape_all' unless valid_type
|
989
|
+
|
990
|
+
if type == :all || type == :model_all || type == :landscape_all
|
991
|
+
showcmd = showcmd + ' -a '
|
992
|
+
end
|
993
|
+
showcmd = showcmd + ' -x ' if probcause
|
994
|
+
if type == :model_all || type == :model
|
995
|
+
showcmd += ' mh='
|
996
|
+
showcmd = showcmd + get_handle(mh_or_lh,Model)
|
997
|
+
end
|
998
|
+
if type == :landscape_all || type == :landscape
|
999
|
+
showcmd += ' lh='
|
1000
|
+
showcmd = showcmd + get_handle(mh_or_lh,Landscape)
|
1001
|
+
end
|
1002
|
+
output = exec_cmd(showcmd)
|
1003
|
+
result = output.readline
|
1004
|
+
show_invalid_mh_or_lh?(result)
|
1005
|
+
if result =~ /^ID\s+/
|
1006
|
+
return output
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
#Execute the <tt>show models</tt> command.
|
1011
|
+
#
|
1012
|
+
#If no filter is passed, returns all model listings for the connected Landscape.
|
1013
|
+
#
|
1014
|
+
#Filter options:
|
1015
|
+
#
|
1016
|
+
#* <tt>:range</tt> - filters on a range of models.
|
1017
|
+
# * Range can either be a single string, an Array of handles, or an Array of Models.
|
1018
|
+
# * Example: <tt>show_models({:range,'0x400000-0x500000'})</tt>
|
1019
|
+
# * Example: <tt>show_models(:range,['0x400000','0x500000']})</tt>
|
1020
|
+
#* <tt>:name</tt> - filters on the model's name (partials accepted)
|
1021
|
+
# * Example: <tt>show_models{:name,'VNM'})</tt>
|
1022
|
+
#* <tt>:landscape</tt> - filters on the given Landscape.
|
1023
|
+
# * Example: <tt>show_models({:landscape,'0x400000'})</tt>
|
1024
|
+
#* <tt>:mtype</tt> - Returns all models of the specified type.
|
1025
|
+
# * Type can either be an MType object, or a model type handle.
|
1026
|
+
# * Examples:
|
1027
|
+
# * <tt>show_models(:mtype, '0x13d0018')</tt>
|
1028
|
+
# * <tt>show_models(:mtype, MType.new('0x13d0018'))</tt>
|
1029
|
+
#
|
1030
|
+
#Returns a StringIO with the command's ouput.
|
1031
|
+
#
|
1032
|
+
def show_models(filter=nil)
|
1033
|
+
showcmd = 'show models '
|
1034
|
+
if filter
|
1035
|
+
filter.keys.each do |option|
|
1036
|
+
case option
|
1037
|
+
when :range
|
1038
|
+
showcmd += ' mhr='
|
1039
|
+
showcmd += filter[option] if filter[option].kind_of?(String)
|
1040
|
+
showcmd += get_handle(filter[option][0],Model) + '-' +
|
1041
|
+
get_handle(filter[option][1],Model) if filter[option].kind_of?(Array)
|
1042
|
+
when :type
|
1043
|
+
showcmd += ' mth=' + get_handle(filter[option],MType)
|
1044
|
+
when :name
|
1045
|
+
showcmd += ' mname=' + filter[option]
|
1046
|
+
when :landscape
|
1047
|
+
showcmd += ' lh=' + get_handle(filter[option],Landscape)
|
1048
|
+
else
|
1049
|
+
raise ArgumentError, 'Valid filter options are :range, :name, :flag, or :landscape'
|
1050
|
+
end
|
1051
|
+
end
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
output = self.exec_cmd(showcmd)
|
1055
|
+
result = output.readline
|
1056
|
+
show_invalid_mh_or_lh?(result)
|
1057
|
+
if result =~ /MHandle\s+/
|
1058
|
+
return output
|
1059
|
+
end
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
#Execute <tt>seek</tt>.
|
1063
|
+
#
|
1064
|
+
#<tt>specattr</tt> may be an Attr object or an attribute ID.
|
1065
|
+
#If <tt>specattr</tt> is an Attr and has the value attribute set,
|
1066
|
+
#<tt>value</tt> does not have to be set. However, you can override
|
1067
|
+
#the Attr object's value in the search by providing your own
|
1068
|
+
#<tt>value</tt>.
|
1069
|
+
#
|
1070
|
+
#If <tt>specattr.value</tt> is nil, or of <tt>specattr</tt> is simply
|
1071
|
+
#an attribute ID, <tt>value</tt> must be set.
|
1072
|
+
#
|
1073
|
+
#If <tt>substring</tt> is true, a partial string match is performed.
|
1074
|
+
#
|
1075
|
+
#If <tt>nocase</tt> is true, case is ignored.
|
1076
|
+
#
|
1077
|
+
#Returns a StringIO with the command's ouput.
|
1078
|
+
def seek(specattr,value=nil,substring=false,nocase=false,landscape=nil)
|
1079
|
+
seekcmd = 'seek'
|
1080
|
+
seekcmd += ' -s' if substring
|
1081
|
+
seekcmd += ' -i' if nocase
|
1082
|
+
seekcmd += ' attr=' + get_id(specattr,Attr)
|
1083
|
+
if specattr.kind_of?(Attr)
|
1084
|
+
value = specattr.value unless value
|
1085
|
+
end
|
1086
|
+
raise ArgumentError, 'When seeking by attribute, must pass in a SpecTools::Attr
|
1087
|
+
with a valid value, or an explict attribute value' unless value
|
1088
|
+
seekcmd += ',val="' + value + '"'
|
1089
|
+
seekcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1090
|
+
output = exec_cmd(seekcmd)
|
1091
|
+
result = output.readline
|
1092
|
+
if result =~ /^MHandle\s+/
|
1093
|
+
return output
|
1094
|
+
else
|
1095
|
+
raise CommandError, result
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
|
1101
|
+
|
1102
|
+
#Execute <tt>show devices</tt>
|
1103
|
+
#
|
1104
|
+
#If <tt>landscape</tt> is set, only devices for the
|
1105
|
+
#given landscape are gathered.
|
1106
|
+
#
|
1107
|
+
#Returns a StringIO with the command's ouput.
|
1108
|
+
def show_devices(landscape = nil)
|
1109
|
+
showcmd = 'show devices '
|
1110
|
+
showcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1111
|
+
output = self.exec_cmd(showcmd)
|
1112
|
+
result = output.readline
|
1113
|
+
show_invalid_mh_or_lh?(result)
|
1114
|
+
if result =~ /MHandle\s+/
|
1115
|
+
return output
|
1116
|
+
end
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
#Execute <tt>show types</tt>
|
1120
|
+
#
|
1121
|
+
#<tt>filter</tt> is a hash of filter types and thier values.
|
1122
|
+
#
|
1123
|
+
#If no filter is passed, returns all model type listings
|
1124
|
+
#for the connected Landscape.
|
1125
|
+
#Filter options:
|
1126
|
+
#
|
1127
|
+
#* <tt>:flag</tt> - filters on the provided flag
|
1128
|
+
# * Example: <tt>show_types({:flag,:unique})</tt>
|
1129
|
+
#* <tt>:range</tt> - filters on a range of model types
|
1130
|
+
# * Range can either be a single string, an Array of handles, or an Array of MTypes.
|
1131
|
+
# * Example: <tt>show_types({:range,'0x400000-0x500000'})</tt>
|
1132
|
+
# * Example: <tt>show_types(:range,['0x400000','0x500000']})</tt>
|
1133
|
+
#* <tt>:name</tt> - filters on the model type's name (partials accepted)
|
1134
|
+
# * Example: <tt>show_types({:name,'VNM'})</tt>
|
1135
|
+
#* <tt>:landscape</tt> - filters on the given Landscape.
|
1136
|
+
# * Example: <tt>show_types({:landscape,'0x400000'})</tt>
|
1137
|
+
#
|
1138
|
+
#Returns a StringIO with the command's ouput.
|
1139
|
+
def show_types(filter=nil)
|
1140
|
+
showcmd = 'show types '
|
1141
|
+
if filter
|
1142
|
+
filter.keys.each do |option|
|
1143
|
+
case option
|
1144
|
+
when :range
|
1145
|
+
showcmd += ' mthr='
|
1146
|
+
showcmd += filter[option] if filter[option].kind_of?(String)
|
1147
|
+
showcmd += get_handle(filter[option][0],MType) + '-' +
|
1148
|
+
get_handle(filter[option][1],MType) if filter[option].kind_of?(Array)
|
1149
|
+
|
1150
|
+
when :name
|
1151
|
+
showcmd += ' mtname=' + filter[option]
|
1152
|
+
when :flag
|
1153
|
+
showcmd += ' flags=' + filter[option]
|
1154
|
+
when :landscape
|
1155
|
+
showcmd += ' lh=' + get_handle(filter[option],Landscape)
|
1156
|
+
else
|
1157
|
+
raise ArgumentError, 'Valid filter options are :range, :name, :flag, or :landscape'
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
end
|
1161
|
+
output = self.exec_cmd(showcmd)
|
1162
|
+
result = output.readline
|
1163
|
+
show_invalid_mh_or_lh?(result)
|
1164
|
+
if result =~ /Handle\s+/
|
1165
|
+
return output
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
#Execute <tt>show relations</tt>
|
1170
|
+
#
|
1171
|
+
#If <tt>landscape</tt> is set to a Landscape or a ladnscape handle,
|
1172
|
+
#shows relations for the given <tt>landscape</tt>.
|
1173
|
+
#
|
1174
|
+
#Returns a StringIO with the command's ouput.
|
1175
|
+
def show_relations(landscape=nil)
|
1176
|
+
showcmd = 'show relations '
|
1177
|
+
showcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1178
|
+
output = self.exec_cmd(showcmd)
|
1179
|
+
result = output.readline
|
1180
|
+
show_invalid_mh_or_lh?(result)
|
1181
|
+
if result =~ /Name\s+/
|
1182
|
+
return output
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
#Execute <tt>show associations</tt>.
|
1187
|
+
#
|
1188
|
+
#<tt>mh</tt> can be either a Model, or a model handle.
|
1189
|
+
#
|
1190
|
+
#Returns a StringIO with the command's ouput.
|
1191
|
+
def show_associations(mh)
|
1192
|
+
showcmd = 'show associations ' + mh
|
1193
|
+
output = self.exec_cmd(showcmd)
|
1194
|
+
result = output.readline
|
1195
|
+
show_invalid_mh_or_lh?(result)
|
1196
|
+
if result =~ /^LMHandle\s+/
|
1197
|
+
return output
|
1198
|
+
end
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
#Execute <tt>show parents</tt>.
|
1202
|
+
#
|
1203
|
+
#<tt>model</tt> can be a Model or a model handle.
|
1204
|
+
#If <tt>relation</tt> is set to a Relation or a relation
|
1205
|
+
#name, only parents with the given relation will be
|
1206
|
+
#retrieved.
|
1207
|
+
#
|
1208
|
+
#Returns a StringIO with the command's ouput.
|
1209
|
+
def show_parents(model,relation=nil)
|
1210
|
+
showcmd = 'show parents '
|
1211
|
+
showcmd += ' rel=' + get_relation(relation) if relation
|
1212
|
+
showcmd += ' mh=' + get_handle(model,Model)
|
1213
|
+
output = self.exec_cmd(showcmd)
|
1214
|
+
result = output.readline
|
1215
|
+
show_invalid_mh_or_lh?(result)
|
1216
|
+
if result =~ /^MHandle\s+/
|
1217
|
+
return output
|
1218
|
+
elsif result =~ /invalid relation/
|
1219
|
+
raise CommandError, result
|
1220
|
+
end
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
|
1224
|
+
#Execute <tt>show children</tt>
|
1225
|
+
#
|
1226
|
+
#<tt>model</tt> can be a Model or a model handle.
|
1227
|
+
#If <tt>relation</tt> is set to a Relation or a relation
|
1228
|
+
#name, only parents with the given relation will be
|
1229
|
+
#retrieved.
|
1230
|
+
#
|
1231
|
+
#Returns a StringIO with the command's ouput.
|
1232
|
+
def show_children(model,relation=nil)
|
1233
|
+
showcmd = 'show children '
|
1234
|
+
showcmd += ' rel=' + get_relation(relation) if relation
|
1235
|
+
showcmd += ' mh=' + get_handle(model,Model)
|
1236
|
+
output = self.exec_cmd(showcmd)
|
1237
|
+
result = output.readline
|
1238
|
+
show_invalid_mh_or_lh?(result)
|
1239
|
+
if result =~ /^MHandle\s+/
|
1240
|
+
return output
|
1241
|
+
elsif result =~ /invalid relation/
|
1242
|
+
raise CommandError, result
|
1243
|
+
end
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
#Execute <tt>show events</tt>
|
1247
|
+
#
|
1248
|
+
#Available types:
|
1249
|
+
#* <tt>:all</tt> - Retrieve all events.
|
1250
|
+
#* <tt>:model</tt> - Retrieve all events for a given model.
|
1251
|
+
# * If set, mh_or_lh must be a valid Model or a model handle.
|
1252
|
+
#* <tt>:landscape</tt> - Retrieve all events for a given landscape.
|
1253
|
+
# * If set, mh_or_lh must be a valid Landscape or a landscape handle.
|
1254
|
+
#Options:
|
1255
|
+
#* <tt>limit</tt> - Set the maximum number of events to retrieve.
|
1256
|
+
# * Default is 2000, Setting to :all is equivalent to setting to 10000
|
1257
|
+
#* <tt>evformat</tt> - If set to true, populate the Events with the event message.
|
1258
|
+
#
|
1259
|
+
#Returns a StringIO with the command's ouput.
|
1260
|
+
def show_events(type=:all,mh_or_lh=nil,limit=2000,evformat=false)
|
1261
|
+
showcmd = 'show events '
|
1262
|
+
if limit == :all
|
1263
|
+
showcmd += ' -a '
|
1264
|
+
elsif limit != 2000 && limit
|
1265
|
+
showcmd += ' -n ' + limit.to_s
|
1266
|
+
end
|
1267
|
+
if evformat
|
1268
|
+
showcmd += ' -x '
|
1269
|
+
end
|
1270
|
+
if type == :model
|
1271
|
+
showcmd += ' mh=' + get_handle(mh_or_lh,Model)
|
1272
|
+
end
|
1273
|
+
if type == :landscape
|
1274
|
+
showcmd += ' lh=' + get_handle(mh_or_lh,Landscape)
|
1275
|
+
end
|
1276
|
+
output = self.exec_cmd(showcmd)
|
1277
|
+
result = output.readline
|
1278
|
+
show_invalid_mh_or_lh?(result)
|
1279
|
+
if result =~ /^Date\s+/
|
1280
|
+
return output
|
1281
|
+
end
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
#Execute <tt>show inheritance</tt>
|
1285
|
+
#
|
1286
|
+
#<tt>mtype</tt> can be an MType or a model type handle.
|
1287
|
+
#If <tt>landscape</tt> is set, only gethers inheritance for
|
1288
|
+
#the given landscape.
|
1289
|
+
#
|
1290
|
+
#Returns a StringIO with the command's ouput.
|
1291
|
+
def show_inheritance(mtype,landscape = nil)
|
1292
|
+
showcmd = 'show inheritance mth=' + get_handle(mtype,MType)
|
1293
|
+
showcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1294
|
+
output = self.exec_cmd(showcmd)
|
1295
|
+
result = output.readline
|
1296
|
+
show_invalid_mh_or_lh?(result)
|
1297
|
+
if result =~ /^Handle\s+/
|
1298
|
+
return output
|
1299
|
+
elsif result =~ /invalid model type handle/
|
1300
|
+
raise CommandError, result
|
1301
|
+
end
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
#Execute <tt>show rules</tt>
|
1305
|
+
#
|
1306
|
+
#<tt>relation</tt> can be wither a Relation or a relation name.
|
1307
|
+
#If <tt>lanscape</tt> is set to a Landscape or a landscape handle,
|
1308
|
+
#will only show rules for the given landscape.
|
1309
|
+
#
|
1310
|
+
#Returns a StringIO with the command's ouput.
|
1311
|
+
def show_rules(relation,landscape = nil)
|
1312
|
+
showcmd = 'show rules rel=' + get_relation(relation)
|
1313
|
+
showcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1314
|
+
output = self.exec_cmd(showcmd)
|
1315
|
+
result = output.readline
|
1316
|
+
show_invalid_mh_or_lh?(result)
|
1317
|
+
if result =~ /^LMTHandle\s+/
|
1318
|
+
return output
|
1319
|
+
elsif result =~ /invalid relation/
|
1320
|
+
raise CommandError, result
|
1321
|
+
end
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
#Execute <tt>show enumerations</tt>
|
1325
|
+
#
|
1326
|
+
#Available types are:
|
1327
|
+
#
|
1328
|
+
#* <b>:mtype</b> - enumerations by model type.
|
1329
|
+
# * When set, <tt>mtype_landscape_attr</tt> must be a valid MType or a model type handle.
|
1330
|
+
# * May also specify an optional <tt>landscape</tt>, which can be either a Landscape or a landscape handle.
|
1331
|
+
#* <b>:landscape</b> - all enumerations for a specific landscape.
|
1332
|
+
# * When set, <tt>mtype_landscape_attr</tt> must be a valid Landscape or landscape handle.
|
1333
|
+
#* <b>:attr</b> - enumerations for a spceific attribute.
|
1334
|
+
# * When set, <tt>mtype_landscape_attr</tt> must be an Attr or an attribute id.
|
1335
|
+
#
|
1336
|
+
#Returns a StringIO with the command's ouput.
|
1337
|
+
def show_enumerations(type=:all,mtype_landscape_attr=nil,landscape=nil)
|
1338
|
+
showcmd = 'show enumerations '
|
1339
|
+
case type
|
1340
|
+
when :mtype
|
1341
|
+
showcmd += ' mth=' + get_handle(mtype_landscape_attr,MType)
|
1342
|
+
showcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1343
|
+
when :landscape
|
1344
|
+
showcmd += ' lh=' + get_handle(mtype_landscape_attr,Landscape)
|
1345
|
+
when :attr
|
1346
|
+
showcmd += ' attr=' + get_id(mtype_landscape_attr,Attr)
|
1347
|
+
end
|
1348
|
+
output = self.exec_cmd(showcmd)
|
1349
|
+
result = output.readline
|
1350
|
+
show_invalid_mh_or_lh?(result)
|
1351
|
+
if result =~ /Id\s+/
|
1352
|
+
return output
|
1353
|
+
elsif result =~ /invalid attribute/
|
1354
|
+
raise CommandError, result
|
1355
|
+
elsif result =~ /invalid model type handle/
|
1356
|
+
raise CommandError, result
|
1357
|
+
end
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
#Execute <tt>show watch</tt>
|
1361
|
+
#
|
1362
|
+
#<tt>model</tt> can either be a Model or a model handle.
|
1363
|
+
#
|
1364
|
+
#Returns a StringIO with the command's ouput.
|
1365
|
+
def show_watch(model)
|
1366
|
+
showcmd = 'show watch '
|
1367
|
+
showcmd += ' mh=' + get_handle(model,Model)
|
1368
|
+
output = self.exec_cmd(showcmd)
|
1369
|
+
result = output.readline
|
1370
|
+
show_invalid_mh_or_lh?(result)
|
1371
|
+
if result =~ /^Watch_Id\s+/
|
1372
|
+
return output
|
1373
|
+
end
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
#Execute <tt>show landscapes</tt>
|
1377
|
+
#
|
1378
|
+
#Returns a StringIO with the command's ouput.
|
1379
|
+
def show_landscapes
|
1380
|
+
showcmd = 'show landscapes'
|
1381
|
+
output = self.exec_cmd(showcmd)
|
1382
|
+
result = output.readline
|
1383
|
+
if result =~ /SSName/
|
1384
|
+
return output
|
1385
|
+
end
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
#Execute <tt>show attributes</tt>
|
1389
|
+
#
|
1390
|
+
#Available types:
|
1391
|
+
#
|
1392
|
+
#* <b>:model</b> - Get attributes for a given model.
|
1393
|
+
# * When set, mh_or_mth must be a Model or a model handle.
|
1394
|
+
# * If <tt>enumerate</tt> is set, values will be automatically enumerated.
|
1395
|
+
#* <b>:mtype</b> - get attributes for a given model type.
|
1396
|
+
# * When set, mh_or_mth must be a MType or a model type handle.
|
1397
|
+
# * <tt>enumerate</tt> is ignored.
|
1398
|
+
#
|
1399
|
+
#Filter options.
|
1400
|
+
#
|
1401
|
+
#* <tt>:id</tt> - returns the specific attribute.
|
1402
|
+
# * Only valid for the <tt>:model</tt> type.
|
1403
|
+
# * Takes an Attr or an attribute ID.
|
1404
|
+
# * Returns all instances for a list attribute.
|
1405
|
+
# * Example: <tt>show_attributes(:model,{:id,'0x10000'})</tt>
|
1406
|
+
#* <tt>:instance</tt> = returns a specific instance of an attribute.
|
1407
|
+
# * Only valid for the <tt>:model</tt> type.
|
1408
|
+
# * Takes a 2 element array.
|
1409
|
+
# * The first element must be an Attr or an attribute id.
|
1410
|
+
# * The second element must be an instance identifier.
|
1411
|
+
# * Example: <tt>show_attributes(:model,{:instance,['0x10000','192.168.1.1']})</tt>
|
1412
|
+
#* <tt>:range</tt> - returns attributes whose ID in in the specified range.
|
1413
|
+
# * Valid for both <tt>:model</tt> and <tt>:mtype</tt> types.
|
1414
|
+
# * :range can take a single range string, or an array of Model handles or Models.
|
1415
|
+
# * Example: <tt>show_attributes(:mtype,{:range,['0x10000','0x1000a])</tt>
|
1416
|
+
# * Example: <tt>show_attributes(:model,{:range,'0x10000-0x1000a'})</tt>
|
1417
|
+
#* <tt>:name</tt> - returns attributes whose name contains the specified string.
|
1418
|
+
# * Valid for both <tt>:model</tt> and <tt>:mtype</tt>.
|
1419
|
+
# * Example: <tt>show_attributes(:mtype{:name,'Condition'})</tt>
|
1420
|
+
#* <tt>:flag</tt> - returns attributes that have the specified flag set.
|
1421
|
+
# * Only valid for the <tt>:mtype</tt> type.
|
1422
|
+
# * Example: <tt>show_attributes(:mtype,{:flag,'G'})</tt>
|
1423
|
+
#* <tt>:lanscape</tt> - returns attributes in the specified landscape.
|
1424
|
+
# * Only valid for the <tt>:mtype</tt> type.
|
1425
|
+
# * landscape can be a Landscape object or a landscape handle.
|
1426
|
+
# * Example: <tt>show_attributes(:mtype,{:landscape,'0x400000'})</tt>
|
1427
|
+
def show_attributes(type,mh_or_mth,filter=nil,enumerate=false)
|
1428
|
+
showcmd = 'show attributes '
|
1429
|
+
if type == :model
|
1430
|
+
showcmd += ' -e ' if enumerate
|
1431
|
+
if filter
|
1432
|
+
filter.keys.each do |option|
|
1433
|
+
case option
|
1434
|
+
when :id
|
1435
|
+
showcmd += ' attr=' + get_id(filter[option],Attr)
|
1436
|
+
when :instance
|
1437
|
+
if filter[option].kind_of?(Attr)
|
1438
|
+
instance = filter[option].instance
|
1439
|
+
attrid = filter[option].id
|
1440
|
+
else
|
1441
|
+
instance = filter[option][1]
|
1442
|
+
attrid = filter[option][0]
|
1443
|
+
end
|
1444
|
+
raise ArgumentError, 'instance is not an instance identifier' unless
|
1445
|
+
instance =~ /^\d+(\.\d+)*$/
|
1446
|
+
showcmd += ' attr=' + get_id(attrid,Attr) + ',iid=' + instance
|
1447
|
+
when :name
|
1448
|
+
showcmd += ' attrname=' + filter[option]
|
1449
|
+
when :range
|
1450
|
+
showcmd += ' attrr='
|
1451
|
+
showcmd += filter[option] if filter[option].kind_of?(String)
|
1452
|
+
showcmd += get_id(filter[option][0],Attr) + '-' +
|
1453
|
+
get_id(filter[option][1],Attr) if filter[option].kind_of?(Array)
|
1454
|
+
end
|
1455
|
+
end
|
1456
|
+
end
|
1457
|
+
showcmd += ' mh=' + get_handle(mh_or_mth,Model)
|
1458
|
+
elsif type == :mtype
|
1459
|
+
showcmd += ' mth=' + get_handle(mh_or_mth,MType)
|
1460
|
+
if filter
|
1461
|
+
filter.keys.each do |option|
|
1462
|
+
case option
|
1463
|
+
when :range
|
1464
|
+
showcmd += ' attrr='
|
1465
|
+
showcmd += filter[option] if filter[option].kind_of?(String)
|
1466
|
+
showcmd += get_id(filter[option][0],Attr) + '-' +
|
1467
|
+
get_id(filter[option][1],Attr) if filter[option].kind_of?(Array)
|
1468
|
+
when :name
|
1469
|
+
showcmd += ' attrname=' + filter[option]
|
1470
|
+
when :flag
|
1471
|
+
showcmd += ' flags=' + filter[option]
|
1472
|
+
when :landscape
|
1473
|
+
showcmd += ' lh=' + get_handle(filter[option],Landscape)
|
1474
|
+
end
|
1475
|
+
end
|
1476
|
+
end
|
1477
|
+
else
|
1478
|
+
raise ArgumentError, 'Valid types are :model or :mtype'
|
1479
|
+
end
|
1480
|
+
output = self.exec_cmd(showcmd)
|
1481
|
+
result = output.readline
|
1482
|
+
show_invalid_mh_or_lh?(result)
|
1483
|
+
if result =~ /^Id\s+/
|
1484
|
+
return output
|
1485
|
+
elsif result =~ /invalid model type handle/
|
1486
|
+
raise CommandError, result
|
1487
|
+
elsif result =~ /non list attribute/
|
1488
|
+
raise CommandError, result
|
1489
|
+
elsif result =~ /invalid attribute/
|
1490
|
+
raise CommandError,result
|
1491
|
+
elsif result =~ /invalid instance/
|
1492
|
+
raise CommandError,result
|
1493
|
+
end
|
1494
|
+
end
|
1495
|
+
|
1496
|
+
#Execute <tt>destroy model</tt>.
|
1497
|
+
#
|
1498
|
+
#<tt>model</tt> can either be a Model or a model handle
|
1499
|
+
#
|
1500
|
+
#Returns true if the destroy succeeded, otherwise CommandError
|
1501
|
+
#is raised.
|
1502
|
+
def destroy_model(model)
|
1503
|
+
destroycmd = 'destroy model -n mh=' + get_handle(model,Model)
|
1504
|
+
output = exec_cmd(destroycmd)
|
1505
|
+
result = output.readlines.last
|
1506
|
+
if result =~ /destroy model: successful/
|
1507
|
+
return true
|
1508
|
+
else
|
1509
|
+
raise CommandError, result
|
1510
|
+
end
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
#Execute <tt>destroy association</tt>.
|
1514
|
+
#
|
1515
|
+
#Returns true if the destroy succeeded, otherwise CommandError
|
1516
|
+
#is raised.
|
1517
|
+
def destroy_association(relation,left_model,right_model)
|
1518
|
+
destroycmd = 'destroy association -n '
|
1519
|
+
destroycmd += ' rel=' + get_relation(relation)
|
1520
|
+
destroycmd += ' lmh=' + get_handle(left_model,Model)
|
1521
|
+
destroycmd += ' rmh=' + get_handle(right_model,Model)
|
1522
|
+
output = exec_cmd(destroycmd)
|
1523
|
+
result = output.readlines.last
|
1524
|
+
if result =~ /destroy association: successful/
|
1525
|
+
return true
|
1526
|
+
else
|
1527
|
+
raise CommandError, result
|
1528
|
+
end
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
#Execute <tt>destroy alarm</tt>
|
1532
|
+
#
|
1533
|
+
#<tt>alarm</tt> can be an Alarm or an alarm ID.
|
1534
|
+
#
|
1535
|
+
#If <tt>landscape</tt> is set, will detroy the alarm
|
1536
|
+
#on the specified landscape.
|
1537
|
+
#<tt>landscape</tt> can be a Landscape object or a valid
|
1538
|
+
#landscape handle.
|
1539
|
+
#
|
1540
|
+
#Returns true if the destroy succeeded, otherwise CommandError
|
1541
|
+
#is raised.
|
1542
|
+
def destroy_alarm(alarm,landscape=nil)
|
1543
|
+
destroycmd = 'destroy alarm -n aid=' + get_id(alarm,Alarm)
|
1544
|
+
destroycmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1545
|
+
output = exec_cmd(destroycmd)
|
1546
|
+
result = output.readlines.last
|
1547
|
+
if result =~ /destroy alarm: successful/
|
1548
|
+
return true
|
1549
|
+
else
|
1550
|
+
raise CommandError, result
|
1551
|
+
end
|
1552
|
+
end
|
1553
|
+
|
1554
|
+
#Execute <tt>create model</tt> with the IP
|
1555
|
+
#option.
|
1556
|
+
#
|
1557
|
+
#Options:
|
1558
|
+
#* <tt>ip</tt> - Required. The device's IP address.
|
1559
|
+
#* <tt>comm</tt> - Optional. The community string.
|
1560
|
+
#* <tt>timeout</tt> - Optional. The device's timeout.
|
1561
|
+
#* <tt>retries</tt> - Optional. The number of times to attempt to contact the device.
|
1562
|
+
#* <tt>sdm</tt> - Optional. The address of the Secure Domain Connector.
|
1563
|
+
#* <tt>landscape</tt> - Optional. The landscape to create the device on.
|
1564
|
+
#
|
1565
|
+
#If creation is sucessful, returns a new Model with the handle filled in.
|
1566
|
+
#otherwise, raises a CommandError.
|
1567
|
+
def discover_device(ip,comm=nil,timeout=nil,retries=nil,sdm=nil,landscape=nil)
|
1568
|
+
createcmd = 'create model ip=' + ip
|
1569
|
+
createcmd += ' sec_dom=' + sdm if sdm
|
1570
|
+
createcmd += ' comm=' + comm if comm
|
1571
|
+
createcmd += ' to=' + timeout if timeout
|
1572
|
+
createcmd += ' tc=' + retries if retries
|
1573
|
+
createcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1574
|
+
output = exec_cmd(createcmd)
|
1575
|
+
result = output.readlines.last
|
1576
|
+
if result =~ /created model handle\s+=\s+(0x[0-f]+)/
|
1577
|
+
model = Model.new
|
1578
|
+
model.handle = $1
|
1579
|
+
return model
|
1580
|
+
else
|
1581
|
+
raise CommandError, result
|
1582
|
+
end
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
#Execute <tt>create model</tt> without the
|
1586
|
+
#IP option.
|
1587
|
+
#<tt>mtype</tt> may either be a valid MType object, or a model type handle.
|
1588
|
+
#<tt>attrs</tt> is an array of Attr objects that you want to be set on the
|
1589
|
+
#model when it is created.
|
1590
|
+
#<tt>landscape</tt> is the landscape you wish to create the model on.
|
1591
|
+
#<tt>landscape</tt> may be a Landscape object or a landscape handle.
|
1592
|
+
def create_model(mtype,attrs=nil,landscape=nil)
|
1593
|
+
createcmd = 'create model mth='
|
1594
|
+
createcmd += get_handle(mtype,MType)
|
1595
|
+
createcmd += expand_attrs(attrs) if attrs
|
1596
|
+
createcmd += ' lh=' + get_handle(landscape,Landscape) if landscape
|
1597
|
+
output = exec_cmd(createcmd)
|
1598
|
+
result = output.readlines.last
|
1599
|
+
if result =~ /created model handle\s+=\s+(0x[0-f]+)/
|
1600
|
+
model = Model.new
|
1601
|
+
model.handle = $1
|
1602
|
+
model.attrs = attrs
|
1603
|
+
if mtype.instance_of?(MType)
|
1604
|
+
model.type = mtype
|
1605
|
+
else
|
1606
|
+
model.type = MType.new(mtype)
|
1607
|
+
end
|
1608
|
+
return model
|
1609
|
+
else
|
1610
|
+
raise CommandError, result
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
#Execute <tt>update model</tt>.
|
1616
|
+
#<tt>model</tt> can be a Model object or a model handle.
|
1617
|
+
#<tt>attrs</tt> is an array of Attr objects to update.
|
1618
|
+
#
|
1619
|
+
#Returns true if the update succeeded, or raises a CommandError.
|
1620
|
+
def update_model(model,attrs)
|
1621
|
+
updatecmd = 'update mh='
|
1622
|
+
updatecmd += get_handle(model,Model)
|
1623
|
+
updatecmd += expand_attrs(attrs)
|
1624
|
+
output = exec_cmd(updatecmd)
|
1625
|
+
result = output.readlines.first
|
1626
|
+
if result =~ /^Id/
|
1627
|
+
return true
|
1628
|
+
else
|
1629
|
+
raise CommandError, result
|
1630
|
+
end
|
1631
|
+
end
|
1632
|
+
|
1633
|
+
#Execute <tt>update alarm</tt>.
|
1634
|
+
#<tt>alarm</tt> can be an Alarm object or an alarm id.
|
1635
|
+
#<tt>action</tt> is the field that will be updated.
|
1636
|
+
#Valid actions are:
|
1637
|
+
#* <tt>:assign</tt>
|
1638
|
+
#* <tt>:ticket</tt>
|
1639
|
+
#* <tt>:url</tt>
|
1640
|
+
#* <tt>:ack</tt>
|
1641
|
+
#* <tt>:status</tt>
|
1642
|
+
#
|
1643
|
+
#<tt>action</tt> may also be a Hash of alarm attributes to set.
|
1644
|
+
#If <tt>action</tt> is a single attribute, <tt>value</tt> must be set.
|
1645
|
+
#<tt>replace</tt> will replace the existing value, as opposed to just
|
1646
|
+
#appending. <tt>replace</tt> is only valid when updating <tt>:ticket</tt>
|
1647
|
+
#and <tt>status</tt>.
|
1648
|
+
#
|
1649
|
+
def update_alarm(alarm,action,val=nil,replace=false)
|
1650
|
+
if action.kind_of?(Symbol) && val == nil
|
1651
|
+
raise ArgumentError, 'When updating an individual alarm attribute, you must pass a value'
|
1652
|
+
elsif action.kind_of?(Hash) && replace == true
|
1653
|
+
raise ArgumentError, 'Field replacement may only be done by updating a single alarm attribute'
|
1654
|
+
end
|
1655
|
+
unless action.kind_of?(Hash) || action.kind_of?(Symbol)
|
1656
|
+
raise ArgnumentError, 'Valid actions may be a single Symbol or a Hash'
|
1657
|
+
end
|
1658
|
+
updatecmd = 'update alarm aid='
|
1659
|
+
if alarm.instance_of?(Alarm)
|
1660
|
+
updatecmd += alarm.id
|
1661
|
+
else
|
1662
|
+
updatecmd += alarm
|
1663
|
+
end
|
1664
|
+
if action.kind_of?(Symbol)
|
1665
|
+
updatecmd += ' -r ' if replace
|
1666
|
+
updatecmd += process_alarm_action(action,val)
|
1667
|
+
end
|
1668
|
+
if action.kind_of?(Hash)
|
1669
|
+
action.keys.each do |key|
|
1670
|
+
updatecmd += process_alarm_action(key,action[key])
|
1671
|
+
end
|
1672
|
+
end
|
1673
|
+
result = exec_cmd(updatecmd)
|
1674
|
+
if $?.exitstatus == 0
|
1675
|
+
return true
|
1676
|
+
else
|
1677
|
+
raise CommandError, result
|
1678
|
+
end
|
1679
|
+
end
|
1680
|
+
|
1681
|
+
|
1682
|
+
|
1683
|
+
|
1684
|
+
#Execute <tt>create association</tt>.
|
1685
|
+
#
|
1686
|
+
#<tt>relation</tt> can be a Relation object or a relation name.
|
1687
|
+
#<tt>left_model</tt> and <tt>right_model</tt> can be a
|
1688
|
+
#Model object or a model handle.
|
1689
|
+
def create_association(relation,left_model,right_model)
|
1690
|
+
createcmd = 'create association '
|
1691
|
+
createcmd += ' rel=' + get_relation(relation)
|
1692
|
+
createcmd += ' lmh='
|
1693
|
+
createcmd += get_handle(left_model,Model)
|
1694
|
+
createcmd += ' rmh='
|
1695
|
+
createcmd += get_handle(right_model,Model)
|
1696
|
+
|
1697
|
+
output = exec_cmd(createcmd)
|
1698
|
+
result = output.readlines.last
|
1699
|
+
if result =~ /create association: successful/
|
1700
|
+
if relation.kind_of? String
|
1701
|
+
rel = Relation.new(rel)
|
1702
|
+
end
|
1703
|
+
if left_model.kind_of? String
|
1704
|
+
left_model = Model.new(left_model)
|
1705
|
+
end
|
1706
|
+
if right_model.kind_of? String
|
1707
|
+
right_model = Model.new(right_model)
|
1708
|
+
end
|
1709
|
+
return Association.new(left_model,right_model,relation)
|
1710
|
+
else
|
1711
|
+
raise CommandError, result
|
1712
|
+
end
|
1713
|
+
end
|
1714
|
+
|
1715
|
+
#Execute <tt>create alarm</tt>.
|
1716
|
+
#* <tt>severity</tt> is the alarm severity. Allowable options are:
|
1717
|
+
# * CRITICAL
|
1718
|
+
# * MAJOR
|
1719
|
+
# * MINOR
|
1720
|
+
# * SUPPRESSED
|
1721
|
+
# * MAINTENANCE
|
1722
|
+
# * INITIAL
|
1723
|
+
#* <tt>cause</tt> is the probable cause code.
|
1724
|
+
#* <tt>model</tt> is the model to assert the alarm on.
|
1725
|
+
# * <tt>model</tt> can be a Model object or a model handle.
|
1726
|
+
#* If <tt>replace</tt> is true, will replace an existing alarm on the model.
|
1727
|
+
#
|
1728
|
+
#Returns the created Alarm object if sucessful, otherwise raises a CommandError.
|
1729
|
+
def create_alarm(severity,cause,model,replace = false)
|
1730
|
+
createcmd = 'create alarm '
|
1731
|
+
createcmd += '-nr ' if replace
|
1732
|
+
if severity =~ /CRITICAL/i ||
|
1733
|
+
/MAJOR/i ||
|
1734
|
+
/MINOR/i ||
|
1735
|
+
/SUPPRESSED/i ||
|
1736
|
+
/MAINTENANCE/i ||
|
1737
|
+
/INITIAL/i
|
1738
|
+
createcmd += "sev=#{severity} "
|
1739
|
+
else
|
1740
|
+
raise ArgumentError, 'Severity must be CRITICAL, MAJOR, MINOR, SUPPRESSED, MAINTENANCE, or INITIAL'
|
1741
|
+
end
|
1742
|
+
if cause.instance_of?(Alarm)
|
1743
|
+
createcmd += "cause=#{cause.causeid} "
|
1744
|
+
elsif cause.kind_of?(String)
|
1745
|
+
createcmd += "cause=#{cause} "
|
1746
|
+
else
|
1747
|
+
raise ArgumentError, 'You must pass a valid Probable Cause code'
|
1748
|
+
end
|
1749
|
+
createcmd += 'mh='+get_handle(model,Model)
|
1750
|
+
output = exec_cmd(createcmd).readlines
|
1751
|
+
if output.first =~ /^ID/
|
1752
|
+
return Alarm.parse(output.last)
|
1753
|
+
else
|
1754
|
+
raise CommandError, output.last
|
1755
|
+
end
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
#Execute <tt>create event</tt>.
|
1759
|
+
#
|
1760
|
+
#<tt>model</tt> can be a Model or a model handle.
|
1761
|
+
#<tt>evcode</tt> is a valid event code.
|
1762
|
+
#<tt>text</tt> is the event text.
|
1763
|
+
#
|
1764
|
+
#Returns true if the event was created, otherwise returns
|
1765
|
+
#a CommandError.
|
1766
|
+
#
|
1767
|
+
def create_event(model,evcode,text='')
|
1768
|
+
createcmd = 'create event type='
|
1769
|
+
if evcode.instance_of?(Event)
|
1770
|
+
createcmd += evcode.type
|
1771
|
+
createcmd += ' text=\"' + evcode.message + '\"'
|
1772
|
+
elsif evcode.kind_of?(String) && evcode.hex?
|
1773
|
+
createcmd += evcode
|
1774
|
+
createcmd += ' text=\"' + text + '\"'
|
1775
|
+
else
|
1776
|
+
raise ArgumentError, 'You must pass a valid Event Code'
|
1777
|
+
end
|
1778
|
+
createcmd += ' mh=' + get_handle(model,Model)
|
1779
|
+
output = exec_cmd(createcmd)
|
1780
|
+
if $?.exitstatus > 0
|
1781
|
+
raise CommandError, output.readlines.first
|
1782
|
+
else
|
1783
|
+
return true
|
1784
|
+
end
|
1785
|
+
end
|
1786
|
+
|
1787
|
+
|
1788
|
+
|
1789
|
+
|
1790
|
+
|
1791
|
+
|
1792
|
+
|
1793
|
+
|
1794
|
+
|
1795
|
+
private
|
1796
|
+
|
1797
|
+
def valid_alarm_action?(action)
|
1798
|
+
validactions = [ :ticket,
|
1799
|
+
:assign,
|
1800
|
+
:status,
|
1801
|
+
:ack,
|
1802
|
+
:url ]
|
1803
|
+
ret = false
|
1804
|
+
validactions.each do |validaction|
|
1805
|
+
if action == validaction
|
1806
|
+
ret=true
|
1807
|
+
end
|
1808
|
+
end
|
1809
|
+
return ret
|
1810
|
+
end
|
1811
|
+
|
1812
|
+
def process_alarm_action(action,value)
|
1813
|
+
if valid_alarm_action?(action)
|
1814
|
+
return ' ' + action.to_s + '="' + value.to_s + '"'
|
1815
|
+
else
|
1816
|
+
raise ArgumentError, 'The requested field to update, ' + action.to_s + ', is not valid'
|
1817
|
+
end
|
1818
|
+
end
|
1819
|
+
|
1820
|
+
|
1821
|
+
def get_handle(obj,match_class)
|
1822
|
+
if obj.instance_of?(match_class)
|
1823
|
+
raise ArgumentError, match_class.to_s + ' must have a valid handle.' unless obj.handle && obj.handle.hex?
|
1824
|
+
return obj.handle
|
1825
|
+
elsif obj.kind_of?(String) && obj.hex?
|
1826
|
+
return obj
|
1827
|
+
else
|
1828
|
+
raise ArgumentError, 'Argument must be a ' + match_class.to_s + ' object or a valid handle.'
|
1829
|
+
end
|
1830
|
+
end
|
1831
|
+
|
1832
|
+
def get_id(obj,match_class)
|
1833
|
+
if obj.instance_of?(match_class)
|
1834
|
+
formaterror = match_class.to_s + ' must have a valid id.'
|
1835
|
+
if obj.instance_of?(Alarm)
|
1836
|
+
raise ArgumentError, formaterror unless obj.id == obj.id.to_i.to_s
|
1837
|
+
else
|
1838
|
+
raise ArgumentError, formaterror unless obj.id && obj.id.hex?
|
1839
|
+
end
|
1840
|
+
return obj.id
|
1841
|
+
elsif (obj.kind_of?(String) && obj.hex? && match_class != Alarm) ||
|
1842
|
+
(match_class == Alarm && obj.to_s == obj.to_i.to_s)
|
1843
|
+
return obj
|
1844
|
+
else
|
1845
|
+
raise ArgumentError, 'Argument must be a ' + match_class.to_s + ' object or a valid id.'
|
1846
|
+
end
|
1847
|
+
end
|
1848
|
+
|
1849
|
+
def get_relation(rel)
|
1850
|
+
if rel.instance_of?(Relation)
|
1851
|
+
raise ArgumentError, 'Relation must have a valid name.' unless rel.name
|
1852
|
+
return rel.name
|
1853
|
+
else
|
1854
|
+
return rel
|
1855
|
+
end
|
1856
|
+
end
|
1857
|
+
|
1858
|
+
def expand_attr(specattr,instance=nil)
|
1859
|
+
unless specattr.instance_of?(Attr)
|
1860
|
+
raise ArgumentError, 'Argument must be a SpecTools::Attr'
|
1861
|
+
end
|
1862
|
+
str = ' attr=' + specattr.id
|
1863
|
+
if specattr.list
|
1864
|
+
if specattr.value_table && spceattr.value_table[instance]
|
1865
|
+
str += ',iid=' + instance
|
1866
|
+
val = value_table[instance]
|
1867
|
+
else
|
1868
|
+
raise IsAListAttrError, 'Attempt to update a list attribute without an instance'
|
1869
|
+
end
|
1870
|
+
else
|
1871
|
+
val = specattr.value
|
1872
|
+
end
|
1873
|
+
str += ',val="' + val + '"'
|
1874
|
+
|
1875
|
+
end
|
1876
|
+
|
1877
|
+
def expand_attrs(attrs)
|
1878
|
+
cmd=''
|
1879
|
+
if attrs.kind_of?(Array)
|
1880
|
+
attrs.each do |specattr|
|
1881
|
+
cmd += expand_attr(specattr)
|
1882
|
+
end
|
1883
|
+
else
|
1884
|
+
cmd += expand_attr(attrs)
|
1885
|
+
end
|
1886
|
+
return cmd
|
1887
|
+
end
|
1888
|
+
|
1889
|
+
def append_lh(cmd,landscape)
|
1890
|
+
if landscape.instance_of?(Landscape)
|
1891
|
+
cmd += ' lh=' + landscape.handle
|
1892
|
+
elsif landscape.kind_of?(String) && landscape.hex?
|
1893
|
+
cmd += ' lh=' + landscape
|
1894
|
+
end
|
1895
|
+
end
|
1896
|
+
|
1897
|
+
|
1898
|
+
|
1899
|
+
|
1900
|
+
|
1901
|
+
|
1902
|
+
public
|
1903
|
+
|
1904
|
+
# == SpecTools::EnvironmentError
|
1905
|
+
# This error means that the module was unable to detect a proper environment for VNMSH.
|
1906
|
+
# Possible causes might be that the Specroot passwed was invalid, or the user does not
|
1907
|
+
# have execute permissions to the VNMSH commands.
|
1908
|
+
class EnvironmentError < StandardError
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
# == SpecTools::ConnectError
|
1912
|
+
# This error means that the module was unable to connect to a SpectroSERVER.
|
1913
|
+
class ConnectError < StandardError
|
1914
|
+
end
|
1915
|
+
|
1916
|
+
# == SpecTools::NotConnectedError
|
1917
|
+
# This error means that you attempted to use a session that was not yet connected.
|
1918
|
+
class NotConnectedError < StandardError
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
# == SpecTools::CommandError
|
1922
|
+
# This error means that the attempted command failed to execute
|
1923
|
+
class CommandError < StandardError
|
1924
|
+
end
|
1925
|
+
|
1926
|
+
end
|
1927
|
+
|
1928
|
+
|
1929
|
+
|
1930
|
+
|