net-snmp2 0.3.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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +20 -0
  6. data/README.md +28 -0
  7. data/Rakefile +24 -0
  8. data/TODO.md +6 -0
  9. data/bin/mib2rb +129 -0
  10. data/bin/net-snmp2 +64 -0
  11. data/examples/agent.rb +104 -0
  12. data/examples/manager.rb +11 -0
  13. data/examples/trap_handler.rb +46 -0
  14. data/examples/v1_trap_session.rb +24 -0
  15. data/examples/v2_trap_session.rb +21 -0
  16. data/lib/net-snmp2.rb +85 -0
  17. data/lib/net/snmp.rb +27 -0
  18. data/lib/net/snmp/agent/agent.rb +48 -0
  19. data/lib/net/snmp/agent/provider.rb +51 -0
  20. data/lib/net/snmp/agent/provider_dsl.rb +124 -0
  21. data/lib/net/snmp/agent/request_dispatcher.rb +38 -0
  22. data/lib/net/snmp/constants.rb +287 -0
  23. data/lib/net/snmp/debug.rb +54 -0
  24. data/lib/net/snmp/dispatcher.rb +108 -0
  25. data/lib/net/snmp/error.rb +29 -0
  26. data/lib/net/snmp/listener.rb +76 -0
  27. data/lib/net/snmp/message.rb +142 -0
  28. data/lib/net/snmp/mib/mib.rb +67 -0
  29. data/lib/net/snmp/mib/module.rb +39 -0
  30. data/lib/net/snmp/mib/node.rb +122 -0
  31. data/lib/net/snmp/mib/templates.rb +48 -0
  32. data/lib/net/snmp/oid.rb +134 -0
  33. data/lib/net/snmp/pdu.rb +235 -0
  34. data/lib/net/snmp/repl/manager_repl.rb +243 -0
  35. data/lib/net/snmp/session.rb +560 -0
  36. data/lib/net/snmp/trap_handler/trap_handler.rb +42 -0
  37. data/lib/net/snmp/trap_handler/v1_trap_dsl.rb +44 -0
  38. data/lib/net/snmp/trap_handler/v2_trap_dsl.rb +38 -0
  39. data/lib/net/snmp/trap_session.rb +92 -0
  40. data/lib/net/snmp/utility.rb +10 -0
  41. data/lib/net/snmp/varbind.rb +57 -0
  42. data/lib/net/snmp/version.rb +5 -0
  43. data/lib/net/snmp/wrapper.rb +450 -0
  44. data/net-snmp2.gemspec +30 -0
  45. data/spec/README.md +105 -0
  46. data/spec/async_spec.rb +123 -0
  47. data/spec/em_spec.rb +23 -0
  48. data/spec/error_spec.rb +34 -0
  49. data/spec/fiber_spec.rb +41 -0
  50. data/spec/mib_spec.rb +68 -0
  51. data/spec/net-snmp_spec.rb +18 -0
  52. data/spec/oid_spec.rb +21 -0
  53. data/spec/spec_helper.rb +10 -0
  54. data/spec/sync_spec.rb +132 -0
  55. data/spec/thread_spec.rb +19 -0
  56. data/spec/trap_spec.rb +45 -0
  57. data/spec/utility_spec.rb +10 -0
  58. data/spec/wrapper_spec.rb +69 -0
  59. metadata +166 -0
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $:.unshift lib
4
+ require 'net/snmp/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "net-snmp2"
8
+ s.version = Net::SNMP::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Ron McClain", "Jared Breeden"]
11
+ s.email = ["jared.breeden@gmail.com"]
12
+ s.homepage = "https://github.com/jbreeden/net-snmp2"
13
+ s.summary = %q{Object oriented wrapper around C net-snmp libraries}
14
+ s.description = %q{Cross platform net-snmp wrapper for Ruby, building on the original net-snmp gem}
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # Documentation options
22
+ s.has_rdoc = true
23
+ s.extra_rdoc_files = %w{ README.md }
24
+ s.rdoc_options = ["--main=README.md", "--line-numbers", "--inline-source", "--title=#{s.name}-#{s.version} Documentation"]
25
+
26
+ s.add_dependency 'nice-ffi'
27
+ s.add_dependency 'pry'
28
+ s.add_development_dependency "rspec"
29
+ s.add_development_dependency "eventmachine"
30
+ end
@@ -0,0 +1,105 @@
1
+ Notes
2
+ -----
3
+
4
+ - To test sets, you have to have a local snmpd running with write permissions
5
+ - For your local agent, use read community "public" & write community "private"
6
+ - A free simulator can be downloaded from [veraxsystems](http://www.veraxsystems.com/en/products/free-snmp-agent-simulator)
7
+ + TODO: This simulator could be used to replace the dependency on test.net-snmp.org
8
+
9
+ Latest Results
10
+ --------------
11
+
12
+ Generated with `rspec -f d -o spec/spec.txt --no-color`
13
+
14
+ ```
15
+ async
16
+ version 1
17
+ get should work
18
+ get should return an error
19
+ getnext should work
20
+ version 2
21
+ get should work
22
+ getnext should work
23
+ version 3
24
+ should get async using snmpv3
25
+ get should work
26
+ getnext should work
27
+
28
+ em
29
+ should work in event_machine
30
+
31
+ snmp errors
32
+ should rescue a timeout error
33
+ should rescue timeout error in a fiber
34
+
35
+ in fiber
36
+ get should work in a fiber with synchronous calling style
37
+ getnext
38
+ should get using snmpv3
39
+
40
+ Net::SNMP::MIB::Node
41
+ should get info for sysDescr
42
+ should get parent
43
+ should get node children
44
+ should get siblings
45
+ should get oid
46
+ should get by oid
47
+ should do stuff
48
+
49
+ Net::SNMP::OID
50
+ should instantiate valid oid with numeric
51
+ should instantiate valid oid with string
52
+ should to_s correctly
53
+
54
+ synchronous calls
55
+ version 1
56
+ get should succeed
57
+ multiple calls within session should succeed
58
+ get should succeed with multiple oids
59
+ set should succeed
60
+ getnext should succeed
61
+ getbulk should succeed
62
+ getbulk should succeed with multiple oids
63
+ get should return error with invalid oid
64
+ get_table should work
65
+ walk should work
66
+ walk should work with multiple oids
67
+ get_columns should work
68
+ get a value with oid type should work
69
+ version 3
70
+ should get using snmpv3
71
+ should set using snmpv3 (PENDING: No reason given)
72
+ should get using authpriv (PENDING: No reason given)
73
+
74
+ in a thread
75
+ should get an oid asynchronously in a thread
76
+
77
+ snmp traps
78
+ should send a v1 trap
79
+ should send a v2 inform (PENDING: still working on it)
80
+ should send v2 trap (PENDING: still working on it)
81
+
82
+ Net::SNMP::Utility
83
+ should compare oids
84
+
85
+ Net::SNMP::Wrapper
86
+ wrapper should snmpget synchronously
87
+ wrapper should snmpget asynchronously
88
+
89
+ Pending:
90
+ synchronous calls version 3 should set using snmpv3
91
+ # No reason given
92
+ # ./spec/sync_spec.rb:117
93
+ synchronous calls version 3 should get using authpriv
94
+ # No reason given
95
+ # ./spec/sync_spec.rb:125
96
+ snmp traps should send a v2 inform
97
+ # still working on it
98
+ # ./spec/trap_spec.rb:14
99
+ snmp traps should send v2 trap
100
+ # still working on it
101
+ # ./spec/trap_spec.rb:26
102
+
103
+ Finished in 25.41 seconds (files took 0.38735 seconds to load)
104
+ 47 examples, 0 failures, 4 pending
105
+ ```
@@ -0,0 +1,123 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "async" do
4
+ context "version 1" do
5
+ it "get should work" do
6
+ did_callback = false
7
+ sess = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
8
+ s.get(["sysDescr.0", "sysContact.0"]) do |op, pdu|
9
+ did_callback = true
10
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
11
+ pdu.varbinds[1].value.should match(/Coders/)
12
+ end
13
+ end
14
+ Net::SNMP::Dispatcher.select(false)
15
+ did_callback.should be(true)
16
+ end
17
+
18
+ it "get should return an error" do
19
+ did_callback = false
20
+ sess = Net::SNMP::Session.open(:peername => 'www.yahoo.com', :timeout => 1, :retries => 0) do |sess|
21
+ sess.get("sysDescr.0") do |op, pdu|
22
+ did_callback = true
23
+ op.should eql(:timeout)
24
+ end
25
+ end
26
+ sleep 2
27
+ pdu = sess.select(10)
28
+
29
+ pdu.should eql(0)
30
+ did_callback.should eq(true)
31
+ end
32
+
33
+ it "getnext should work" do
34
+ did_callback = false
35
+ Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
36
+ s.get_next(["sysDescr", "sysContact"]) do |op, pdu|
37
+ did_callback = true
38
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
39
+ pdu.varbinds[1].value.should match(/Coders/)
40
+ end
41
+ end
42
+ Net::SNMP::Dispatcher.select(false)
43
+ did_callback.should be(true)
44
+ end
45
+ end
46
+
47
+ context "version 2" do
48
+ it "get should work" do
49
+ did_callback = false
50
+ Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic', :version => '2c') do |s|
51
+ s.get(["sysDescr.0", "sysContact.0"]) do |op, pdu|
52
+ did_callback = true
53
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
54
+ pdu.varbinds[1].value.should match(/Coders/)
55
+ end
56
+ end
57
+ Net::SNMP::Dispatcher.select(false)
58
+ did_callback.should be(true)
59
+ end
60
+
61
+ it "getnext should work" do
62
+ did_callback = false
63
+ Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic', :version => '2c') do |s|
64
+ s.get_next(["sysDescr", "sysContact"]) do |op, pdu|
65
+ did_callback = true
66
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
67
+ pdu.varbinds[1].value.should match(/Coders/)
68
+ end
69
+ end
70
+ Net::SNMP::Dispatcher.select(false)
71
+ did_callback.should be(true)
72
+ end
73
+
74
+ end
75
+
76
+ context "version 3" do
77
+ #failing intermittently
78
+ it "should get async using snmpv3" do
79
+ did_callback = false
80
+ Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 3, :username => 'MD5User',:security_level => Net::SNMP::Constants::SNMP_SEC_LEVEL_AUTHNOPRIV, :auth_protocol => :md5, :password => 'The Net-SNMP Demo Password') do |sess|
81
+ sess.get(["sysDescr.0"]) do |op, pdu|
82
+ did_callback = true
83
+ pdu.varbinds[0].value.should eql('test.net-snmp.org')
84
+ end
85
+ sleep(0.5)
86
+ Net::SNMP::Dispatcher.select(false)
87
+ #Net::SNMP::Dispatcher.select(false)
88
+ #puts "done select"
89
+ did_callback.should be(true)
90
+ end
91
+ end
92
+
93
+ it "get should work" do
94
+ did_callback = false
95
+ sess = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 3, :username => 'MD5User',:security_level => Net::SNMP::Constants::SNMP_SEC_LEVEL_AUTHNOPRIV, :auth_protocol => :md5, :password => 'The Net-SNMP Demo Password') do |sess|
96
+ sess.get(["sysDescr.0", "sysContact.0"]) do |op,pdu|
97
+ did_callback = true
98
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
99
+ pdu.varbinds[1].value.should match(/Coders/)
100
+ end
101
+ end
102
+ Net::SNMP::Dispatcher.select(false)
103
+ sess.close
104
+ did_callback.should be(true)
105
+ end
106
+
107
+ # XXX occasionally segfaulting
108
+ it "getnext should work" do
109
+ did_callback = false
110
+
111
+ sess = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 3, :username => 'MD5User',:security_level => Net::SNMP::Constants::SNMP_SEC_LEVEL_AUTHNOPRIV, :auth_protocol => :md5, :password => 'The Net-SNMP Demo Password') do |sess|
112
+ sess.get_next(["sysDescr", "sysContact"]) do |op, pdu|
113
+ did_callback = true
114
+ pdu.varbinds[0].value.should eql("test.net-snmp.org")
115
+ pdu.varbinds[1].value.should match(/Coders/)
116
+ end
117
+ end
118
+ Net::SNMP::Dispatcher.select(false)
119
+ sess.close
120
+ did_callback.should be(true)
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'eventmachine'
3
+
4
+ describe "em" do
5
+ it "should work in event_machine" do
6
+ did_callback = false
7
+ EM.run do
8
+ Net::SNMP::Dispatcher.em_loop
9
+
10
+ session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic') do |s|
11
+ s.get("sysDescr.0") do |op, result|
12
+ did_callback = true
13
+ result.varbinds[0].value.should eql("test.net-snmp.org")
14
+ end
15
+ end
16
+
17
+ EM.add_timer(3) do
18
+ did_callback.should eq(true)
19
+ EM.stop
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'eventmachine'
3
+
4
+ describe "snmp errors" do
5
+ it "should rescue a timeout error" do
6
+ Net::SNMP::Session.open(:peername => 'www.yahoo.com') do |sess|
7
+ begin
8
+ sess.get("sysDescr.0")
9
+ rescue Net::SNMP::Error => e
10
+ e.print
11
+ e.status.should eql(Net::SNMP::Constants::STAT_TIMEOUT)
12
+ end
13
+ end
14
+ end
15
+
16
+ it "should rescue timeout error in a fiber" do
17
+ got_error = false
18
+ EM.run {
19
+ Fiber.new {
20
+ Net::SNMP::Dispatcher.fiber_loop
21
+ Net::SNMP::Session.open(:peername => 'www.yahoo.com') do |sess|
22
+ begin
23
+ sess.get("sysDescr.0")
24
+ rescue Net::SNMP::TimeoutError => e
25
+ got_error = true
26
+ end
27
+ end
28
+ EM.stop
29
+ }.resume(nil)
30
+ }
31
+ got_error.should eq(true)
32
+ end
33
+
34
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'eventmachine'
3
+ require 'fiber'
4
+
5
+ describe "in fiber" do
6
+
7
+ def wrap_fiber
8
+ EM.run do
9
+ Net::SNMP::Dispatcher.fiber_loop
10
+ Fiber.new { yield; EM.stop }.resume(nil)
11
+ end
12
+ end
13
+
14
+ it "get should work in a fiber with synchronous calling style" do
15
+ wrap_fiber do
16
+ session = Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :community => 'demopublic')
17
+ result = session.get("sysDescr.0")
18
+ result.varbinds[0].value.should eql("test.net-snmp.org")
19
+ end
20
+ end
21
+
22
+ it "getnext" do
23
+ wrap_fiber do
24
+ Net::SNMP::Session.open(:peername => "test.net-snmp.org", :community => "demopublic" ) do |sess|
25
+ result = sess.get_next(["sysUpTimeInstance.0"])
26
+ result.varbinds.first.oid.oid.should eql("1.3.6.1.2.1.1.4.0")
27
+ result.varbinds.first.value.should match(/Net-SNMP Coders/)
28
+ end
29
+ end
30
+ end
31
+
32
+ it "should get using snmpv3" do
33
+ wrap_fiber do
34
+ Net::SNMP::Session.open(:peername => 'test.net-snmp.org', :version => 3, :username => 'MD5User', :security_level => Net::SNMP::Constants::SNMP_SEC_LEVEL_AUTHNOPRIV, :auth_protocol => :md5, :password => 'The Net-SNMP Demo Password') do |sess|
35
+ result = sess.get(["sysDescr.0"])
36
+ result.varbinds.first.value.should eql('test.net-snmp.org')
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Net::SNMP::MIB do
4
+ describe '::translate' do
5
+ it "translates OIDs to variable names including instance indexes" do
6
+ expect(Net::SNMP::MIB.translate('sysContact.0')).to eql '1.3.6.1.2.1.1.4.0'
7
+ end
8
+
9
+ it "translates variable names to OIDs including instance indexes" do
10
+ expect(Net::SNMP::MIB.translate('1.3.6.1.2.1.1.4.0')).to eql 'sysContact.0'
11
+ end
12
+ end
13
+
14
+ describe '::[]' do
15
+ it "can retrieve MIB nodes by variable name" do
16
+ node = Net::SNMP::MIB["sysDescr"]
17
+ node.label.should eq("sysDescr")
18
+ end
19
+
20
+ it "can retrieve MIB nodes by numeric oid" do
21
+ node = Net::SNMP::MIB["1.3.6.1.2.1.1.1"]
22
+ node.label.should eq("sysDescr")
23
+ end
24
+ end
25
+ end
26
+
27
+ describe Net::SNMP::MIB::Node do
28
+ describe "::get_node" do
29
+ it "retrieves MIB nodes by variable name" do
30
+ node = Net::SNMP::MIB::Node.get_node("sysDescr")
31
+ node.label.should eq("sysDescr")
32
+ end
33
+
34
+ it "retrieves MIB nodes by numeric oid" do
35
+ node = Net::SNMP::MIB::Node.get_node("1.3.6.1.2.1.1.1")
36
+ node.label.should eq("sysDescr")
37
+ end
38
+ end
39
+
40
+ describe "#parent" do
41
+ it "links to the parent node" do
42
+ node = Net::SNMP::MIB::Node.get_node("sysDescr")
43
+ node.parent.label.should eq("system")
44
+ end
45
+ end
46
+
47
+ describe "#children" do
48
+ it "contains Node objects for all child nodes" do
49
+ node = Net::SNMP::MIB::Node.get_node("ifTable")
50
+ if_entry = node.children.first
51
+ if_entry.children.should include { |n| n.label == "ifIndex" }
52
+ end
53
+ end
54
+
55
+ describe "#siblings" do
56
+ it "contains an array of sibling nodes" do
57
+ node = Net::SNMP::MIB::Node.get_node("sysDescr")
58
+ node.siblings.should include { |n| n.label == "sysName" }
59
+ end
60
+ end
61
+
62
+ describe "#oid" do
63
+ it "is an OID object for the node" do
64
+ node = Net::SNMP::MIB::Node.get_node("sysDescr")
65
+ node.oid.to_s.should eq("1.3.6.1.2.1.1.1")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "NetSnmp" do
4
+
5
+
6
+
7
+ # it "should get columns" do
8
+ # Net::SNMP::Session.open(:peername => 'localhost', :version => '2c', :community => 'public') do |sess|
9
+ # result = sess.get_columns(['ifIndex', 'ifInOctets', 'ifOutOctets'])
10
+ # result.size.should eql(7)
11
+ # result['1']['ifIndex'].should eql('1')
12
+ # result['2']['ifInOctets'].should be > 10
13
+ # end
14
+ # end
15
+
16
+
17
+
18
+ end