netsnmp 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 615bdc207baf5d3c7db16cfe106324acbc2f434937366ed6750d653df712f36c
4
- data.tar.gz: d1601c013dadf943eb202964c43c2ac6a17eb40dddb9544577d901513eedcf08
3
+ metadata.gz: d6bb62b9abd416188660e04be1c12cf009b1df0e307030b9c239ea4b2acd73cc
4
+ data.tar.gz: ee88f7eb292f1a0077ab25e4677713290447e0e7755049bbe6db50f07d15d6a1
5
5
  SHA512:
6
- metadata.gz: f3fbc65c63d1c3c8d0711e8c2c225d3d0442211f8875befa0c62b0de44dbe5e9e22d03b0e55ac49cf05bbac80c282be59c73f21503166c1582389e196b3948a7
7
- data.tar.gz: 473a0f7f7f9f6d8fb9522bd809a7acd9644128bfdd471839a63e0ffb9b825b066cc1eb5e1be45f6a703fe94e18764212f6305b5f147ed04495eede058eb24b3b
6
+ metadata.gz: fc90cc626d4be2a04d598ec267bcfc108e87aea8e8a585a7611033fc56cb6c174a222250bb9eeeb05b2d03d058983b106c92c30ba3d91e922b171ecfbc37041a
7
+ data.tar.gz: '09dbbb277ae24d9b760c0de70738a02037da527d653d5e003632c1b41d808cc21c44034fb51bec63394a132fe3c30ffaac1adc846dc061ca483e13fc0719af97'
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # netsnmp
2
2
 
3
- [![Build Status](https://travis-ci.org/swisscom/ruby-netsnmp.svg?branch=master)](https://travis-ci.org/swisscom/ruby-netsnmp)
4
- [![Coverage Status](https://coveralls.io/repos/github/swisscom/ruby-netsnmp/badge.svg?branch=master)](https://coveralls.io/github/swisscom/ruby-netsnmp?branch=master)
3
+ ![Tests](https://github.com/swisscom/ruby-netsnmp/workflows/Tests/badge.svg)
5
4
  [![Code Climate](https://codeclimate.com/github/swisscom/ruby-netsnmp/badges/gpa.svg)](https://codeclimate.com/github/swisscom/ruby-netsnmp)
6
5
  [![Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/github/swisscom/ruby-netsnmp/master)
7
6
 
@@ -223,6 +222,7 @@ All encoding/decoding/encryption/decryption/digests are done using `openssl`, wh
223
222
 
224
223
  This library uses RSpec. The client specs are "integration" tests, in that we communicate with an [snmpsim-built snmp agent simulator](https://github.com/etingof/snmpsim).
225
224
 
225
+
226
226
  ### RSpec
227
227
 
228
228
  You can run all tests by typing:
@@ -234,37 +234,31 @@ You can run all tests by typing:
234
234
  ...
235
235
  ```
236
236
 
237
- ### SNMP Simulator
238
-
239
- You can install the package yourself (ex: `pip install snmpsim`) and run the server locally, and then set the `SNMP_PORT` environment variable, where the snmp simulator is running.
240
237
 
241
- #### Docker
238
+ ### Docker
242
239
 
243
- The preferred way to use the snmp simulator is by using docker.
244
-
245
- In order to start the simulator container, run:
240
+ The most straightforward way of running the tests is by using the `docker-compose` setup (which is also what's used in the CI). Run it against the ruby version you're targeting:
246
241
 
247
242
  ```
248
- > spec/support/spec.sh start
243
+ > docker-compose -f docker-compose.yml -f docker-compose-ruby-${RUBY_MAJOR_VERSION}.${RUBY_MAJOR_VERSION}.yml run netsnmp
249
244
  ```
250
245
 
251
- after, you just need to set the `SNMP_PORT` variable to the port found typing:
246
+ The CI runs the tests against all supported ruby versions. If changes break a specific version of ruby, make sure you commit appropriate changes addressing the edge case, or let me know in the issues board, so I can help.
252
247
 
253
- ```
254
- > docker port test-snmp 1161/udp
255
- ```
248
+ ### SNMP Simulator
256
249
 
257
- and run the tests.
250
+ The SNMP simulator runs in its own container in the `docker` setup.
258
251
 
259
- #### CI
252
+ You can install the package yourself (ex: `pip install snmpsim`) and run the server locally, and then set the `SNMP_PORT` environment variable, where the snmp simulator is running.
260
253
 
261
- If you want to replicate what the CI is doing, just do:
254
+ #### CI
262
255
 
263
- ```
264
- > spec/support/spec.sh run
265
- ```
256
+ The job of the CI is:
266
257
 
267
- Which should: build and run the simulator container, run the tests, run rubocop, and remove all artifacts.
258
+ * Run all the tests;
259
+ * Make sure the tests cover an appropriate surface of the code;
260
+ * Lint the code;
261
+ * (for ruby 3.0) type check the code;
268
262
 
269
263
 
270
264
  ## Contributing
@@ -34,6 +34,18 @@ rescue LoadError
34
34
  end
35
35
 
36
36
  module NETSNMP
37
+ module StringExtensions
38
+ # If you wonder why this is there: the oauth feature uses a refinement to enhance the
39
+ # Regexp class locally with #match? , but this is never tested, because ActiveSupport
40
+ # monkey-patches the same method... Please ActiveSupport, stop being so intrusive!
41
+ # :nocov:
42
+ refine(String) do
43
+ def match?(*args)
44
+ !match(*args).nil?
45
+ end
46
+ end
47
+ end
48
+
37
49
  def self.debug=(io)
38
50
  @debug_output = io
39
51
  end
@@ -23,8 +23,7 @@ module NETSNMP
23
23
  # puts client.get(oid: "1.3.6.1.2.1.1.5.0")
24
24
  # end
25
25
  #
26
- def initialize(**options)
27
- version = options[:version]
26
+ def initialize(version: nil, **options)
28
27
  version = case version
29
28
  when Integer then version # assume the use know what he's doing
30
29
  when /v?1/ then 0
@@ -33,7 +32,7 @@ module NETSNMP
33
32
  end
34
33
 
35
34
  @retries = options.fetch(:retries, RETRIES)
36
- @session ||= version == 3 ? V3Session.new(options) : Session.new(options)
35
+ @session ||= version == 3 ? V3Session.new(**options) : Session.new(version: version, **options)
37
36
  return unless block_given?
38
37
  begin
39
38
  yield self
@@ -4,13 +4,14 @@ module NETSNMP
4
4
  # Abstracts the OID structure
5
5
  #
6
6
  module OID
7
+ using StringExtensions unless String.method_defined?(:match?)
8
+
7
9
  OIDREGEX = /^[\d\.]*$/
8
10
 
9
11
  module_function
10
12
 
11
13
  def build(o)
12
14
  case o
13
- when OID then o
14
15
  when Array
15
16
  o.join(".")
16
17
  when OIDREGEX
@@ -29,7 +30,7 @@ module NETSNMP
29
30
  # @return [true, false] whether the given OID belongs to the sub-tree
30
31
  #
31
32
  def parent?(parent_oid, child_oid)
32
- child_oid.match(/\A#{parent_oid}\./)
33
+ child_oid.match?(/\A#{parent_oid}\./)
33
34
  end
34
35
  end
35
36
  end
@@ -55,7 +55,7 @@ module NETSNMP
55
55
  when :response then 2
56
56
  else raise Error, "#{type} is not supported as type"
57
57
  end
58
- new(args.merge(type: typ))
58
+ new(type: typ, **args)
59
59
  end
60
60
  end
61
61
 
@@ -64,7 +64,7 @@ module NETSNMP
64
64
  attr_reader :version, :community, :request_id
65
65
 
66
66
  def initialize(type:, headers:,
67
- request_id: nil,
67
+ request_id: SecureRandom.random_number(MAXREQUESTID),
68
68
  error_status: 0,
69
69
  error_index: 0,
70
70
  varbinds: [])
@@ -75,9 +75,9 @@ module NETSNMP
75
75
  @type = type
76
76
  @varbinds = []
77
77
  varbinds.each do |varbind|
78
- add_varbind(varbind)
78
+ add_varbind(**varbind)
79
79
  end
80
- @request_id = request_id || SecureRandom.random_number(MAXREQUESTID)
80
+ @request_id = request_id
81
81
  check_error_status(@error_status)
82
82
  end
83
83
 
@@ -9,6 +9,8 @@ module NETSNMP
9
9
  super(type: type, headers: [3, nil], **options)
10
10
  end
11
11
 
12
+ private
13
+
12
14
  def encode_headers_asn
13
15
  [OpenSSL::ASN1::OctetString.new(@engine_id || ""),
14
16
  OpenSSL::ASN1::OctetString.new(@context || "")]
@@ -24,7 +24,7 @@ module NETSNMP
24
24
 
25
25
  # @param [String] username the snmp v3 username
26
26
  # @param [String] engine_id the device engine id (initialized to '' for report)
27
- # @param [Symbol, integer] security_level allowed snmp v3 security level (:auth_priv, :auh_no_priv, etc)
27
+ # @param [Symbol, integer] security_level allowed snmp v3 security level (:auth_priv, :auth_no_priv, etc)
28
28
  # @param [Symbol, nil] auth_protocol a supported authentication protocol (currently supported: :md5, :sha)
29
29
  # @param [Symbol, nil] priv_protocol a supported privacy protocol (currently supported: :des, :aes)
30
30
  # @param [String, nil] auth_password the authentication password
@@ -99,7 +99,7 @@ module NETSNMP
99
99
  # @note this method is used in the process of authenticating a message
100
100
  def sign(message)
101
101
  # don't sign unless you have to
102
- return nil unless @auth_protocol
102
+ return unless @auth_protocol
103
103
 
104
104
  key = auth_key.dup
105
105
 
@@ -211,7 +211,7 @@ module NETSNMP
211
211
  end
212
212
 
213
213
  def authorizable?
214
- @auth_protocol && @auth_protocol != :none
214
+ @auth_protocol != :none
215
215
  end
216
216
  end
217
217
  end
@@ -10,7 +10,7 @@ module NETSNMP
10
10
  def initialize(version: 1, community: "public", **options)
11
11
  @version = version
12
12
  @community = community
13
- validate(options)
13
+ validate(**options)
14
14
  end
15
15
 
16
16
  # Closes the session
@@ -36,23 +36,20 @@ module NETSNMP
36
36
  # @return [NETSNMP::PDU] the response pdu
37
37
  #
38
38
  def send(pdu)
39
- encoded_request = encode(pdu)
39
+ encoded_request = pdu.to_der
40
40
  encoded_response = @transport.send(encoded_request)
41
- decode(encoded_response)
41
+ PDU.decode(encoded_response)
42
42
  end
43
43
 
44
44
  private
45
45
 
46
- def validate(**options)
47
- proxy = options[:proxy]
46
+ def validate(host: nil, port: 161, proxy: nil, timeout: TIMEOUT, **)
48
47
  if proxy
49
48
  @proxy = true
50
49
  @transport = proxy
51
50
  else
52
- host, port = options.values_at(:host, :port)
53
51
  raise "you must provide an hostname/ip under :host" unless host
54
- port ||= 161 # default snmp port
55
- @transport = Transport.new(host, port.to_i, timeout: options.fetch(:timeout, TIMEOUT))
52
+ @transport = Transport.new(host, port.to_i, timeout: timeout)
56
53
  end
57
54
  @version = case @version
58
55
  when Integer then @version # assume the use know what he's doing
@@ -64,14 +61,6 @@ module NETSNMP
64
61
  end
65
62
  end
66
63
 
67
- def encode(pdu)
68
- pdu.to_der
69
- end
70
-
71
- def decode(stream)
72
- PDU.decode(stream)
73
- end
74
-
75
64
  class Transport
76
65
  MAXPDUSIZE = 0xffff + 1
77
66
 
@@ -4,7 +4,7 @@ module NETSNMP
4
4
  # Abstraction for the v3 semantics.
5
5
  class V3Session < Session
6
6
  # @param [String, Integer] version SNMP version (always 3)
7
- def initialize(version: 3, context: "", **opts)
7
+ def initialize(context: "", **opts)
8
8
  @context = context
9
9
  @security_parameters = opts.delete(:security_parameters)
10
10
  super
@@ -19,8 +19,10 @@ module NETSNMP
19
19
  end
20
20
 
21
21
  # @see {NETSNMP::Session#send}
22
- def send(*)
23
- pdu, = super
22
+ def send(pdu)
23
+ encoded_request = encode(pdu)
24
+ encoded_response = @transport.send(encoded_request)
25
+ pdu, = decode(encoded_response)
24
26
  pdu
25
27
  end
26
28
 
@@ -6,7 +6,7 @@ module NETSNMP
6
6
  class Varbind
7
7
  attr_reader :oid, :value
8
8
 
9
- def initialize(oid, value: nil, type: nil, **_opts)
9
+ def initialize(oid, value: nil, type: nil)
10
10
  @oid = OID.build(oid)
11
11
  @type = type
12
12
  @value = convert_val(value) if value
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NETSNMP
4
- VERSION = "0.1.9"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -0,0 +1,24 @@
1
+ module NETSNMP
2
+ class Client
3
+
4
+ def get: (*untyped) -> untyped
5
+ | (*untyped) { (PDU) -> void } -> untyped
6
+
7
+ def get_next: (*untyped) -> untyped
8
+ | (*untyped) { (PDU) -> void } -> untyped
9
+
10
+ def set: (*untyped) -> untyped
11
+ | (*untyped) { (PDU) -> void } -> untyped
12
+
13
+ def inform: (*untyped) -> untyped
14
+ | (*untyped) { (PDU) -> void } -> untyped
15
+
16
+ def walk: (oid: oid) -> _Each[oid_type, oid_value]
17
+
18
+ def close: () -> void
19
+
20
+ private
21
+
22
+ def initialize: (?version?: snmp_version, **untyped) -> untyped
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ module NETSNMP
2
+ module Message
3
+ def self?.decode: (String stream, security_parameters: SecurityParameters) -> [ScopedPDU, String, Integer, Integer]
4
+
5
+ def self?.encode: (ScopedPDU pdu, security_parameters: SecurityParameters, ?engine_boots: Integer, ?engine_time: Integer) -> String
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ module NETSNMP
2
+ interface _Logger
3
+ def <<: (string) -> void
4
+ end
5
+
6
+ interface _Authenticate
7
+ def reset: () -> void
8
+ def <<: (string) -> void
9
+ def digest: () -> String
10
+ end
11
+
12
+ interface _Encrypt
13
+ def encrypt: (String payload, engine_boots: Integer, engine_time: Integer) -> String
14
+
15
+ def decrypt: (String payload, salt: String, engine_boots: Integer, engine_time: Integer) -> String
16
+ end
17
+
18
+ type snmp_version = 0 | 1 | 3 | :v1 | :v2c | :v3 | nil
19
+
20
+ def self.debug=: (_Logger) -> void
21
+
22
+ def self.debug: { () -> string } -> void
23
+ end
@@ -0,0 +1,18 @@
1
+ module NETSNMP
2
+ type oid = String | Array[Integer]
3
+
4
+ type oid_type = Integer | :ipaddress | :counter32 | :gauge | :timetick | :opaque | :nsap | :counter64 | :uinteger
5
+
6
+ type oid_value = String | Integer | Timetick | true | false | nil | IPAddr
7
+
8
+ # type oid_options = {}
9
+
10
+ module OID
11
+
12
+ def self?.build: (oid) -> String
13
+
14
+ def self?.to_asn: (String oid) -> OpenSSL::ASN1::ObjectId
15
+
16
+ def self?.parent?: (String oid, String oid) -> bool
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module OpenSSL
2
+ module ASN1
3
+ class ASN1Data
4
+ end
5
+ class ObjectId < ASN1Data
6
+ end
7
+ class Primitive < ASN1Data
8
+ end
9
+ class Integer < ASN1Data
10
+ end
11
+ class OctetString < ASN1Data
12
+ end
13
+ class Sequence < ASN1Data
14
+ end
15
+ end
16
+ end
17
+
18
+ interface _ToAsn
19
+ def to_asn: () -> OpenSSL::ASN1::ASN1Data
20
+ end
@@ -0,0 +1,48 @@
1
+ module NETSNMP
2
+ type pdu_type = :get | :getnext | :set | :inform | :trap | :response
3
+
4
+ class PDU
5
+
6
+ # type pdu_options = {
7
+ # headers: [snmp_version?, String?],
8
+ # ?request_id: String,
9
+ # ?error_status: Integer,
10
+ # ?error_index: Integer,
11
+ # ?varbinds: Array[varbind_options]
12
+ # }
13
+
14
+ attr_reader varbinds: Array[Varbind]
15
+ attr_reader type: pdu_type
16
+ attr_reader version: snmp_version
17
+ attr_reader community: String
18
+ attr_reader request_id: Integer
19
+
20
+ def self.decode: (String der) -> PDU
21
+ | (OpenSSL::ASN1::ASN1Data der) -> PDU
22
+
23
+ def self.build: (pdu_type, **untyped) -> PDU
24
+
25
+
26
+ def to_asn: () -> OpenSSL::ASN1::ASN1Data
27
+
28
+ def to_der: () -> String
29
+
30
+ def add_varbind: (oid: oid, **varbind_options) -> void
31
+ alias << add_varbind
32
+
33
+ private
34
+
35
+ def initialize: (
36
+ type: Integer,
37
+ headers: [snmp_version?, String?],
38
+ ?request_id: Integer,
39
+ ?error_status: Integer,
40
+ ?error_index: Integer,
41
+ ?varbinds: Array[varbind_options]
42
+ ) -> untyped
43
+
44
+ def encode_headers_asn: () -> [OpenSSL::ASN1::Integer, OpenSSL::ASN1::OctetString]
45
+
46
+ def check_error_status: (Integer) -> void
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ module NETSNMP
2
+ class ScopedPDU < PDU
3
+ attr_reader engine_id: String
4
+
5
+ private
6
+
7
+ def initialize: (
8
+ type: Integer,
9
+ headers: [String?, String?],
10
+ **untyped
11
+ ) -> void
12
+
13
+ def encode_headers_asn: () -> [OpenSSL::ASN1::OctetString, OpenSSL::ASN1::OctetString]
14
+ end
15
+ end
@@ -0,0 +1,56 @@
1
+ module NETSNMP
2
+ class SecurityParameters
3
+ type security_level = :noauth | :auth_no_priv | :auth_priv | 0 | 1 | 3 | nil
4
+
5
+ type auth_protocol = :md5 | :sha
6
+ type priv_protocol = :des | :aes
7
+
8
+
9
+ @auth_protocol: auth_protocol?
10
+ @auth_password: String?
11
+ @priv_protocol: priv_protocol?
12
+ @priv_password: String?
13
+ @digest: _Authenticate?
14
+ @encryption: _Encrypt?
15
+
16
+ attr_reader security_level: security_level
17
+ attr_reader username: String
18
+ attr_reader engine_id: String
19
+
20
+ def engine_id=: (String id) -> void
21
+
22
+ def encode: (_ToAsn, salt: OpenSSL::ASN1::ASN1Data, engine_time: Integer, engine_boots: Integer) -> [OpenSSL::ASN1::ASN1Data, OpenSSL::ASN1::ASN1Data]
23
+
24
+ def decode: (OpenSSL::ASN1::ASN1Data | String der, salt: OpenSSL::ASN1::ASN1Data | String, engine_time: Integer, engine_boots: Integer) -> OpenSSL::ASN1::ASN1Data
25
+
26
+ def sign: (String message) -> String?
27
+
28
+ def verify: (String stream, String salt) -> void
29
+
30
+ def must_revalidate?: () -> bool
31
+
32
+ private
33
+
34
+ def initialize: (
35
+ username: String,
36
+ ?engine_id: String,
37
+ ?security_level: security_level?,
38
+ ?auth_protocol: auth_protocol?,
39
+ ?auth_password: String?,
40
+ ?priv_protocol: priv_protocol?,
41
+ ?priv_password: String?,
42
+ ) -> untyped
43
+
44
+ def auth_key: () -> String
45
+
46
+ def priv_key: () -> String
47
+
48
+ def check_parameters: () -> void
49
+
50
+ def localize_key: (String key) -> String
51
+
52
+ def passkey: (String password) -> String
53
+
54
+ def authorizable?: () -> bool
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ module NETSNMP
2
+ class Session
3
+ @transport: _Transport
4
+ @version: 0 | 1 | 3
5
+ @community: String?
6
+
7
+ def close: () -> void
8
+
9
+ def build_pdu: (pdu_type, *untyped) -> PDU
10
+
11
+ def send: (PDU) -> PDU
12
+
13
+ private
14
+
15
+ def initialize: (?version: snmp_version, ?community: String, **untyped) -> untyped
16
+
17
+ def validate: (?host: String?, ?port: Integer, ?proxy: _Transport, ?timeout: Integer, **untyped) -> void
18
+
19
+ class Transport
20
+ def initialize: (String host, Integer port, timeout: Integer) -> untyped
21
+ def close: () -> void
22
+ def send: (String payload) -> String
23
+ def write: (String) -> void
24
+ def recv: () -> void
25
+
26
+ private
27
+
28
+ def wait: (:wait_readable | :wait_writable) -> void
29
+ end
30
+ end
31
+
32
+ interface _Transport
33
+ def close: () -> void
34
+ def send: (String payload) -> String
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module NETSNMP
2
+ class Timetick < Numeric
3
+ @ticks: Integer
4
+
5
+ def to_asn: () -> OpenSSL::ASN1::ASN1Data
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ module NETSNMP
2
+ class V3Session < Session
3
+
4
+ def build_pdu: (pdu_type, *untyped) -> ScopedPDU
5
+
6
+ def send: (ScopedPDU pdu) -> ScopedPDU
7
+ | (ScopedPDU pdu) -> [PDU, String, Integer, Integer]
8
+
9
+ private
10
+
11
+ def encode: (ScopedPDU) -> String
12
+
13
+ def initialize: (?context: String, **untyped) -> untyped
14
+
15
+ def security_parameters: () -> SecurityParameters
16
+
17
+ def probe_for_engine: () -> String
18
+
19
+ def decode: (String, ?security_parameters: SecurityParameters) -> [PDU, String, Integer, Integer]
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ module NETSNMP
2
+ type varbind_options = untyped
3
+
4
+ class Varbind
5
+
6
+ type varbind_value = OpenSSL::ASN1::OctetString | OpenSSL::ASN1::Primitive | OpenSSL::ASN1::ASN1Data | oid_value
7
+
8
+ attr_reader oid: String
9
+ attr_reader value: oid_value
10
+
11
+ def to_asn: () -> OpenSSL::ASN1::Sequence
12
+
13
+ def to_der: () -> String
14
+
15
+ def convert_val: (varbind_value) -> oid_value
16
+
17
+
18
+ def convert_to_asn: (oid_type, oid_value) -> OpenSSL::ASN1::ASN1Data
19
+
20
+ def convert_application_asn: (OpenSSL::ASN1::ASN1Data asn) -> oid_value
21
+
22
+ private
23
+
24
+ def initialize: (oid, ?value: varbind_value, ?type: oid_type) -> untyped
25
+
26
+ def unpack_32bit_integer: (String) -> Integer
27
+
28
+ def unpack_64bit_integer: (String) -> Integer
29
+ end
30
+ end
@@ -3,11 +3,11 @@
3
3
  require_relative "support/request_examples"
4
4
 
5
5
  RSpec.describe NETSNMP::Client do
6
- let(:host) { "localhost" }
6
+ let(:host) { SNMPHOST }
7
7
 
8
8
  let(:device_options) do
9
9
  {
10
- peername: "localhost",
10
+ peername: SNMPHOST,
11
11
  port: SNMPPORT
12
12
  }
13
13
  end
@@ -31,14 +31,15 @@ RSpec.describe "with cellulloid", type: :celluloid do
31
31
  WALK
32
32
  end
33
33
 
34
+ before(:all) { Celluloid.boot }
34
35
  around(:each) do |example|
35
36
  within_io_actor { example.run }
36
37
  end
37
- let(:proxy) { CelluloidHelpers::Proxy.new("localhost", SNMPPORT) }
38
+ let(:proxy) { CelluloidHelpers::Proxy.new(SNMPHOST, SNMPPORT) }
38
39
  after(:each) { proxy.close }
39
40
 
40
41
  it_behaves_like "an snmp client" do
41
- subject { NETSNMP::Client.new(options) }
42
+ subject { NETSNMP::Client.new(**options) }
42
43
  let(:device_options) { { proxy: proxy } }
43
44
  let(:protocol_options) { user_options }
44
45
  let(:extra_options) { { version: 3, context: "a172334d7d97871b72241397f713fa12" } }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe NETSNMP::Session do
4
- let(:host) { "localhost" }
4
+ let(:host) { SNMPHOST }
5
5
  let(:options) do
6
6
  {
7
7
  version: "2c",
@@ -9,6 +9,6 @@ RSpec.describe NETSNMP::Session do
9
9
  port: SNMPPORT
10
10
  }
11
11
  end
12
- subject { described_class.new(host, options) }
12
+ subject { described_class.new(host: host, **options) }
13
13
  after { subject.close }
14
14
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "simplecov" if ENV["COVERAGE"]
4
- require "coveralls"
5
- Coveralls.wear!
3
+ if ENV.key?("CI")
4
+ require "simplecov"
5
+ SimpleCov.command_name "#{RUBY_ENGINE}-#{RUBY_VERSION}"
6
+ SimpleCov.coverage_dir "coverage/#{RUBY_ENGINE}-#{RUBY_VERSION}"
7
+ end
6
8
 
7
9
  if defined?(SimpleCov)
8
10
  SimpleCov.start do
@@ -17,7 +19,8 @@ Bundler.require(:default, :test)
17
19
 
18
20
  require "netsnmp"
19
21
 
20
- SNMPPORT = (ENV["SNMP_PORT"] || 1161).to_i
22
+ SNMPPORT = ENV.fetch("SNMP_PORT", 1161).to_i
23
+ SNMPHOST = ENV.fetch("SNMP_HOST", "localhost")
21
24
 
22
25
  # This file was generated by the `rspec --init` command. Conventionally, all
23
26
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
@@ -3,7 +3,7 @@
3
3
  RSpec.shared_examples "an snmp client" do
4
4
  let(:device_options) do
5
5
  {
6
- host: "localhost",
6
+ host: SNMPHOST,
7
7
  port: SNMPPORT
8
8
  }
9
9
  end
@@ -11,7 +11,7 @@ RSpec.shared_examples "an snmp client" do
11
11
  let(:extra_options) { {} }
12
12
  let(:options) { protocol_options.merge(device_options).merge(extra_options) }
13
13
 
14
- subject { described_class.new(options) }
14
+ subject { described_class.new(**options) }
15
15
 
16
16
  describe "#get" do
17
17
  let(:value) { subject.get(oid: get_oid) }
@@ -7,19 +7,19 @@ RSpec.describe NETSNMP::V3Session do
7
7
  priv_protocol: :des, security_level: :auth_priv }
8
8
  end
9
9
  it "generates the security parameters handler" do
10
- sess = described_class.new(security_options.merge(host: "localhost", port: SNMPPORT))
10
+ sess = described_class.new(**security_options.merge(host: SNMPHOST, port: SNMPPORT))
11
11
  # not generated yet
12
12
  expect(sess.instance_variable_get(:@security_parameters)).to be_a(NETSNMP::SecurityParameters)
13
13
  end
14
14
 
15
15
  it "allows to pass a custom one" do
16
- sec_params = NETSNMP::SecurityParameters.new(security_options)
17
- sess = described_class.new(host: "localhost", port: SNMPPORT, security_parameters: sec_params)
16
+ sec_params = NETSNMP::SecurityParameters.new(**security_options)
17
+ sess = described_class.new(host: SNMPHOST, port: SNMPPORT, security_parameters: sec_params)
18
18
  # not generated yet
19
19
  expect(sess.instance_variable_get(:@security_parameters)).to be(sec_params)
20
20
  end
21
21
 
22
22
  it "fails if the pass object doesn't follow the expected api" do
23
- expect { described_class.new(host: "localhost", port: SNMPPORT, security_parameters: double) }.to raise_error(NETSNMP::Error)
23
+ expect { described_class.new(host: SNMPHOST, port: SNMPPORT, security_parameters: double) }.to raise_error(NETSNMP::Error)
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,75 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netsnmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-29 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 10.1.0
20
- - - "~>"
21
- - !ruby/object:Gem::Version
22
- version: '10.1'
23
- type: :development
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 10.1.0
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '10.1'
33
- - !ruby/object:Gem::Dependency
34
- name: rspec
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 3.5.0
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: '3.5'
43
- type: :development
44
- prerelease: false
45
- version_requirements: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 3.5.0
50
- - - "~>"
51
- - !ruby/object:Gem::Version
52
- version: '3.5'
53
- - !ruby/object:Gem::Dependency
54
- name: celluloid-io
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '0.17'
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 0.17.2
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '0.17'
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 0.17.2
11
+ date: 2020-12-18 00:00:00.000000000 Z
12
+ dependencies: []
73
13
  description: |2
74
14
  Wraps the net-snmp core usage into idiomatic ruby.
75
15
  It is designed to support as many environments and concurrency frameworks as possible.
@@ -78,17 +18,9 @@ executables: []
78
18
  extensions: []
79
19
  extra_rdoc_files: []
80
20
  files:
81
- - ".coveralls.yml"
82
- - ".gitignore"
83
- - ".rspec"
84
- - ".rubocop.yml"
85
- - ".rubocop_todo.yml"
86
- - ".travis.yml"
87
21
  - AUTHORS
88
- - Gemfile
89
22
  - LICENSE.txt
90
23
  - README.md
91
- - Rakefile
92
24
  - lib/netsnmp.rb
93
25
  - lib/netsnmp/client.rb
94
26
  - lib/netsnmp/encryption/aes.rb
@@ -105,7 +37,18 @@ files:
105
37
  - lib/netsnmp/v3_session.rb
106
38
  - lib/netsnmp/varbind.rb
107
39
  - lib/netsnmp/version.rb
108
- - netsnmp.gemspec
40
+ - sig/client.rbs
41
+ - sig/message.rbs
42
+ - sig/netsnmp.rbs
43
+ - sig/oid.rbs
44
+ - sig/openssl.rbs
45
+ - sig/pdu.rbs
46
+ - sig/scoped_pdu.rbs
47
+ - sig/security_parameters.rbs
48
+ - sig/session.rbs
49
+ - sig/timeticks.rbs
50
+ - sig/v3_session.rbs
51
+ - sig/varbind.rbs
109
52
  - spec/client_spec.rb
110
53
  - spec/handlers/celluloid_spec.rb
111
54
  - spec/oid_spec.rb
@@ -113,11 +56,8 @@ files:
113
56
  - spec/security_parameters_spec.rb
114
57
  - spec/session_spec.rb
115
58
  - spec/spec_helper.rb
116
- - spec/support/Dockerfile
117
59
  - spec/support/celluloid.rb
118
60
  - spec/support/request_examples.rb
119
- - spec/support/specs.sh
120
- - spec/support/stop_docker.sh
121
61
  - spec/timeticks_spec.rb
122
62
  - spec/v3_session_spec.rb
123
63
  - spec/varbind_spec.rb
@@ -126,7 +66,7 @@ licenses:
126
66
  - Apache-2.0
127
67
  metadata:
128
68
  allowed_push_host: https://rubygems.org/
129
- post_install_message:
69
+ post_install_message:
130
70
  rdoc_options: []
131
71
  require_paths:
132
72
  - lib
@@ -142,23 +82,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
82
  version: '0'
143
83
  requirements:
144
84
  - net-snmp
145
- rubygems_version: 3.0.6
146
- signing_key:
85
+ rubygems_version: 3.1.4
86
+ signing_key:
147
87
  specification_version: 4
148
88
  summary: SNMP Client library
149
89
  test_files:
90
+ - spec/timeticks_spec.rb
91
+ - spec/spec_helper.rb
92
+ - spec/session_spec.rb
150
93
  - spec/client_spec.rb
151
- - spec/handlers/celluloid_spec.rb
152
94
  - spec/oid_spec.rb
95
+ - spec/varbind_spec.rb
96
+ - spec/support/request_examples.rb
97
+ - spec/support/celluloid.rb
153
98
  - spec/pdu_spec.rb
154
99
  - spec/security_parameters_spec.rb
155
- - spec/session_spec.rb
156
- - spec/spec_helper.rb
157
- - spec/support/Dockerfile
158
- - spec/support/celluloid.rb
159
- - spec/support/request_examples.rb
160
- - spec/support/specs.sh
161
- - spec/support/stop_docker.sh
162
- - spec/timeticks_spec.rb
163
100
  - spec/v3_session_spec.rb
164
- - spec/varbind_spec.rb
101
+ - spec/handlers/celluloid_spec.rb
@@ -1 +0,0 @@
1
- service_name: travis-ci
data/.gitignore DELETED
@@ -1,14 +0,0 @@
1
- /coverage/
2
- /doc/
3
- /pkg/
4
- /tmp/
5
- /log/
6
- /.yardoc/
7
- /.bundle
8
- /Gemfile.lock
9
- /vendor
10
- .env
11
-
12
- *.DS_Store
13
- *.sw[po]
14
- *.nfs*
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --color
2
- --require spec_helper
3
- --format documentation
@@ -1,11 +0,0 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
- AllCops:
4
- TargetRubyVersion: 2.3
5
-
6
- Layout/IndentHeredoc:
7
- Enabled: false
8
-
9
- Style/NumericPredicate:
10
- Exclude:
11
- - lib/netsnmp.rb
@@ -1,69 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2018-02-07 22:49:11 +0000 using RuboCop version 0.52.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- Metrics/BlockLength:
10
- Max: 200
11
-
12
- # Offense count: 17
13
- Metrics/AbcSize:
14
- Max: 100
15
-
16
- # Offense count: 2
17
- # Configuration parameters: CountComments.
18
- Metrics/ClassLength:
19
- Max: 150
20
-
21
- # Offense count: 8
22
- Metrics/CyclomaticComplexity:
23
- Max: 20
24
-
25
- # Offense count: 22
26
- # Configuration parameters: CountComments.
27
- Metrics/MethodLength:
28
- Max: 50
29
-
30
- # Offense count: 2
31
- # Configuration parameters: CountKeywordArgs.
32
- Metrics/ParameterLists:
33
- Max: 7
34
-
35
- # Offense count: 1
36
- Metrics/PerceivedComplexity:
37
- Max: 9
38
-
39
- # Offense count: 10
40
- Style/Documentation:
41
- Exclude:
42
- - 'spec/**/*'
43
- - 'test/**/*'
44
- - 'lib/netsnmp.rb'
45
- - 'lib/netsnmp/encryption/aes.rb'
46
- - 'lib/netsnmp/encryption/des.rb'
47
- - 'lib/netsnmp/encryption/none.rb'
48
- - 'lib/netsnmp/scoped_pdu.rb'
49
- - 'lib/netsnmp/session.rb'
50
- - 'lib/netsnmp/timeticks.rb'
51
-
52
- # Offense count: 8
53
- # Cop supports --auto-correct.
54
- # Configuration parameters: Strict.
55
- Style/NumericLiterals:
56
- MinDigits: 11
57
-
58
- # Offense count: 264
59
- # Cop supports --auto-correct.
60
- # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
61
- # SupportedStyles: single_quotes, double_quotes
62
- Style/StringLiterals:
63
- EnforcedStyle: double_quotes
64
-
65
- # Offense count: 112
66
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
67
- # URISchemes: http, https
68
- Metrics/LineLength:
69
- Max: 189
@@ -1,28 +0,0 @@
1
- sudo: required
2
- services:
3
- - docker
4
-
5
- install:
6
- - gem i rubygems-update -v '<3' && update_rubygems
7
- - bundle install --path .bundle
8
-
9
- script:
10
- - spec/support/specs.sh run
11
-
12
- language: ruby
13
- rvm:
14
- - 2.1
15
- - 2.2
16
- - 2.3
17
- - 2.4
18
- - 2.5
19
- - 2.6
20
- - ruby-head
21
- - jruby-head
22
- - truffleruby
23
- matrix:
24
- allow_failures:
25
- - rvm: ruby-head
26
- - rvm: jruby-head
27
- # to figure out later
28
- - rvm: truffleruby
data/Gemfile DELETED
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org/"
4
- ruby RUBY_VERSION
5
-
6
- gemspec
7
-
8
- gem "coveralls", require: false
9
-
10
- group :development do
11
- gem "pry"
12
- end
13
-
14
- gem "nio4r", "~> 1.2" if RUBY_VERSION < "2.2"
15
-
16
- platforms :mri do
17
- gem "pry-byebug", require: false
18
- gem "stackprof", require: false
19
- gem "xorcist", require: false
20
- end
21
-
22
- gem "rubocop", "0.52.1", require: false
data/Rakefile DELETED
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "coveralls/rake/task"
6
- require "rubocop/rake_task"
7
-
8
- desc "runs the tests and sends to coveralls server"
9
- Coveralls::RakeTask.new
10
-
11
- desc "runs the tests"
12
- RSpec::Core::RakeTask.new
13
-
14
- desc "Run rubocop"
15
- task :rubocop do
16
- RuboCop::RakeTask.new
17
- end
18
-
19
- task default: [:spec]
20
-
21
- namespace :spec do
22
- desc "runs the tests in coverage mode"
23
- task :coverage do
24
- ENV["COVERAGE"] = "true"
25
- Rake::Task["spec"].execute
26
- end
27
-
28
- desc "runs tests, check coverage, pushes to coverage server"
29
- task ci: ["spec:coverage", "coveralls:push", "rubocop"]
30
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path("../lib/netsnmp/version", __FILE__)
4
-
5
- Gem::Specification.new do |gem|
6
- gem.name = "netsnmp"
7
- gem.summary = "SNMP Client library"
8
- gem.description = <<-DESC
9
- Wraps the net-snmp core usage into idiomatic ruby.
10
- It is designed to support as many environments and concurrency frameworks as possible.
11
- DESC
12
- gem.requirements = ["net-snmp"]
13
- gem.version = NETSNMP::VERSION
14
- gem.license = "Apache-2.0"
15
- gem.authors = ["Tiago Cardoso"]
16
- gem.email = "cardoso_tiago@hotmail.com"
17
- gem.homepage = ""
18
- gem.platform = Gem::Platform::RUBY
19
- gem.metadata["allowed_push_host"] = "https://rubygems.org/"
20
-
21
- # Manifest
22
- gem.files = `git ls-files`.split("\n") - Dir["tmp/**/*"]
23
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
- gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
25
- gem.require_paths = ["lib"]
26
-
27
- gem.add_development_dependency "rake", ["~> 10.1", ">= 10.1.0"]
28
- gem.add_development_dependency "rspec", ["~> 3.5", ">= 3.5.0"]
29
-
30
- gem.add_development_dependency "celluloid-io", ["~> 0.17", ">= 0.17.2"]
31
- end
@@ -1,14 +0,0 @@
1
- FROM python:2.7-alpine
2
- Maintainer Tiago Cardoso <cardoso_tiago@hotmail.com>
3
-
4
- RUN easy_install snmpsim==0.3.0
5
- RUN easy_install pycrypto==2.6.1
6
- EXPOSE 1161
7
- # Create non-privileged user
8
- RUN useradd -m snmp_server
9
-
10
-
11
- USER snmp_server
12
- ENTRYPOINT ["/usr/local/bin/snmpsimd.py"]
13
-
14
- CMD ["--help"]
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- function start {
4
- docker pull honeyryderchuck/snmp-server-emulator:latest
5
- docker run -d -p :1161/udp --name test-snmp -v $(pwd)/spec/support/snmpsim:/home/snmp_server/.snmpsim honeyryderchuck/snmp-server-emulator \
6
- --v3-engine-id=000000000000000000000002 \
7
- --agent-udpv4-endpoint=0.0.0.0:1161 --agent-udpv6-endpoint='[::0]:1161' \
8
- --v3-user=simulator --v3-auth-key=auctoritas --v3-priv-key=privatus \
9
- --v3-user=authmd5 --v3-auth-key=maplesyrup --v3-auth-proto=MD5 --v3-priv-proto=NONE \
10
- --v3-user=authsha --v3-auth-key=maplesyrup --v3-auth-proto=SHA --v3-priv-proto=NONE \
11
- --v3-user=authprivshaaes --v3-auth-key=maplesyrup --v3-auth-proto=SHA \
12
- --v3-priv-key=maplesyrup --v3-priv-proto=AES \
13
- --v3-user=authprivmd5aes --v3-auth-key=maplesyrup --v3-auth-proto=MD5 \
14
- --v3-priv-key=maplesyrup --v3-priv-proto=AES \
15
- --v3-user=authprivshades --v3-auth-key=maplesyrup --v3-auth-proto=SHA \
16
- --v3-priv-key=maplesyrup --v3-priv-proto=DES \
17
- --v3-user=authprivmd5des --v3-auth-key=maplesyrup --v3-auth-proto=MD5 \
18
- --v3-priv-key=maplesyrup --v3-priv-proto=DES \
19
- --v3-user=unsafe --v3-auth-proto=NONE --v3-priv-proto=NONE
20
-
21
- }
22
-
23
- function run {
24
- sleep 20 # give some time for the simulator to boot
25
-
26
- port="$(docker port test-snmp 1161/udp)"
27
- export SNMP_PORT=$(echo $port | cut -d':' -f2)
28
-
29
- bundle exec rake spec:ci
30
- }
31
-
32
- function finish {
33
- docker stop test-snmp
34
- docker rm test-snmp
35
- }
36
-
37
- trap finish EXIT
38
-
39
- case "$1" in
40
- start)
41
- start
42
- docker logs -f test-snmp
43
- ;;
44
- run)
45
- start
46
- run
47
- ;;
48
- *)
49
- echo $"Usage: $0 {start|run}"
50
- exit 1
51
- esac
@@ -1,5 +0,0 @@
1
- sudo docker stop test-snmp-emulator
2
- sudo docker rm test-snmp-emulator
3
- sudo docker rmi snmp-server-emulator
4
-
5
-