netsnmp 0.0.2 → 0.1.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.travis.yml +4 -4
  4. data/Gemfile +5 -1
  5. data/README.md +124 -63
  6. data/lib/netsnmp.rb +66 -10
  7. data/lib/netsnmp/client.rb +93 -75
  8. data/lib/netsnmp/encryption/aes.rb +84 -0
  9. data/lib/netsnmp/encryption/des.rb +80 -0
  10. data/lib/netsnmp/encryption/none.rb +17 -0
  11. data/lib/netsnmp/errors.rb +1 -3
  12. data/lib/netsnmp/message.rb +81 -0
  13. data/lib/netsnmp/oid.rb +18 -137
  14. data/lib/netsnmp/pdu.rb +106 -64
  15. data/lib/netsnmp/scoped_pdu.rb +23 -0
  16. data/lib/netsnmp/security_parameters.rb +198 -0
  17. data/lib/netsnmp/session.rb +84 -275
  18. data/lib/netsnmp/v3_session.rb +81 -0
  19. data/lib/netsnmp/varbind.rb +65 -156
  20. data/lib/netsnmp/version.rb +2 -1
  21. data/netsnmp.gemspec +2 -8
  22. data/spec/client_spec.rb +147 -99
  23. data/spec/handlers/celluloid_spec.rb +33 -20
  24. data/spec/oid_spec.rb +11 -5
  25. data/spec/pdu_spec.rb +22 -22
  26. data/spec/security_parameters_spec.rb +40 -0
  27. data/spec/session_spec.rb +0 -23
  28. data/spec/support/celluloid.rb +24 -0
  29. data/spec/support/request_examples.rb +36 -0
  30. data/spec/support/start_docker.sh +15 -1
  31. data/spec/v3_session_spec.rb +21 -0
  32. data/spec/varbind_spec.rb +2 -51
  33. metadata +30 -76
  34. data/lib/netsnmp/core.rb +0 -12
  35. data/lib/netsnmp/core/client.rb +0 -15
  36. data/lib/netsnmp/core/constants.rb +0 -153
  37. data/lib/netsnmp/core/inline.rb +0 -20
  38. data/lib/netsnmp/core/libc.rb +0 -48
  39. data/lib/netsnmp/core/libsnmp.rb +0 -44
  40. data/lib/netsnmp/core/structures.rb +0 -167
  41. data/lib/netsnmp/core/utilities.rb +0 -13
  42. data/lib/netsnmp/handlers/celluloid.rb +0 -27
  43. data/lib/netsnmp/handlers/em.rb +0 -56
  44. data/spec/core/libc_spec.rb +0 -2
  45. data/spec/core/libsnmp_spec.rb +0 -32
  46. data/spec/core/structures_spec.rb +0 -54
  47. data/spec/handlers/em_client_spec.rb +0 -34
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ module NETSNMP
3
+ # Abstraction for the v3 semantics.
4
+ class V3Session < Session
5
+
6
+ # @param [String, Integer] version SNMP version (always 3)
7
+ def initialize(version: 3, context: "", **opts)
8
+ @context = context
9
+ @security_parameters = opts.delete(:security_parameters)
10
+ super
11
+ end
12
+
13
+ # @see {NETSNMP::Session#build_pdu}
14
+ #
15
+ # @return [NETSNMP::ScopedPDU] a pdu
16
+ def build_pdu(type, *vars)
17
+ engine_id = security_parameters.engine_id
18
+ pdu = ScopedPDU.build(type, headers: [engine_id, @context], varbinds: vars)
19
+ end
20
+
21
+ # @see {NETSNMP::Session#send}
22
+ def send(*)
23
+ pdu, _ = super
24
+ pdu
25
+ end
26
+
27
+ private
28
+
29
+ def validate(**options)
30
+ super
31
+ if s = @security_parameters
32
+ # inspect public API
33
+ unless s.respond_to?(:encode) &&
34
+ s.respond_to?(:decode) &&
35
+ s.respond_to?(:sign) &&
36
+ s.respond_to?(:verify)
37
+ raise Error, "#{s} doesn't respect the sec params public API (#encode, #decode, #sign)"
38
+ end
39
+ else
40
+ @security_parameters = SecurityParameters.new(security_level: options[:security_level],
41
+ username: options[:username],
42
+ auth_protocol: options[:auth_protocol],
43
+ priv_protocol: options[:priv_protocol],
44
+ auth_password: options[:auth_password],
45
+ priv_password: options[:priv_password])
46
+
47
+ end
48
+ end
49
+
50
+ def security_parameters
51
+ if @security_parameters.engine_id.empty?
52
+ @security_parameters.engine_id = probe_for_engine
53
+ end
54
+ @security_parameters
55
+ end
56
+
57
+ # sends a probe snmp v3 request, to get the additional info with which to handle the security aspect
58
+ #
59
+ def probe_for_engine
60
+ report_sec_params = SecurityParameters.new(security_level: 0,
61
+ username: @security_parameters.username)
62
+ pdu = ScopedPDU.build(:get, headers: [])
63
+ encoded_report_pdu = Message.encode(pdu, security_parameters: report_sec_params)
64
+
65
+ encoded_response_pdu = @transport.send(encoded_report_pdu)
66
+
67
+ _, engine_id, @engine_boots, @engine_time = decode(encoded_response_pdu, security_parameters: report_sec_params)
68
+ engine_id
69
+ end
70
+
71
+ def encode(pdu)
72
+ Message.encode(pdu, security_parameters: @security_parameters,
73
+ engine_boots: @engine_boots,
74
+ engine_time: @engine_time)
75
+ end
76
+
77
+ def decode(stream, security_parameters: @security_parameters)
78
+ Message.decode(stream, security_parameters: security_parameters)
79
+ end
80
+ end
81
+ end
@@ -1,181 +1,90 @@
1
+ # frozen_string_literal: true
1
2
  module NETSNMP
2
3
  # Abstracts the PDU variable structure into a ruby object
3
4
  #
4
5
  class Varbind
5
- Error = Class.new(Error)
6
6
 
7
- attr_reader :struct
7
+ attr_reader :oid, :value
8
8
 
9
- # @param [FFI::Pointer] pointer to the variable list
10
- def initialize(pointer)
11
- @struct = Core::Structures::VariableList.new(pointer)
9
+ def initialize(oid , value: nil, type: nil)
10
+ @oid = OID.build(oid)
11
+ @type = type
12
+ @value = convert_val(value) if value
12
13
  end
13
- end
14
-
15
-
16
- # Abstracts the Varbind used for the PDU Request
17
- class RequestVarbind < Varbind
18
14
 
19
- # @param [RequestPDU] pdu the request pdu for this varbind
20
- # @param [OID] oid the oid for this varbind
21
- # @param [Object] value the value for the oid
22
- # @param [Hash] options additional options
23
- # @option options [Symbol, Integer, nil] :type C net-snmp type flag,
24
- # type-label for value (see #convert_type), if not set it's inferred from the value
25
- #
26
- def initialize(pdu, oid, value, options={})
27
- type = case options[:type]
28
- when Integer then options[:type] # assume that the code is properly passed
29
- when Symbol then convert_type(options[:type]) # DSL-specific API
30
- when nil then infer_from_value(value)
31
- else
32
- raise Error, "#{options[:type]} is an unsupported type"
33
- end
34
-
35
- value_length = case type
36
- when Core::Constants::ASN_NULL,
37
- Core::Constants::SNMP_NOSUCHOBJECT,
38
- Core::Constants::SNMP_NOSUCHINSTANCE,
39
- Core::Constants::SNMP_ENDOFMIBVIEW
40
- 0
41
- else value ? value.size : 0
42
- end
43
- value = convert_value(value, type)
44
-
45
- pointer = Core::LibSNMP.snmp_pdu_add_variable(pdu.pointer, oid.pointer, oid.length, type, value, value_length)
46
- super(pointer)
15
+ def to_s
16
+ "#<#{self.class}:0x#{object_id.to_s(16)} @oid=#{@oid} @value=#{@value}>"
47
17
  end
48
18
 
49
-
50
- private
51
-
52
- # @param [Object] value value to infer the type from
53
- # @return [Integer] the C net-snmp flag indicating the type
54
- # @raise [Error] when the value is from an unexpected type
55
- #
56
- def infer_from_value(value)
57
- case value
58
- when String then Core::Constants::ASN_OCTET_STR
59
- when Fixnum then Core::Constants::ASN_INTEGER
60
- when OID then Core::Constants::ASN_OBJECT_ID
61
- when nil then Core::Constants::ASN_NULL
62
- else raise Error, "#{value} is from an unsupported type"
63
- end
19
+ def to_der
20
+ to_asn.to_der
64
21
  end
65
22
 
66
- # @param [Symbol] symbol_type symbol representing the type
67
- # @return [Integer] the C net-snmp flag indicating the type
68
- # @raise [Error] when the symbol is unsupported
69
- #
70
- def convert_type(symbol_type)
71
- case symbol_type
72
- when :integer then Core::Constants::ASN_INTEGER
73
- when :gauge then Core::Constants::ASN_GAUGE
74
- when :counter then Core::Constants::ASN_COUNTER
75
- when :timeticks then Core::Constants::ASN_TIMETICKS
76
- when :unsigned then Core::Constants::ASN_UNSIGNED
77
- when :boolean then Core::Constants::ASN_BOOLEAN
78
- when :string then Core::Constants::ASN_OCTET_STR
79
- when :binary then Core::Constants::ASN_BIT_STR
80
- when :ip_address then Core::Constants::ASN_IPADDRESS
81
- else
82
- raise Error, "#{symbol_type} cannot be converted"
83
- end
84
- end
85
-
86
- # @param [Object] value the value to convert
87
- # @param [Integer] type the C net-snmp level object type flakg
88
- #
89
- # @return [FFI::Pointer] pointer to the memory location where the value is stored
90
- #
91
- def convert_value(value, type)
92
- case type
93
- when Core::Constants::ASN_INTEGER,
94
- Core::Constants::ASN_GAUGE,
95
- Core::Constants::ASN_COUNTER,
96
- Core::Constants::ASN_TIMETICKS,
97
- Core::Constants::ASN_UNSIGNED
98
- new_val = FFI::MemoryPointer.new(:long)
99
- new_val.write_long(value)
100
- new_val
101
- when Core::Constants::ASN_OCTET_STR,
102
- Core::Constants::ASN_BIT_STR,
103
- Core::Constants::ASN_OPAQUE
104
- value
105
- when Core::Constants::ASN_IPADDRESS
106
- # TODO
107
- when Core::Constants::ASN_OBJECT_ID
108
- value.pointer
109
- when Core::Constants::ASN_NULL,
110
- Core::Constants::SNMP_NOSUCHOBJECT,
111
- Core::Constants::SNMP_NOSUCHINSTANCE,
112
- Core::Constants::SNMP_ENDOFMIBVIEW
113
- nil
23
+ def to_asn
24
+ asn_oid = OID.to_asn(@oid)
25
+ asn_val = if @type
26
+ asn_type, asn_val = convert_to_asn(@type, @value)
27
+ OpenSSL::ASN1::ASN1Data.new(asn_val, asn_type, :APPLICATION)
28
+ else
29
+ case @value
30
+ when String
31
+ OpenSSL::ASN1::OctetString
32
+ when Integer
33
+ OpenSSL::ASN1::Integer
34
+ when true, false
35
+ OpenSSL::ASN1::Boolean
36
+ when nil
37
+ OpenSSL::ASN1::Null
114
38
  else
115
- raise Error, "Unknown variable type: #{type}"
39
+ raise Error, "#{@value}: unsupported varbind type"
40
+ end.new(@value)
116
41
  end
42
+ OpenSSL::ASN1::Sequence.new( [asn_oid, asn_val] )
117
43
  end
118
- end
119
-
120
- # Abstracts the Varbind used for the PDU Response
121
- #
122
- class ResponseVarbind < Varbind
123
44
 
124
- attr_reader :value, :oid_code
125
45
 
126
- # @param [FFI::Pointer] pointer pointer to the response varbind structure
127
- #
128
- # @note it loads the value and oid code on initialization
129
- #
130
- def initialize(pointer)
131
- super
132
- @value = load_varbind_value
133
- @oid_code = load_oid_code
46
+ def convert_val(asn_value)
47
+ case asn_value
48
+ when OpenSSL::ASN1::Primitive
49
+ val = asn_value.value
50
+ val = val.to_i if val.is_a?(OpenSSL::BN)
51
+ val
52
+ when OpenSSL::ASN1::ASN1Data
53
+ # application data
54
+ convert_application_asn(asn_value)
55
+ when OpenSSL::BN
56
+ else
57
+ asn_value # assume it's already primitive
58
+ end
134
59
  end
135
60
 
136
- private
137
-
138
- # @return [String] the oid code from the varbind
139
- def load_oid_code
140
- OID.read_pointer(@struct[:name], @struct[:name_length])
61
+ def convert_to_asn(typ, value)
62
+ return [typ, value] unless typ.is_a?(Symbol)
63
+ case typ
64
+ when :ipaddress then 0
65
+ when :counter32 then 1
66
+ when :gauge then 2
67
+ when :timetick then [3, [ value].pack("N") ]
68
+ when :opaque then 4
69
+ when :nsap then 5
70
+ when :counter64 then 6
71
+ when :uinteger then 7
72
+ end
141
73
  end
142
74
 
143
- # @return [Object] the value for the varbind (a ruby type, a string, an integer, a symbol etc...)
144
- #
145
- def load_varbind_value
146
- object_type = @struct[:type]
147
- case object_type
148
- when Core::Constants::ASN_OCTET_STR,
149
- Core::Constants::ASN_OPAQUE
150
- @struct[:val][:string].read_string(@struct[:val_len])
151
- when Core::Constants::ASN_INTEGER
152
- @struct[:val][:integer].read_long
153
- when Core::Constants::ASN_UINTEGER,
154
- Core::Constants::ASN_TIMETICKS,
155
- Core::Constants::ASN_COUNTER,
156
- Core::Constants::ASN_GAUGE
157
- @struct[:val][:integer].read_ulong
158
- when Core::Constants::ASN_IPADDRESS
159
- @struct[:val][:objid].read_string(@struct[:val_len]).unpack('CCCC').join(".")
160
- when Core::Constants::ASN_NULL
161
- nil
162
- when Core::Constants::ASN_OBJECT_ID
163
- OID.from_pointer(@struct[:val][:objid], @struct[:val_len] / OID.default_size)
164
- when Core::Constants::ASN_COUNTER64
165
- counter = Core::Structures::Counter64.new(@struct[:val][:counter64])
166
- counter[:high] * 2^32 + counter[:low]
167
- when Core::Constants::ASN_BIT_STR
168
- # XXX not sure what to do here. Is this obsolete?
169
- when Core::Constants::SNMP_ENDOFMIBVIEW
170
- :endofmibview
171
- when Core::Constants::SNMP_NOSUCHOBJECT
172
- :nosuchobject
173
- when Core::Constants::SNMP_NOSUCHINSTANCE
174
- :nosuchinstance
175
- else
176
- raise Error, "#{object_type} is an invalid type"
75
+ def convert_application_asn(asn)
76
+ case asn.tag
77
+ when 0 # IP Address
78
+ when 1 # ASN counter 32
79
+ asn.value.unpack("n*")[0] || 0
80
+ when 2 # gauge
81
+ when 3 # timeticks
82
+ asn.value.unpack("N*")[0] || 0
83
+ when 4 # opaque
84
+ when 5 # NSAP
85
+ when 6 # ASN Counter 64
86
+ when 7 # ASN UInteger
177
87
  end
178
88
  end
179
-
180
89
  end
181
90
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module NETSNMP
2
- VERSION = '0.0.2'.freeze
3
+ VERSION = '0.1.0'
3
4
  end
data/netsnmp.gemspec CHANGED
@@ -14,8 +14,8 @@ DESC
14
14
  gem.email = "cardoso_tiago@hotmail.com"
15
15
  gem.homepage = ""
16
16
  gem.platform = Gem::Platform::RUBY
17
- gem.required_ruby_version = '>=2.0.0'
18
- gem.metadata["allowed_push_hosts"] = "https://rubygems.org/"
17
+ gem.required_ruby_version = '>=2.1.0'
18
+ gem.metadata["allowed_push_host"] = "https://rubygems.org/"
19
19
 
20
20
  # Manifest
21
21
  gem.files = `git ls-files`.split("\n") - Dir['tmp/**/*']
@@ -24,14 +24,8 @@ DESC
24
24
  gem.require_paths = ["lib"]
25
25
 
26
26
  gem.executables = Dir["bin/*"].map { |e| File.basename e }
27
- gem.add_runtime_dependency "ffi", ["~> 1.9"]
28
- unless RUBY_PLATFORM == "java"
29
- gem.add_runtime_dependency "RubyInline", ["~> 3.12"]
30
- end
31
-
32
27
  gem.add_development_dependency "rake", ["~> 10.4.2"]
33
28
  gem.add_development_dependency "rspec", ["~> 3.3.0"]
34
29
 
35
- gem.add_development_dependency "em-synchrony", ["~> 1.0.4"]
36
30
  gem.add_development_dependency "celluloid-io", ["~> 0.17.2"]
37
31
  end
data/spec/client_spec.rb CHANGED
@@ -1,119 +1,167 @@
1
+ require_relative "support/request_examples"
2
+
1
3
  RSpec.describe NETSNMP::Client do
2
4
  let(:host) { "localhost" }
3
- let(:host_options) { {
5
+
6
+ let(:device_options) { {
4
7
  peername: "localhost",
5
- port: SNMPPORT,
6
- username: "simulator",
7
- auth_password: "auctoritas",
8
- auth_protocol: :md5,
9
- priv_password: "privatus",
10
- priv_protocol: :des
8
+ port: SNMPPORT
11
9
  } }
12
-
13
- subject { described_class.new(host, options) }
14
-
15
- describe "establishing session" do
16
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
17
- context "with a wrong auth password" do
18
- let(:options) { host_options.merge( auth_password: "auctoritas2", timeout: 5) }
19
- it {
20
- expect {
21
- subject.get(oid)
22
- }.to raise_error(NETSNMP::ConnectionFailed)
10
+ describe "v1" do
11
+ it_behaves_like "an snmp client" do
12
+ let(:protocol_options) { {
13
+ version: "1",
14
+ community: "public"
15
+ } }
16
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
17
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
18
+ let(:walk_oid) { "1.3.6.1.2.1.1" }
19
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
20
+ let(:get_result) { "DEVICE-192.168.1.1" }
21
+ let(:next_result) { "The Cloud" }
22
+ let(:walk_result) { <<-WALK
23
+ 1.3.6.1.2.1.1.1.0: Device description
24
+ 1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
25
+ 1.3.6.1.2.1.1.3.0: 78171676
26
+ 1.3.6.1.2.1.1.4.0: The Owner
27
+ 1.3.6.1.2.1.1.5.0: DEVICE-192.168.1.1
28
+ 1.3.6.1.2.1.1.6.0: The Cloud
29
+ 1.3.6.1.2.1.1.7.0: 72
30
+ 1.3.6.1.2.1.1.8.0: 0
31
+ WALK
23
32
  }
33
+ let(:set_oid_result) { 43 }
24
34
  end
25
- context "with a wrong priv password" do
26
- let(:options) { host_options.merge( priv_password: "privatus2", timeout: 5) }
27
- it {
28
- expect {
29
- subject.get(oid)
30
- }.to raise_error(NETSNMP::ConnectionFailed)
35
+ end
36
+ describe "v2" do
37
+ it_behaves_like "an snmp client" do
38
+ let(:protocol_options) { {
39
+ version: "2c",
40
+ community: "public"
41
+ } }
42
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
43
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
44
+ let(:walk_oid) { "1.3.6.1.2.1.1" }
45
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" }
46
+ let(:get_result) { "DEVICE-192.168.1.1" }
47
+ let(:next_result) { "The Cloud" }
48
+ let(:walk_result) { <<-WALK
49
+ 1.3.6.1.2.1.1.1.0: Device description
50
+ 1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
51
+ 1.3.6.1.2.1.1.3.0: 78171676
52
+ 1.3.6.1.2.1.1.4.0: The Owner
53
+ 1.3.6.1.2.1.1.5.0: DEVICE-192.168.1.1
54
+ 1.3.6.1.2.1.1.6.0: The Cloud
55
+ 1.3.6.1.2.1.1.7.0: 72
56
+ 1.3.6.1.2.1.1.8.0: 0
57
+ WALK
31
58
  }
32
- end
59
+ let(:set_oid_result) { 43 }
33
60
 
34
- context "with an unexisting user" do
35
- let(:options) { host_options.merge(username: "simulata", timeout: 5) }
36
- it {
37
- expect {
38
- subject.get(oid)
39
- }.to raise_error(NETSNMP::ConnectionFailed)
40
- }
41
61
  end
42
62
  end
43
63
 
44
- describe "#get" do
45
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
46
- let(:value) { subject.get(oid) }
47
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
48
- it "fetches the varbinds for a given oid" do
49
- expect(value).to eq("tt")
50
- end
51
- end
52
64
 
53
- describe "#get_next" do
54
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
55
- let(:value) { subject.get_next(oid) }
56
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
57
- it "fetches the varbinds for the next oid" do
58
- expect(value).to start_with("KK12")
59
- end
60
- end
65
+ describe "v3" do
66
+ let(:extra_options) { {} }
67
+ let(:version_options) { {
68
+ version: "3",
69
+ context: "a172334d7d97871b72241397f713fa12",
70
+ } }
71
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
72
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
73
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
74
+ let(:walk_oid) { "1.3.6.1.2.1.1.9.1.3" }
75
+ let(:get_result) { "tt" }
76
+ let(:next_result) { "KK12" }
77
+ let(:walk_result) { <<-WALK
78
+ 1.3.6.1.2.1.1.9.1.3.1: The SNMP Management Architecture MIB.
79
+ 1.3.6.1.2.1.1.9.1.3.2: The MIB for Message Processing and Dispatching.
80
+ 1.3.6.1.2.1.1.9.1.3.3: The management information definitions for the SNMP User-based Security Model.
81
+ 1.3.6.1.2.1.1.9.1.3.4: The MIB module for SNMPv2 entities
82
+ 1.3.6.1.2.1.1.9.1.3.5: The MIB module for managing TCP implementations
83
+ 1.3.6.1.2.1.1.9.1.3.6: The MIB module for managing IP and ICMP implementations
84
+ 1.3.6.1.2.1.1.9.1.3.7: The MIB module for managing UDP implementations
85
+ 1.3.6.1.2.1.1.9.1.3.8: View-based Access Control Model for SNMP.
86
+ WALK
87
+ }
88
+ let(:set_oid_result) { 43}
89
+ context "with a no auth no priv policy" do
90
+ let(:user_options) { { username: "unsafe", security_level: :noauth } }
91
+ it_behaves_like "an snmp client" do
92
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
93
+ # why is this here? that variation/notification community causes the simulagtor to go down
94
+ # until I find the origin of the issue and patched it with an appropriated community, this
95
+ # is here so that I test the set call at least once, although I'm sure it'll work always
96
+ # for v3
97
+ describe "#set" do
98
+ let(:extra_options) { { #community: "variation/notification",
99
+ context: "0886e1397d572377c17c15036a1e6c66" } }
100
+ it "updates the value of the oid" do
101
+ prev_value = subject.get(oid: set_oid)
102
+ expect(prev_value).to be_a(Integer)
103
+
104
+ # without type
105
+ subject.set(oid: set_oid, value: set_oid_result)
106
+ expect(subject.get(oid: set_oid)).to eq(set_oid_result)
61
107
 
62
- describe "#walk" do
63
- let(:oid) { "1.3.6.1.2.1.1.9.1.3" } # sysORDescr
64
- let(:value) { subject.walk(oid) }
65
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
66
- it "fetches the varbinds for the next oid" do
67
- expect(value.next).to eq(["#{oid}.1","The SNMP Management Architecture MIB."])
68
- expect(value.next).to eq(["#{oid}.2","The MIB for Message Processing and Dispatching."])
69
- expect(value.next).to eq(["#{oid}.3","The management information definitions for the SNMP User-based Security Model."])
70
- expect(value.next).to eq(["#{oid}.4","The MIB module for SNMPv2 entities"])
71
- expect(value.next).to eq(["#{oid}.5","The MIB module for managing TCP implementations"])
72
- expect(value.next).to eq(["#{oid}.6","The MIB module for managing IP and ICMP implementations"])
73
- expect(value.next).to eq(["#{oid}.7","The MIB module for managing UDP implementations"])
74
- expect(value.next).to eq(["#{oid}.8","View-based Access Control Model for SNMP."])
75
- expect{ value.next }.to raise_error(StopIteration)
76
- end
77
- end
108
+ subject.set(oid: set_oid, value: prev_value)
109
+ end
110
+ end
78
111
 
79
- describe "#get_bulk" do
80
- let(:oid) { "1.3.6.1.2.1.1.9.1.3" }
81
- let(:value) { subject.get_bulk(oid) }
82
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
83
- it "fetches the varbinds for the next oid" do
84
- expect(value.next).to eq(["#{oid}.1","The SNMP Management Architecture MIB."])
85
- expect(value.next).to eq(["#{oid}.2","The MIB for Message Processing and Dispatching."])
86
- expect(value.next).to eq(["#{oid}.3","The management information definitions for the SNMP User-based Security Model."])
87
- expect(value.next).to eq(["#{oid}.4","The MIB module for SNMPv2 entities"])
88
- expect(value.next).to eq(["#{oid}.5","The MIB module for managing TCP implementations"])
89
- expect(value.next).to eq(["#{oid}.6","The MIB module for managing IP and ICMP implementations"])
90
- expect(value.next).to eq(["#{oid}.7","The MIB module for managing UDP implementations"])
91
- expect(value.next).to eq(["#{oid}.8","View-based Access Control Model for SNMP."])
92
- expect(value.next).to eq(["1.3.6.1.2.1.1.9.1.4.1",2])
93
- expect(value.next).to eq(["1.3.6.1.2.1.1.9.1.4.2",2])
94
- expect{ value.next }.to raise_error(StopIteration)
112
+ end
95
113
  end
96
- end
97
-
98
-
99
- # TODO: use this oid to test error calls
100
- # let(:oid) { "SNMPv2-MIB::sysORDescr.1" }
114
+ context "with an only auth policy" do
115
+ context "speaking md5" do
116
+ let(:user_options) { { username: "authmd5", security_level: :auth_no_priv,
117
+ auth_password: "maplesyrup", auth_protocol: :md5 } }
118
+ it_behaves_like "an snmp client" do
119
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
120
+ end
121
+ end
122
+ context "speaking sha" do
123
+ let(:user_options) { { username: "authsha", security_level: :auth_no_priv,
124
+ auth_password: "maplesyrup", auth_protocol: :sha } }
125
+ it_behaves_like "an snmp client" do
126
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
127
+ end
128
+ end
101
129
 
102
- describe "#set" do
103
- let(:options) { host_options.merge(context: "0886e1397d572377c17c15036a1e6c66") } # write cache
104
- let(:oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
105
- let(:new_value) { 43 }
106
- after { subject.set(oid, value: 42) }
107
- it "updates the value of the oid" do
108
- expect(subject.get(oid)).to be(42)
109
-
110
- # without type
111
- subject.set(oid, value: 43)
112
- expect(subject.get(oid)).to be(43)
113
-
114
- subject.set(oid, value: 44, type: :integer)
115
- expect(subject.get(oid)).to be(44)
130
+ end
131
+ context "with an auth priv policy" do
132
+ context "auth in md5, encrypting in des" do
133
+ let(:user_options) { { username: "authprivmd5des", auth_password: "maplesyrup",
134
+ auth_protocol: :md5, priv_password: "maplesyrup",
135
+ priv_protocol: :des } }
136
+ it_behaves_like "an snmp client" do
137
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
138
+ end
139
+ end
140
+ context "auth in sha, encrypting in des" do
141
+ let(:user_options) { { username: "authprivshades", auth_password: "maplesyrup",
142
+ auth_protocol: :sha, priv_password: "maplesyrup",
143
+ priv_protocol: :des } }
144
+ it_behaves_like "an snmp client" do
145
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
146
+ end
147
+ end
116
148
 
149
+ context "auth in md5, encrypting in aes" do
150
+ let(:user_options) { { username: "authprivmd5aes", auth_password: "maplesyrup",
151
+ auth_protocol: :md5, priv_password: "maplesyrup",
152
+ priv_protocol: :aes } }
153
+ it_behaves_like "an snmp client" do
154
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
155
+ end
156
+ end
157
+ context "auth in sha, encrypting in aes" do
158
+ let(:user_options) { { username: "authprivshaaes", auth_password: "maplesyrup",
159
+ auth_protocol: :sha, priv_password: "maplesyrup",
160
+ priv_protocol: :aes } }
161
+ it_behaves_like "an snmp client" do
162
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
163
+ end
164
+ end
117
165
  end
118
166
  end
119
167
  end