snmp-open 0.2.0 → 0.6.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
- SHA1:
3
- metadata.gz: eb1bfb86bae4239a253fa4528be54e46a30e770d
4
- data.tar.gz: 0574b00db365565c87e647314b00f34950ba8280
2
+ SHA256:
3
+ metadata.gz: 1362f32d8e43b509be4884b392c43689b9cba48c2e2d6f63c4912e645ba6fcc9
4
+ data.tar.gz: d751cce9e00204ae0b0d131120338ce3b7beaf1bbfb2e71f114c60f8c9bfdfa8
5
5
  SHA512:
6
- metadata.gz: db49e2407897332554aae593b909bb74db5878a6b2f5f72779bfe6fdd1be116c2579226811bca87814c5f2ae3f55678c4a9ccbfcebd0157ccc918a4b48bea0b4
7
- data.tar.gz: 98f0150f390faf0fe8f8cffb8e60c535aae051cda4bfa964900a4e2172449807c3e85fdcaccf9d2090c1a082084885a872d93402b423e6fa2abb94de797b086e
6
+ metadata.gz: 51603c2ee2b8d5077be2dcc8f26b74ad174d09a31fe6b6879343d98b33bba5f30f6246cf2ac3999f3a3aa46fda3b5cf7f849310016de5725cbdd0574741af99c
7
+ data.tar.gz: 2670576c9373c22e74e5bc7a118317ffdefb33d685ef654236e1ec5f369f9ac772d619ff7cfba3e8532ba52a5fc3b0d52bc67439cbeb96d84a08d6cc36f40819
@@ -0,0 +1,24 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest]
15
+ ruby: [2.4, 2.5, 2.6, 2.7, jruby, truffleruby]
16
+ runs-on: ${{ matrix.os }}
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - name: Run tests
24
+ run: bundle exec rake
@@ -0,0 +1,2 @@
1
+ Style/CommentedKeyword:
2
+ Enabled: false
@@ -1,39 +1,13 @@
1
1
  require 'open3'
2
+ require 'snmp/open/options'
2
3
 
3
4
  module SNMP
4
5
  class Open
5
6
  # Open3-based data source that executes an snmp* command and captures the
6
7
  # output
7
8
  class CommandReader
8
- # see snmpcmd(1) for explanation of options
9
- OPTIONS = {
10
- version: '-v',
11
- auth_password: '-A',
12
- auth_protocol: '-a',
13
- community: '-c',
14
- context: '-n',
15
- no_check_increasing: {
16
- 'snmpbulkwalk' => '-Cc',
17
- 'snmpwalk' => '-Cc'
18
- },
19
- numeric: '-On', # needed by parser, should always be enabled
20
- priv_password: '-X', # not recommended, see snmp.conf(5)
21
- priv_protocol: '-x',
22
- sec_level: '-l',
23
- sec_user: '-u',
24
- retries: '-r',
25
- timeout: '-t',
26
- host: nil
27
- }.freeze
28
-
29
- OPTION_VALUES = {
30
- no_check_increasing: {
31
- true => ''
32
- }.freeze
33
- }.freeze
34
-
35
9
  # +options+ accepts options dealing with making connections to the host,
36
- # including all of the options listed in the +OPTIONS+ constant hash.
10
+ # including all of the options listed in the +Options::MAP+ constant hash.
37
11
  # Other options can be given as strings (or any object with a suitable
38
12
  # +to_s+ method), e.g., these are equivalent:
39
13
  #
@@ -44,7 +18,9 @@ module SNMP
44
18
  @env = options.delete(:env)
45
19
  host = options.delete(:host) ||
46
20
  (raise ArgumentError, 'Host expected but not given')
47
- opts = merge_options(options).merge('-On' => nil, host => nil)
21
+ opts = Options::REQUIRED_BY_PARSER
22
+ .merge(merge_options(options))
23
+ .merge(host => nil)
48
24
  @command_options, @host_options = partition_options(opts)
49
25
  end
50
26
 
@@ -54,7 +30,7 @@ module SNMP
54
30
  else
55
31
  Open3.capture3(cli(cmd, oid, options))
56
32
  end
57
- raise CommandError, err.chomp unless err.empty?
33
+ raise_capture_errors(err)
58
34
  out
59
35
  end
60
36
 
@@ -65,6 +41,7 @@ module SNMP
65
41
  [
66
42
  command,
67
43
  *options.map { |k, v| "#{k}#{v}" },
44
+ *oid_options(id),
68
45
  *@host_options.map { |k, v| "#{k}#{v}" },
69
46
  *@command_options.fetch(command, {}).map { |k, v| "#{k}#{v}" },
70
47
  *id
@@ -73,11 +50,24 @@ module SNMP
73
50
 
74
51
  private
75
52
 
53
+ def raise_capture_errors(err)
54
+ case err
55
+ when /^Cannot find module \(([^)]+)\)/
56
+ raise UnknownMIBError, "Unknown MIB: #{Regexp.last_match(1)}"
57
+ when /^(\S+): Unknown Object Identifier$/
58
+ raise UnknownOIDError, "Unknown OID: #{Regexp.last_match(1)}"
59
+ when /^timeout/i
60
+ raise CommandTimeoutError, err.chomp
61
+ when /./
62
+ raise CommandError, err.chomp
63
+ end
64
+ end
65
+
76
66
  def merge_options(options = {})
77
67
  options.each_pair.with_object({}) do |(key, value), opts|
78
- if OPTIONS.key?(key)
79
- opts[OPTIONS[key]] =
80
- (OPTION_VALUES.fetch(key, {}).fetch(value, value) || next)
68
+ if Options::MAP.key?(key)
69
+ opts[Options::MAP[key]] =
70
+ (Options::VALUES.fetch(key, {}).fetch(value, value) || next)
81
71
  elsif key.is_a?(String)
82
72
  opts[key] = value
83
73
  else
@@ -86,6 +76,15 @@ module SNMP
86
76
  end
87
77
  end
88
78
 
79
+ # if the request OID is all-numeric, force numeric OID in the output
80
+ def oid_options(id)
81
+ if id =~ /[^0-9.]/
82
+ []
83
+ else
84
+ ['-On']
85
+ end
86
+ end
87
+
89
88
  def normalize_command(command)
90
89
  case command
91
90
  when Symbol then "snmp#{command}"
@@ -122,5 +121,8 @@ module SNMP
122
121
  end # class CommandReader
123
122
 
124
123
  class CommandError < RuntimeError; end
124
+ class CommandTimeoutError < CommandError; end
125
+ class UnknownMIBError < CommandError; end
126
+ class UnknownOIDError < CommandError; end
125
127
  end # class Open
126
128
  end # module SNMP
@@ -13,20 +13,37 @@ module SNMP
13
13
  # be used to generate a needed file, if the file is unavailable. Controlled
14
14
  # by the `warnings` option.
15
15
  class FileReader
16
+ DEFAULT_WARNING_FORMATTER = lambda { |gen, cmd, oid, outfile|
17
+ "#{gen.cli(cmd, oid)} > #{outfile}"
18
+ }
19
+
16
20
  def initialize(directory, options = {})
17
21
  @directory = directory
18
22
  @warnings = options.delete(:warnings)
19
- @command_generator =
20
- SNMP::Open::CommandReader.new(options.merge(host: '$OPTIONS'))
23
+ @make_directories = options.delete(:make_directories)
24
+ if @warnings && !@warnings.respond_to?(:call)
25
+ @warnings = DEFAULT_WARNING_FORMATTER
26
+ end
27
+ options[:host] ||= '$OPTIONS'
28
+ @command_generator = SNMP::Open::CommandReader.new(options)
21
29
  end
22
30
 
23
31
  def capture(cmd, oid, _options = {})
24
- outfile = File.join(cmd.to_s, oid)
25
- File.read(File.join(@directory, outfile))
32
+ mkdir(@directory, cmd.to_s) if @make_directories
33
+ outfile = File.join(@directory, cmd.to_s, oid)
34
+ File.read(outfile)
26
35
  rescue Errno::ENOENT => err
27
- warn "#{@command_generator.cli(cmd, oid)} > #{outfile}" if @warnings
36
+ if @warnings
37
+ warning = @warnings.call(@command_generator, cmd, oid, outfile)
38
+ warn warning
39
+ end
28
40
  raise err
29
41
  end
42
+
43
+ def mkdir(base, cmd)
44
+ Dir.mkdir(base) unless File.exist?(base)
45
+ Dir.mkdir(File.join(base, cmd)) unless File.exist?(File.join(base, cmd))
46
+ end
30
47
  end # class FileReader
31
48
  end # class Open
32
49
  end # module SNMP
@@ -0,0 +1,41 @@
1
+ module SNMP
2
+ class Open
3
+ class Options
4
+ # see snmpcmd(1) for explanation of options
5
+ MAP = {
6
+ version: '-v',
7
+ auth_password: '-A',
8
+ auth_protocol: '-a',
9
+ community: '-c',
10
+ context: '-n',
11
+ no_check_increasing: {
12
+ 'snmpbulkwalk' => '-Cc',
13
+ 'snmpwalk' => '-Cc'
14
+ },
15
+ no_units: '-OU',
16
+ non_symbolic: '-Oe',
17
+ numeric: '-On',
18
+ priv_password: '-X', # not recommended, see snmp.conf(5)
19
+ priv_protocol: '-x',
20
+ sec_level: '-l',
21
+ sec_user: '-u',
22
+ retries: '-r',
23
+ timeout: '-t',
24
+ host: nil
25
+ }.freeze
26
+
27
+ # On some systems, SNMP command outputs will include symbolic values
28
+ # and/or value units. The parser doesn't support these, so disable them.
29
+ REQUIRED_BY_PARSER = {
30
+ '-Oe' => nil,
31
+ '-OU' => nil
32
+ }.freeze
33
+
34
+ VALUES = {
35
+ no_check_increasing: {
36
+ true => ''
37
+ }.freeze
38
+ }.freeze
39
+ end # class Options
40
+ end # class Open
41
+ end # module SNMP
@@ -1,5 +1,7 @@
1
1
  require 'set'
2
2
  require 'shellwords'
3
+ require 'snmp/open/parser/constants'
4
+ require 'snmp/open/parser/value_parser'
3
5
 
4
6
  module SNMP
5
7
  class Open
@@ -11,10 +13,8 @@ module SNMP
11
13
 
12
14
  # convert SNMP command output into arrays
13
15
  class Parser
14
- NOSUCHOBJECT_STR =
15
- 'No Such Object available on this agent at this OID'.freeze
16
- NOSUCHINSTANCE_STR =
17
- 'No Such Instance currently exists at this OID'.freeze
16
+ include SNMP::Open::Parser::Constants
17
+ OID_RE = Regexp.union(/\S+-MIB::\S+/, /[0-9\.]+/)
18
18
 
19
19
  def initialize(oids)
20
20
  @oids = oids
@@ -22,11 +22,8 @@ module SNMP
22
22
 
23
23
  def parse(texts)
24
24
  columns = texts.map do |text|
25
- tokenized =
26
- text
27
- .gsub(NOSUCHOBJECT_STR, %("#{NOSUCHOBJECT_STR}"))
28
- .gsub(NOSUCHINSTANCE_STR, %("#{NOSUCHINSTANCE_STR}"))
29
- .shellsplit
25
+ clean = clean_input_text(text)
26
+ tokenized = clean.shellsplit
30
27
  parse_tokens(tokenized)
31
28
  end
32
29
 
@@ -35,7 +32,7 @@ module SNMP
35
32
 
36
33
  private
37
34
 
38
- def table(columns)
35
+ def align(columns)
39
36
  indexes = columns.first.map { |value| index_using_first_oid(value) }
40
37
  hash = columns.flat_map { |row| row.map { |v| [v.oid, v] } }.to_h
41
38
 
@@ -47,6 +44,16 @@ module SNMP
47
44
  end
48
45
  end
49
46
 
47
+ def clean_input_text(text)
48
+ text
49
+ .gsub(/\r\n|\n\r|\r/, "\n")
50
+ .gsub(/^(#{OID_RE})\s*=\s*(Opaque|STRING):\s*\n/,
51
+ %(\\1 = \\2: ""\n))
52
+ .gsub(/^(#{OID_RE}) = (Opaque|STRING): ((?!")[^\n]*)\n/,
53
+ %(\\1 = \\2: "\\3"\n))
54
+ .gsub(Static::ANY_MESSAGE, Static::QUOTED_MESSAGES)
55
+ end
56
+
50
57
  def index_using_first_oid(value)
51
58
  base = @oids.first
52
59
 
@@ -69,12 +76,12 @@ module SNMP
69
76
 
70
77
  objects
71
78
  rescue StopIteration
72
- return objects
79
+ objects
73
80
  end
74
81
 
75
82
  def parse_next_object(tokens)
76
83
  oid = tokens.next.sub(/\A\./, '')
77
- raise "Parse error at #{oid}" unless oid =~ /\A[0-9.]+\z/
84
+ raise "Parse error at #{oid}" unless oid =~ OID_RE
78
85
  equals = tokens.next
79
86
  raise "Parse error after #{oid}" unless equals == '='
80
87
  type, value = parse_type(tokens)
@@ -82,21 +89,16 @@ module SNMP
82
89
  end
83
90
 
84
91
  def parse_type(tokens)
85
- next_token = tokens.next
86
- type = next_token.match(/\A([A-Z]+):\z/) { |md| md[1] }
87
- type, value = parse_value(tokens, next_token, type)
88
- [type, Conversions.convert_value(type, value)]
92
+ token = tokens.next
93
+ type = token.match(/\A([-A-Za-z]+[0-9]*):\z/) { |md| md[1] }
94
+ ValueParser.find(type, token).parse(tokens)
89
95
  end
90
96
 
91
- def parse_value(tokens, token, type)
92
- if token == NOSUCHOBJECT_STR
93
- ['No Such Object', nil]
94
- elsif token == NOSUCHINSTANCE_STR
95
- ['No Such Instance', nil]
96
- elsif !type
97
- ['STRING', token]
97
+ def table(columns)
98
+ if columns.size == 1 && columns.all? { |column| column.size == 1 }
99
+ columns
98
100
  else
99
- [type, tokens.next]
101
+ align(columns)
100
102
  end
101
103
  end
102
104
 
@@ -116,25 +118,24 @@ module SNMP
116
118
  @oids.zip(columns).map do |oid, column|
117
119
  indexes.map do |index|
118
120
  id = (oid == index ? index : "#{oid}.#{index}")
119
- column.find { |o| o.oid == id } || Conversions.absent_value(id)
121
+ column.find { |o| o.oid == id } || Value.new(id, 'absent', nil)
120
122
  end
121
123
  end
122
124
  end
123
125
 
124
- # functions to generate value objects
125
- module Conversions
126
- module_function def convert_value(type, value)
127
- case type
128
- when 'INTEGER'
129
- value.to_i
130
- else
131
- value
132
- end
133
- end
126
+ # static messages from net-snmp commands
127
+ module Static
128
+ include SNMP::Open::Parser::Constants
134
129
 
135
- module_function def absent_value(id)
136
- Value.new(id, 'absent', nil)
137
- end
130
+ MESSAGES = [
131
+ NOSUCHOBJECT_STR,
132
+ NOSUCHINSTANCE_STR,
133
+ NOMOREVARIABLES_STR
134
+ ].freeze
135
+
136
+ ANY_MESSAGE = Regexp.union(*MESSAGES)
137
+
138
+ QUOTED_MESSAGES = MESSAGES.map { |v| [v, %("#{v}")] }.to_h.freeze
138
139
  end
139
140
  end # class Parser
140
141
  end # class Open
@@ -0,0 +1,15 @@
1
+ module SNMP
2
+ class Open
3
+ class Parser
4
+ module Constants
5
+ NOSUCHOBJECT_STR =
6
+ 'No Such Object available on this agent at this OID'.freeze
7
+ NOSUCHINSTANCE_STR =
8
+ 'No Such Instance currently exists at this OID'.freeze
9
+ NOMOREVARIABLES_STR =
10
+ 'No more variables left in this MIB View '\
11
+ '(It is past the end of the MIB tree)'.freeze
12
+ end # module Constants
13
+ end # class Parser
14
+ end # class Open
15
+ end # module SNMP
@@ -0,0 +1,127 @@
1
+ module SNMP
2
+ class Open
3
+ class Parser
4
+ # base class for value parsers
5
+ class ValueParser
6
+ include SNMP::Open::Parser::Constants
7
+
8
+ def self.find(type, token)
9
+ cls = KNOWN_TOKENS[token] || KNOWN_TYPES[type] || Other
10
+ cls.new(type, token)
11
+ end
12
+
13
+ def initialize(type, token)
14
+ @type = type
15
+ @token = token
16
+ end
17
+
18
+ def parse(*)
19
+ @parse
20
+ end
21
+
22
+ # parses BITS
23
+ class Bits < ValueParser
24
+ def parse(tokens)
25
+ return @parse if @parse
26
+ bytes = []
27
+ loop do
28
+ break unless tokens.peek =~ /\A[0-9A-Za-z]{1,2}\z/
29
+ bytes << tokens.next.to_i(16)
30
+ end
31
+ @parse = [@type, bytes]
32
+ end
33
+ end # class Bits < ValueParser
34
+
35
+ # parses objects with no explicit type
36
+ class Default < ValueParser
37
+ def initialize(_type, token)
38
+ @parse = ['STRING', token]
39
+ end
40
+ end # class Default
41
+
42
+ # parses integer-like objects
43
+ class Integer < ValueParser
44
+ def parse(tokens)
45
+ @parse ||= [@type, Integer(tokens.next)]
46
+ end
47
+ end
48
+
49
+ # parses objects identified like '= Hex-STRING:'
50
+ class HexString < ValueParser
51
+ def parse(tokens)
52
+ return @parse if @parse
53
+ bytes = []
54
+ loop do
55
+ break unless tokens.peek =~ /\A[0-9A-Za-z]{2}\z/
56
+ bytes << tokens.next
57
+ end
58
+ string = bytes.map { |b| b.to_i(16).chr }.join
59
+ @parse = [@type, string]
60
+ end
61
+ end # class HexString
62
+
63
+ # handles messages indicating the end of the response
64
+ class Stop < ValueParser
65
+ def parse(*)
66
+ raise StopIteration, @token
67
+ end
68
+ end
69
+
70
+ # parses objects identified like '= Timeticks:'
71
+ # note that 1 second = 100 ticks
72
+ class Timeticks < ValueParser
73
+ def parse(tokens)
74
+ return @parse if @parse
75
+ ticks = tokens.next.tr('()', '').to_i
76
+
77
+ # consume tokens through one like 23:59:59.99
78
+ loop do
79
+ break if tokens.next =~ /\A\d\d:\d\d:\d\d.\d\d\z/
80
+ end
81
+
82
+ @parse = [@type, ticks]
83
+ end
84
+ end # class Timeticks
85
+
86
+ # handles objects not handled by any other parser
87
+ class Other < ValueParser
88
+ def parse(tokens)
89
+ @parse ||= [@type, tokens.next]
90
+ end
91
+ end # class Other
92
+
93
+ # handles NoSuchInstance
94
+ class NoSuchInstance < ValueParser
95
+ def initialize(*)
96
+ @parse = ['No Such Instance', nil]
97
+ end
98
+ end # class NoSuchInstance < ValueParser
99
+
100
+ # handles NoSuchObject
101
+ class NoSuchObject < ValueParser
102
+ def initialize(*)
103
+ @parse = ['No Such Object', nil]
104
+ end
105
+ end # class NoSuchObject < ValueParser
106
+
107
+ KNOWN_TOKENS = {
108
+ NOSUCHINSTANCE_STR => NoSuchInstance,
109
+ NOSUCHOBJECT_STR => NoSuchObject,
110
+ NOMOREVARIABLES_STR => Stop
111
+ }.freeze
112
+
113
+ KNOWN_TYPES = {
114
+ nil => Default,
115
+ 'BITS' => Bits,
116
+ 'INTEGER' => ValueParser::Integer,
117
+ 'Gauge32' => ValueParser::Integer,
118
+ 'Gauge64' => ValueParser::Integer,
119
+ 'Counter32' => ValueParser::Integer,
120
+ 'Counter64' => ValueParser::Integer,
121
+ 'Hex-STRING' => HexString,
122
+ 'Timeticks' => Timeticks
123
+ }.freeze
124
+ end # class ValueParser
125
+ end # class Parser
126
+ end # class Open
127
+ end # module SNMP
@@ -1,5 +1,5 @@
1
- module Snmp
2
- module Open
3
- VERSION = '0.2.0'.freeze
1
+ module SNMP
2
+ class Open
3
+ VERSION = '0.6.0'.freeze
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'snmp/open/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'snmp-open'
7
- spec.version = Snmp::Open::VERSION
7
+ spec.version = SNMP::Open::VERSION
8
8
  spec.authors = ['Ben Miller']
9
9
  spec.email = ['bmiller@rackspace.com']
10
10
 
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency 'bundler', '~> 1.11'
22
- spec.add_development_dependency 'rake', '~> 10.0'
21
+ spec.add_development_dependency 'bundler', '~> 2.2'
22
+ spec.add_development_dependency 'rake', '~> 13.0'
23
23
  spec.add_development_dependency 'rspec', '~> 3.0'
24
24
  spec.add_development_dependency 'snmp'
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snmp-open
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Miller
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-06 00:00:00.000000000 Z
11
+ date: 2020-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: '2.2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: '2.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,16 +66,17 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description:
69
+ description:
70
70
  email:
71
71
  - bmiller@rackspace.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/workflows/ruby.yml"
76
77
  - ".gitignore"
77
78
  - ".rspec"
78
- - ".travis.yml"
79
+ - ".rubocop.yml"
79
80
  - CODE_OF_CONDUCT.md
80
81
  - Gemfile
81
82
  - Guardfile
@@ -89,13 +90,16 @@ files:
89
90
  - lib/snmp/open.rb
90
91
  - lib/snmp/open/command_reader.rb
91
92
  - lib/snmp/open/file_reader.rb
93
+ - lib/snmp/open/options.rb
92
94
  - lib/snmp/open/parser.rb
95
+ - lib/snmp/open/parser/constants.rb
96
+ - lib/snmp/open/parser/value_parser.rb
93
97
  - lib/snmp/open/version.rb
94
98
  - snmp-open.gemspec
95
99
  homepage: https://github.com/bjmllr/snmp-open
96
100
  licenses: []
97
101
  metadata: {}
98
- post_install_message:
102
+ post_install_message:
99
103
  rdoc_options: []
100
104
  require_paths:
101
105
  - lib
@@ -110,9 +114,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
114
  - !ruby/object:Gem::Version
111
115
  version: '0'
112
116
  requirements: []
113
- rubyforge_project:
114
- rubygems_version: 2.5.2
115
- signing_key:
117
+ rubygems_version: 3.1.2
118
+ signing_key:
116
119
  specification_version: 4
117
120
  summary: Wrapper for command-line SNMP utilities
118
121
  test_files: []
@@ -1,7 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.4.1
5
- - 2.3.4
6
- - 2.2.7
7
- before_install: gem install bundler -v 1.13.6