net-snmp 0.2.0 → 0.2.1
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/README.rdoc +12 -3
- data/lib/net/snmp/constants.rb +30 -1
- data/lib/net/snmp/mib/node.rb +2 -2
- data/lib/net/snmp/oid.rb +16 -0
- data/lib/net/snmp/pdu.rb +4 -2
- data/lib/net/snmp/session.rb +93 -92
- data/lib/net/snmp/version.rb +1 -1
- data/spec/sync_spec.rb +25 -14
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -12,7 +12,8 @@ It provides classes for sessions, pdus, varbinds, and more.
|
|
12
12
|
* Supports sending of snmpv1 traps and snmpv2 traps/informs using TrapSession
|
13
13
|
* Integrates well with eventmachine, or can be used standalone.
|
14
14
|
* In Ruby 1.9, uses fibers behind the scenes to emulate synchronous calls asynchronously
|
15
|
-
|
15
|
+
* MIB support
|
16
|
+
* Convenience methods such as session.walk, session.get_columns, and session.table
|
16
17
|
|
17
18
|
== USAGE
|
18
19
|
|
@@ -49,7 +50,7 @@ You must call Session.close when you're done with a session to avoid leaking mem
|
|
49
50
|
In the synchronous versions, all session methods raise Net::SNMP:Error on any error. Timeouts raise Net::SNMP::TimeoutError.
|
50
51
|
In the asynchronous versions, the first argument to your callback will be the return status. Possible values include :success, :timeout, and :send_error.
|
51
52
|
If you need the underlying net-snmp session errors, you can call session.errno, session.snmp_err, and session.error_message.
|
52
|
-
|
53
|
+
PDU errors can be retreived with pdu.errstat, pdu.errindex giving the index of the offending varbind. See constants.rb for possible errors.
|
53
54
|
|
54
55
|
== EXAMPLES
|
55
56
|
|
@@ -137,6 +138,13 @@ Net::SNMP::OID objects. For example
|
|
137
138
|
|
138
139
|
For more complex MIB parsing needs, see smi-ffi[http://github.com/mixtli/smi-ffi]
|
139
140
|
|
141
|
+
== EXPERIMENTAL THREAD SUPPORT
|
142
|
+
If you intent to use threads, you should set:
|
143
|
+
|
144
|
+
Net::SNMP.thread_safe = true
|
145
|
+
|
146
|
+
Thread support is experimental and may be dropped. Let me know if you're using this feature.
|
147
|
+
|
140
148
|
== CAVEATS/DISCLAIMER
|
141
149
|
|
142
150
|
THIS GEM COULD CRASH YOUR SYSTEM AND EAT YOUR CHILDREN!
|
@@ -166,7 +174,8 @@ break this gem. Please let me know if you find bugs or missing features. Or be
|
|
166
174
|
* Commit, do not mess with rakefile, version, or history.
|
167
175
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
168
176
|
* Send me a pull request. Bonus points for topic branches.
|
177
|
+
* Bug reports including a failing rspec get priority treatment
|
169
178
|
|
170
|
-
== Copyright
|
179
|
+
== Copyright
|
171
180
|
|
172
181
|
Copyright (c) 2010 mixtli. See LICENSE for details.
|
data/lib/net/snmp/constants.rb
CHANGED
@@ -49,7 +49,7 @@ module Net
|
|
49
49
|
# Exception values for SNMPv2 and SNMPv3
|
50
50
|
SNMP_NOSUCHOBJECT = (ASN_CONTEXT | ASN_PRIMITIVE | 0x0)
|
51
51
|
SNMP_NOSUCHINSTANCE = (ASN_CONTEXT | ASN_PRIMITIVE | 0x1)
|
52
|
-
|
52
|
+
SNMP_ENDOFMIBVIEW = (ASN_CONTEXT | ASN_PRIMITIVE | 0x2)
|
53
53
|
|
54
54
|
|
55
55
|
# PDU types
|
@@ -71,6 +71,35 @@ module Net
|
|
71
71
|
NETSNMP_CALLBACK_OP_CONNECT = 4
|
72
72
|
NETSNMP_CALLBACK_OP_DISCONNECT = 5
|
73
73
|
|
74
|
+
|
75
|
+
# Error codes (the value of the field error-status in PDUs)
|
76
|
+
|
77
|
+
# in SNMPv1, SNMPsec, SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs
|
78
|
+
SNMP_ERR_NOERROR = (0) # XXX Used only for PDUs?
|
79
|
+
SNMP_ERR_TOOBIG = (1)
|
80
|
+
SNMP_ERR_NOSUCHNAME = (2)
|
81
|
+
SNMP_ERR_BADVALUE = (3)
|
82
|
+
SNMP_ERR_READONLY = (4)
|
83
|
+
SNMP_ERR_GENERR = (5)
|
84
|
+
|
85
|
+
# in SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs
|
86
|
+
SNMP_ERR_NOACCESS = (6)
|
87
|
+
SNMP_ERR_WRONGTYPE = (7)
|
88
|
+
SNMP_ERR_WRONGLENGTH = (8)
|
89
|
+
SNMP_ERR_WRONGENCODING = (9)
|
90
|
+
SNMP_ERR_WRONGVALUE = (10)
|
91
|
+
SNMP_ERR_NOCREATION = (11)
|
92
|
+
SNMP_ERR_INCONSISTENTVALUE = (12)
|
93
|
+
SNMP_ERR_RESOURCEUNAVAILABLE = (13)
|
94
|
+
SNMP_ERR_COMMITFAILED = (14)
|
95
|
+
SNMP_ERR_UNDOFAILED = (15)
|
96
|
+
SNMP_ERR_AUTHORIZATIONERROR = (16)
|
97
|
+
SNMP_ERR_NOTWRITABLE = (17)
|
98
|
+
|
99
|
+
# in SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs
|
100
|
+
SNMP_ERR_INCONSISTENTNAME = (18)
|
101
|
+
|
102
|
+
|
74
103
|
# SNMP Errors
|
75
104
|
SNMPERR_SUCCESS = (0)
|
76
105
|
SNMPERR_GENERR = (-1)
|
data/lib/net/snmp/mib/node.rb
CHANGED
@@ -8,7 +8,7 @@ module Net::SNMP
|
|
8
8
|
class << self
|
9
9
|
def get_node(oid)
|
10
10
|
if oid.kind_of?(String)
|
11
|
-
oid =
|
11
|
+
oid = OID.new(oid)
|
12
12
|
end
|
13
13
|
struct = Wrapper.get_tree(oid.pointer, oid.length_pointer.read_int, Wrapper.get_tree_head().pointer)
|
14
14
|
new(struct.pointer)
|
@@ -30,7 +30,7 @@ module Net::SNMP
|
|
30
30
|
|
31
31
|
def oid
|
32
32
|
return @oid if @oid
|
33
|
-
@oid =
|
33
|
+
@oid = OID.new(label)
|
34
34
|
end
|
35
35
|
|
36
36
|
# actually seems like list is linked backward, so this will retrieve the previous oid numerically
|
data/lib/net/snmp/oid.rb
CHANGED
@@ -52,6 +52,22 @@ module Net
|
|
52
52
|
node.label + "." + index
|
53
53
|
end
|
54
54
|
|
55
|
+
def <=>(o)
|
56
|
+
a = self._packed
|
57
|
+
b = o._packed
|
58
|
+
a <=> b
|
59
|
+
end
|
60
|
+
|
61
|
+
def _packed
|
62
|
+
i = self.to_s.dip
|
63
|
+
i.sub!(/^\./,'')
|
64
|
+
i.gsub!(/ /, '.0')
|
65
|
+
i.replace(i.split('.').map(&:to_i).pack('N*'))
|
66
|
+
end
|
67
|
+
|
68
|
+
def parent_of?(o)
|
69
|
+
o.to_s =~ /^#{self.to_s}\./
|
70
|
+
end
|
55
71
|
end
|
56
72
|
end
|
57
73
|
end
|
data/lib/net/snmp/pdu.rb
CHANGED
@@ -82,7 +82,6 @@ module Net
|
|
82
82
|
# * +type+ The data type. Possible values include Net::SNMP::ASN_OCTET_STR, Net::SNMP::ASN_COUNTER, etc. See constants.rb
|
83
83
|
# * +value+ The value of the varbind. default is nil.
|
84
84
|
def add_varbind(options)
|
85
|
-
#puts "adding varbind #{options.inspect}"
|
86
85
|
options[:type] ||= case options[:value]
|
87
86
|
when String
|
88
87
|
Constants::ASN_OCTET_STR
|
@@ -125,7 +124,7 @@ module Net
|
|
125
124
|
end
|
126
125
|
end
|
127
126
|
|
128
|
-
oid = options[:oid].kind_of?(
|
127
|
+
oid = options[:oid].kind_of?(OID) ? options[:oid] : OID.new(options[:oid])
|
129
128
|
var_ptr = Wrapper.snmp_pdu_add_variable(@struct.pointer, oid.pointer, oid.length_pointer.read_int, options[:type], value, value_len)
|
130
129
|
varbind = Varbind.new(var_ptr)
|
131
130
|
#Wrapper.print_varbind(varbind.struct)
|
@@ -142,6 +141,9 @@ module Net
|
|
142
141
|
Wrapper::snmp_errstring(self.errstat)
|
143
142
|
end
|
144
143
|
|
144
|
+
def print_errors
|
145
|
+
puts "errstat = #{self.errstat}, index = #{self.errindex}, message = #{self.error_message}"
|
146
|
+
end
|
145
147
|
# Free the pdu
|
146
148
|
def free
|
147
149
|
Wrapper.snmp_free_pdu(@struct.pointer)
|
data/lib/net/snmp/session.rb
CHANGED
@@ -33,9 +33,7 @@ module Net
|
|
33
33
|
# * +retries+ - snmp retries. default = 5
|
34
34
|
# Returns:
|
35
35
|
# Net::SNMP::Session
|
36
|
-
|
37
36
|
def open(options = {})
|
38
|
-
#puts "building session"
|
39
37
|
session = new(options)
|
40
38
|
if Net::SNMP::thread_safe
|
41
39
|
Net::SNMP::Session.lock.synchronize {
|
@@ -52,7 +50,6 @@ module Net
|
|
52
50
|
end
|
53
51
|
|
54
52
|
def initialize(options = {})
|
55
|
-
#puts "in initialize"
|
56
53
|
@timeout = options[:timeout] || 1
|
57
54
|
@retries = options[:retries] || 5
|
58
55
|
@requests = {}
|
@@ -189,20 +186,17 @@ module Net
|
|
189
186
|
end
|
190
187
|
end
|
191
188
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
189
|
def default_max_repeaters
|
196
190
|
# We could do something based on transport here. 25 seems safe
|
197
191
|
25
|
198
192
|
end
|
199
193
|
|
200
|
-
|
201
|
-
|
202
194
|
# Raise a NET::SNMP::Error with the session attached
|
203
195
|
def error(msg, options = {})
|
204
196
|
#Wrapper.snmp_sess_perror(msg, @sess.pointer)
|
205
|
-
|
197
|
+
err = Error.new({:session => self}.merge(options))
|
198
|
+
err.print
|
199
|
+
raise err, msg
|
206
200
|
end
|
207
201
|
|
208
202
|
|
@@ -247,6 +241,90 @@ module Net
|
|
247
241
|
alias :poll :select
|
248
242
|
|
249
243
|
|
244
|
+
# Issue repeated getnext requests on each oid passed in until
|
245
|
+
# the result is no longer a child. Returns a hash with the numeric
|
246
|
+
# oid strings as keys.
|
247
|
+
# XXX work in progress. only works synchronously (except with EM + fibers).
|
248
|
+
# Need to do better error checking and use getbulk when avaiable.
|
249
|
+
def walk(oidlist)
|
250
|
+
oidlist = [oidlist] unless oidlist.kind_of?(Array)
|
251
|
+
oidlist = oidlist.map {|o| o.kind_of?(OID) ? o : OID.new(o)}
|
252
|
+
all_results = {}
|
253
|
+
base_list = oidlist
|
254
|
+
while(!oidlist.empty? && pdu = get_next(oidlist))
|
255
|
+
debug "==============================================================="
|
256
|
+
debug "base_list = #{base_list}"
|
257
|
+
prev_base = base_list.dup
|
258
|
+
oidlist = []
|
259
|
+
print_errors
|
260
|
+
pdu.print_errors
|
261
|
+
pdu.varbinds.each_with_index do |vb, i|
|
262
|
+
if prev_base[i].parent_of?(vb.oid) && vb.object_type != Constants::SNMP_ENDOFMIBVIEW
|
263
|
+
# Still in subtree. Store results and add next oid to list
|
264
|
+
debug "adding #{vb.oid} to oidlist"
|
265
|
+
all_results[vb.oid.to_s] = vb.value
|
266
|
+
oidlist << vb.oid
|
267
|
+
else
|
268
|
+
# End of subtree. Don't add to list or results
|
269
|
+
debug "End of subtree"
|
270
|
+
base_list.delete_at(i)
|
271
|
+
debug "not adding #{vb.oid}"
|
272
|
+
end
|
273
|
+
# If get a pdu error, we can only tell the first failing varbind,
|
274
|
+
# So we remove it and resend all the rest
|
275
|
+
if pdu.error? && pdu.errindex == i + 1
|
276
|
+
oidlist.pop # remove the bad oid
|
277
|
+
debug "caught error"
|
278
|
+
if pdu.varbinds.size > i+1
|
279
|
+
# recram rest of oids on list
|
280
|
+
((i+1)..pdu.varbinds.size).each do |j|
|
281
|
+
debug "j = #{j}"
|
282
|
+
debug "adding #{j} = #{prev_list[j]}"
|
283
|
+
oidlist << prev_list[j]
|
284
|
+
end
|
285
|
+
# delete failing oid from base_list
|
286
|
+
base_list.delete_at(i)
|
287
|
+
end
|
288
|
+
break
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
if block_given?
|
293
|
+
yield all_results
|
294
|
+
end
|
295
|
+
all_results
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
# Given a list of columns (e.g ['ifIndex', 'ifDescr'], will return a hash with
|
300
|
+
# the indexes as keys and hashes as values.
|
301
|
+
# puts sess.get_columns(['ifIndex', 'ifDescr']).inspect
|
302
|
+
# {'1' => {'ifIndex' => '1', 'ifDescr' => 'lo0'}, '2' => {'ifIndex' => '2', 'ifDescr' => 'en0'}}
|
303
|
+
def columns(columns)
|
304
|
+
columns = columns.map {|c| c.kind_of?(OID) ? c : OID.new(c)}
|
305
|
+
walk_hash = walk(columns)
|
306
|
+
results = {}
|
307
|
+
walk_hash.each do |k, v|
|
308
|
+
oid = OID.new(k)
|
309
|
+
results[oid.index] ||= {}
|
310
|
+
results[oid.index][oid.node.label] = v
|
311
|
+
end
|
312
|
+
if block_given?
|
313
|
+
yield results
|
314
|
+
end
|
315
|
+
results
|
316
|
+
end
|
317
|
+
|
318
|
+
# table('ifEntry'). You must pass the direct parent entry. Calls columns with all
|
319
|
+
# columns in +table_name+
|
320
|
+
def table(table_name, &blk)
|
321
|
+
column_names = MIB::Node.get_node(table_name).children.collect {|c| c.oid }
|
322
|
+
results = columns(column_names)
|
323
|
+
if block_given?
|
324
|
+
yield results
|
325
|
+
end
|
326
|
+
results
|
327
|
+
end
|
250
328
|
|
251
329
|
# Send a PDU
|
252
330
|
# +pdu+ The Net::SNMP::PDU object to send. Usually created by Session.get, Session.getnext, etc.
|
@@ -280,10 +358,9 @@ module Net
|
|
280
358
|
# puts e.message
|
281
359
|
# end
|
282
360
|
def send_pdu(pdu, &callback)
|
283
|
-
#puts "send_pdu #{Fiber.current.inspect}"
|
284
361
|
if block_given?
|
285
362
|
@requests[pdu.reqid] = callback
|
286
|
-
|
363
|
+
debug "calling async_send"
|
287
364
|
if Wrapper.snmp_sess_async_send(@struct, pdu.pointer, sess_callback, nil) == 0
|
288
365
|
error("snmp_get async failed")
|
289
366
|
end
|
@@ -346,11 +423,14 @@ module Net
|
|
346
423
|
get_error
|
347
424
|
@snmp_msg
|
348
425
|
end
|
349
|
-
|
426
|
+
|
427
|
+
def print_errors
|
428
|
+
puts "errno: #{errno}, snmp_err: #{@snmp_err}, message: #{@snmp_msg}"
|
429
|
+
end
|
350
430
|
private
|
351
431
|
def sess_callback
|
352
432
|
@sess_callback ||= FFI::Function.new(:int, [:int, :pointer, :int, :pointer, :pointer]) do |operation, session, reqid, pdu_ptr, magic|
|
353
|
-
|
433
|
+
debug "in callback #{operation.inspect} #{session.inspect}"
|
354
434
|
op = case operation
|
355
435
|
when Constants::NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE
|
356
436
|
:success
|
@@ -386,86 +466,7 @@ module Net
|
|
386
466
|
@snmp_msg = msg_ptr.read_pointer.read_string
|
387
467
|
end
|
388
468
|
|
389
|
-
public
|
390
|
-
# XXX This needs work. Need to use getbulk for speed, guess maxrepeaters, etc..
|
391
|
-
# Also need to figure out how we can tell column names from something like ifTable
|
392
|
-
# instead of ifEntry. Needs to handle errors, there are probably offset problems
|
393
|
-
# in cases of bad data, and various other problems. Also need to add async support.
|
394
|
-
# Maybe return a hash with index as key?
|
395
|
-
def get_table(table_name, options = {})
|
396
|
-
column_names = options[:columns] || MIB::Node.get_node(table_name).children.collect {|c| c.label }
|
397
|
-
results = []
|
398
|
-
|
399
|
-
# repeat_count = if @version.to_s == '1' || options[:no_getbulk]
|
400
|
-
# 1
|
401
|
-
# elsif options[:repeat_count]
|
402
|
-
# options[:repeat_count]
|
403
|
-
# else
|
404
|
-
# (1000 / 36 / (column_names.size + 1)).to_i
|
405
|
-
# end
|
406
|
-
#
|
407
|
-
# res = if @version.to_s != '1' && !options[:no_getbulk]
|
408
|
-
# get_bulk(column_names, :max_repetitions => repeat_count)
|
409
|
-
# else
|
410
|
-
# get_next(column_names)
|
411
|
-
# end
|
412
|
-
|
413
|
-
|
414
|
-
first_result = get_next(column_names)
|
415
|
-
oidlist = []
|
416
|
-
good_column_names = []
|
417
|
-
row = {}
|
418
|
-
|
419
|
-
first_result.varbinds.each_with_index do |vb, idx|
|
420
|
-
oid = vb.oid
|
421
|
-
if oid.label[0..column_names[idx].length - 1] == column_names[idx]
|
422
|
-
oidlist << oid.label
|
423
|
-
good_column_names << column_names[idx]
|
424
|
-
row[column_names[idx]] = vb.value
|
425
|
-
end
|
426
|
-
end
|
427
|
-
results << row
|
428
|
-
|
429
|
-
catch :break_main_loop do
|
430
|
-
while(result = get_next(oidlist))
|
431
|
-
oidlist = []
|
432
|
-
row = {}
|
433
|
-
result.varbinds.each_with_index do |vb, idx|
|
434
|
-
#puts "got #{vb.oid.label} #{vb.value.inspect}, type = #{vb.object_type}"
|
435
|
-
row[good_column_names[idx]] = vb.value
|
436
|
-
oidlist << vb.oid.label
|
437
|
-
if vb.oid.label[0..good_column_names[idx].length - 1] != good_column_names[idx]
|
438
|
-
throw :break_main_loop
|
439
|
-
end
|
440
|
-
end
|
441
|
-
results << row
|
442
|
-
end
|
443
|
-
end
|
444
|
-
results
|
445
|
-
end
|
446
|
-
|
447
469
|
|
448
|
-
# def get_entries_cb(pdu, columns, options)
|
449
|
-
# cache = {}
|
450
|
-
# row_index = nil
|
451
|
-
# varbinds = pdu.varbinds.dup
|
452
|
-
# while(varbinds.size > 0)
|
453
|
-
# row = {}
|
454
|
-
# columns.each do |column|
|
455
|
-
# vb = varbinds.shift
|
456
|
-
# if vb.oid.to_s =~ /#{column.to_s}\.(\d+(:?\.\d+)*)/
|
457
|
-
# index = $1
|
458
|
-
# else
|
459
|
-
# last_entry = true
|
460
|
-
# next
|
461
|
-
# end
|
462
|
-
# row_index = index unless row_index
|
463
|
-
# index_cmp = Net::SNMP.oid_lex_cmp(index, row_index)
|
464
|
-
# if(index_cmp == 0)
|
465
|
-
# end
|
466
|
-
# end
|
467
|
-
# end
|
468
|
-
# end
|
469
470
|
end
|
470
471
|
end
|
471
472
|
end
|
data/lib/net/snmp/version.rb
CHANGED
data/spec/sync_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'pp'
|
2
3
|
|
3
4
|
describe "synchronous calls" do
|
4
5
|
# To test sets, you have to have a local snmpd running with write permissions
|
@@ -65,29 +66,39 @@ describe "synchronous calls" do
|
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
68
|
-
it "get_table should work with multiple columns" do
|
69
|
-
#pending
|
70
|
-
session = Net::SNMP::Session.open(:peername => "localhost", :version => '1')
|
71
|
-
table = session.get_table("ifTable", :columns => ["ifIndex", "ifDescr", "ifName"])
|
72
|
-
table[0]['ifName'].should eql("lo0")
|
73
|
-
table[1]['ifName'].should eql("gif0")
|
74
|
-
end
|
75
|
-
|
76
69
|
it "get_table should work" do
|
77
|
-
pending "not yet implemented"
|
70
|
+
#pending "not yet implemented"
|
78
71
|
session = Net::SNMP::Session.open(:peername => "localhost", :version => '1')
|
79
|
-
table = session.
|
80
|
-
table[
|
81
|
-
table[
|
72
|
+
table = session.table("ifEntry")
|
73
|
+
table['1']['ifIndex'].should eql(1)
|
74
|
+
table['2']['ifIndex'].should eql(2)
|
82
75
|
end
|
83
76
|
|
84
77
|
it "walk should work" do
|
85
|
-
pending "not yet implemented"
|
86
|
-
session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 1)
|
78
|
+
#pending "not yet implemented"
|
79
|
+
session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 1, :community => 'demopublic')
|
87
80
|
results = session.walk("system")
|
88
81
|
results['1.3.6.1.2.1.1.1.0'].should match(/test.net-snmp.org/)
|
89
82
|
end
|
90
83
|
|
84
|
+
it "walk should work with multiple oids" do
|
85
|
+
Net::SNMP::Session.open(:peername => 'localhost', :version => 1) do |sess|
|
86
|
+
sess.walk(['system', 'ifTable']) do |results|
|
87
|
+
pp results
|
88
|
+
results['1.3.6.1.2.1.1.1.0'].should match(/Darwin/)
|
89
|
+
results['1.3.6.1.2.1.2.2.1.1.2'].should eql(2)
|
90
|
+
results.size.should eql(186)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it "get_columns should work" do
|
96
|
+
Net::SNMP::Session.open(:peername => 'localhost') do |sess|
|
97
|
+
table = sess.columns(['ifIndex', 'ifDescr', 'ifType'])
|
98
|
+
table['1']['ifIndex'].should eql(1)
|
99
|
+
table['2']['ifDescr'].should eql('gif0')
|
100
|
+
end
|
101
|
+
end
|
91
102
|
end
|
92
103
|
|
93
104
|
context "version 2" do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ron McClain
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-05-01 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|