oxidized 0.30.1 → 0.32.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -4
  3. data/.github/workflows/stale.yml +4 -2
  4. data/.rubocop.yml +18 -3
  5. data/.rubocop_todo.yml +4 -11
  6. data/CHANGELOG.md +93 -1
  7. data/CONTRIBUTING.md +5 -0
  8. data/Dockerfile +84 -20
  9. data/README.md +5 -21
  10. data/Rakefile +31 -2
  11. data/docs/Configuration.md +50 -14
  12. data/docs/Creating-Models.md +75 -4
  13. data/docs/DeviceSimulation.md +184 -0
  14. data/docs/Hooks.md +39 -5
  15. data/docs/Issues.md +97 -0
  16. data/docs/Model-Notes/APC_AOS.md +29 -16
  17. data/docs/Model-Notes/Cumulus.md +5 -0
  18. data/docs/Model-Notes/FSOS.md +6 -0
  19. data/docs/Model-Notes/FortiOS.md +21 -5
  20. data/docs/Model-Notes/HPEAruba.md +31 -0
  21. data/docs/Model-Notes/OS6.md +10 -0
  22. data/docs/Model-Notes/RouterOS.md +15 -0
  23. data/docs/Model-Notes/SikluMHTG.md +7 -0
  24. data/docs/ModelUnitTests.md +186 -0
  25. data/docs/Outputs.md +2 -0
  26. data/docs/Release.md +18 -15
  27. data/docs/Sources.md +21 -0
  28. data/docs/Supported-OS-Types.md +14 -7
  29. data/docs/Troubleshooting.md +35 -0
  30. data/examples/podman-compose/Makefile +59 -17
  31. data/examples/podman-compose/README.md +63 -27
  32. data/examples/podman-compose/docker-compose.yml +11 -2
  33. data/examples/podman-compose/gitserver/.gitignore +1 -0
  34. data/examples/podman-compose/gitserver/Dockerfile +14 -0
  35. data/examples/podman-compose/model-simulation/Dockerfile-model +1 -1
  36. data/examples/podman-compose/model-simulation/asternos.sh +2 -0
  37. data/examples/podman-compose/oxidized-config/.gitignore +2 -0
  38. data/examples/podman-compose/oxidized-config/config +1 -1
  39. data/examples/podman-compose/oxidized-config/config_csv-file +46 -0
  40. data/examples/podman-compose/oxidized-config/config_csv-gitserver +56 -0
  41. data/examples/podman-compose/oxidized-ssh/.gitignore +1 -0
  42. data/extra/device2yaml.rb +245 -0
  43. data/extra/gitdiff-msteams.sh +32 -5
  44. data/extra/nagios_check_failing_nodes.rb +1 -1
  45. data/extra/rest_client.rb +1 -1
  46. data/lib/oxidized/config.rb +8 -2
  47. data/lib/oxidized/hook/githubrepo.rb +37 -7
  48. data/lib/oxidized/hook/slackdiff.rb +29 -7
  49. data/lib/oxidized/input/http.rb +1 -0
  50. data/lib/oxidized/input/ssh.rb +13 -5
  51. data/lib/oxidized/input/telnet.rb +1 -1
  52. data/lib/oxidized/manager.rb +17 -16
  53. data/lib/oxidized/model/aos7.rb +2 -0
  54. data/lib/oxidized/model/aoscx.rb +16 -2
  55. data/lib/oxidized/model/aosw.rb +8 -2
  56. data/lib/oxidized/model/apc_aos.rb +1 -1
  57. data/lib/oxidized/model/arubainstant.rb +90 -0
  58. data/lib/oxidized/model/asa.rb +2 -1
  59. data/lib/oxidized/model/asyncos.rb +1 -1
  60. data/lib/oxidized/model/audiocodes.rb +2 -2
  61. data/lib/oxidized/model/cnos.rb +13 -10
  62. data/lib/oxidized/model/cumulus.rb +19 -2
  63. data/lib/oxidized/model/dlink.rb +1 -0
  64. data/lib/oxidized/model/dlinknextgen.rb +3 -0
  65. data/lib/oxidized/model/edgecos.rb +2 -1
  66. data/lib/oxidized/model/enterprise_sonic.rb +46 -0
  67. data/lib/oxidized/model/eos.rb +2 -0
  68. data/lib/oxidized/model/f5os.rb +17 -0
  69. data/lib/oxidized/model/firewareos.rb +10 -1
  70. data/lib/oxidized/model/fortios.rb +24 -1
  71. data/lib/oxidized/model/fsos.rb +5 -1
  72. data/lib/oxidized/model/garderos.rb +43 -0
  73. data/lib/oxidized/model/h3c.rb +1 -1
  74. data/lib/oxidized/model/ibos.rb +1 -0
  75. data/lib/oxidized/model/ios.rb +20 -12
  76. data/lib/oxidized/model/iosxr.rb +1 -1
  77. data/lib/oxidized/model/junos.rb +1 -1
  78. data/lib/oxidized/model/kornfeldos.rb +33 -0
  79. data/lib/oxidized/model/lenovonos.rb +2 -0
  80. data/lib/oxidized/model/linuxgeneric.rb +1 -1
  81. data/lib/oxidized/model/model.rb +2 -2
  82. data/lib/oxidized/model/netgear.rb +1 -1
  83. data/lib/oxidized/model/nodegrid.rb +1 -1
  84. data/lib/oxidized/model/nsxdfw.rb +30 -0
  85. data/lib/oxidized/model/nxos.rb +2 -1
  86. data/lib/oxidized/model/os6.rb +48 -0
  87. data/lib/oxidized/model/rgos.rb +1 -1
  88. data/lib/oxidized/model/riverbed.rb +104 -0
  89. data/lib/oxidized/model/routeros.rb +2 -2
  90. data/lib/oxidized/model/saos.rb +18 -1
  91. data/lib/oxidized/model/siklumhtg.rb +22 -0
  92. data/lib/oxidized/model/sonicos.rb +8 -2
  93. data/lib/oxidized/model/tplink.rb +1 -0
  94. data/lib/oxidized/model/uplinkolt.rb +46 -0
  95. data/lib/oxidized/model/vyatta.rb +2 -2
  96. data/lib/oxidized/model/xos.rb +7 -0
  97. data/lib/oxidized/node.rb +30 -18
  98. data/lib/oxidized/nodes.rb +13 -5
  99. data/lib/oxidized/output/file.rb +45 -42
  100. data/lib/oxidized/output/git.rb +185 -160
  101. data/lib/oxidized/output/gitcrypt.rb +188 -186
  102. data/lib/oxidized/output/http.rb +53 -51
  103. data/lib/oxidized/output/output.rb +6 -4
  104. data/lib/oxidized/source/csv.rb +44 -49
  105. data/lib/oxidized/source/http.rb +63 -81
  106. data/lib/oxidized/source/jsonfile.rb +63 -0
  107. data/lib/oxidized/source/source.rb +73 -18
  108. data/lib/oxidized/source/sql.rb +66 -59
  109. data/lib/oxidized/version.rb +2 -2
  110. data/oxidized.gemspec +25 -18
  111. metadata +115 -21
@@ -1,102 +1,84 @@
1
1
  module Oxidized
2
- class HTTP < Source
3
- def initialize
4
- @cfg = Oxidized.config.source.http
5
- super
6
- end
7
-
8
- def setup
9
- Oxidized.setup_logger
10
- return unless @cfg.url.empty?
11
-
12
- raise NoConfig, 'no source http url config, edit ~/.config/oxidized/config'
13
- end
14
-
15
- require "net/http"
16
- require "net/https"
17
- require "uri"
18
- require "json"
19
-
20
- def load(node_want = nil)
21
- nodes = []
22
- uri = URI.parse(@cfg.url)
23
- data = JSON.parse(read_http(uri, node_want))
24
- node_data = data
25
- node_data = string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
26
- node_data = pagination(data, node_want) if @cfg.pagination?
2
+ module Source
3
+ require "oxidized/source/jsonfile"
4
+ class HTTP < JSONFile
5
+ def initialize
6
+ super
7
+ @cfg = Oxidized.config.source.http
8
+ end
27
9
 
28
- # at this point we have all the nodes; pagination or not
29
- node_data.each do |node|
30
- next if node.empty?
10
+ def setup
11
+ Oxidized.setup_logger
12
+ if @cfg.empty?
13
+ Oxidized.asetus.user.source.http.url = 'https://url/api'
14
+ Oxidized.asetus.user.source.http.map.name = 'name'
15
+ Oxidized.asetus.user.source.http.map.model = 'model'
16
+ Oxidized.asetus.save :user
31
17
 
32
- # map node parameters
33
- keys = {}
34
- @cfg.map.each do |key, want_position|
35
- keys[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
18
+ raise NoConfig, "No source http config, edit #{Oxidized::Config.configfile}"
36
19
  end
37
- keys[:model] = map_model keys[:model] if keys.has_key? :model
38
- keys[:group] = map_group keys[:group] if keys.has_key? :group
39
20
 
40
- # map node specific vars
41
- vars = {}
42
- @cfg.vars_map.each do |key, want_position|
43
- vars[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
21
+ # check for mandatory attributes
22
+ if !@cfg.has_key?('url')
23
+ raise InvalidConfig, "url is a mandatory http source attribute, edit #{Oxidized::Config.configfile}"
24
+ elsif !@cfg.map.has_key?('name')
25
+ raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
44
26
  end
45
- keys[:vars] = vars unless vars.empty?
46
-
47
- nodes << keys
48
27
  end
49
- nodes
50
- end
51
28
 
52
- private
29
+ require "net/http"
30
+ require "net/https"
31
+ require "uri"
32
+ require "json"
53
33
 
54
- def string_navigate(object, wants)
55
- wants = wants.split(".").map do |want|
56
- head, match, _tail = want.partition(/\[\d+\]/)
57
- match.empty? ? head : [head, match[1..-2].to_i]
58
- end
59
- wants.flatten.each do |want|
60
- object = object[want] if object.respond_to? :each
34
+ def load(node_want = nil)
35
+ uri = URI.parse(@cfg.url)
36
+ data = JSON.parse(read_http(uri, node_want))
37
+ node_data = data
38
+ node_data = string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
39
+ node_data = pagination(data, node_want) if @cfg.pagination?
40
+
41
+ transform_json(node_data)
61
42
  end
62
- object
63
- end
64
43
 
65
- def pagination(data, node_want)
66
- node_data = []
67
- raise Oxidized::OxidizedError, "if using pagination, 'pagination_key_name' setting must be set" unless @cfg.pagination_key_name?
44
+ private
68
45
 
69
- next_key = @cfg.pagination_key_name
70
- loop do
71
- node_data += string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
72
- break if data[next_key].nil?
46
+ def pagination(data, node_want)
47
+ node_data = []
48
+ raise Oxidized::OxidizedError, "if using pagination, 'pagination_key_name' setting must be set" unless @cfg.pagination_key_name?
73
49
 
74
- new_uri = URI.parse(data[next_key]) if data.has_key?(next_key)
75
- data = JSON.parse(read_http(new_uri, node_want))
76
- node_data += string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
50
+ next_key = @cfg.pagination_key_name
51
+ loop do
52
+ node_data += string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
53
+ break if data[next_key].nil?
54
+
55
+ new_uri = URI.parse(data[next_key]) if data.has_key?(next_key)
56
+ data = JSON.parse(read_http(new_uri, node_want))
57
+ node_data += string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
58
+ end
59
+ node_data
77
60
  end
78
- node_data
79
- end
80
61
 
81
- def read_http(uri, node_want)
82
- http = Net::HTTP.new(uri.host, uri.port)
83
- http.use_ssl = true if uri.scheme == 'https'
84
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
62
+ def read_http(uri, node_want)
63
+ http = Net::HTTP.new(uri.host, uri.port)
64
+ http.use_ssl = true if uri.scheme == 'https'
65
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
85
66
 
86
- # Add read_timeout to handle case of big list of nodes (default value is 60 seconds)
87
- http.read_timeout = Integer(@cfg.read_timeout) if @cfg.has_key? "read_timeout"
67
+ # Add read_timeout to handle case of big list of nodes (default value is 60 seconds)
68
+ http.read_timeout = Integer(@cfg.read_timeout) if @cfg.has_key? "read_timeout"
88
69
 
89
- # map headers
90
- headers = {}
91
- @cfg.headers.each do |header, value|
92
- headers[header] = value
93
- end
70
+ # map headers
71
+ headers = {}
72
+ @cfg.headers.each do |header, value|
73
+ headers[header] = value
74
+ end
94
75
 
95
- req_uri = uri.request_uri
96
- req_uri = "#{req_uri}/#{node_want}" if node_want
97
- request = Net::HTTP::Get.new(req_uri, headers)
98
- request.basic_auth(@cfg.user, @cfg.pass) if @cfg.user? && @cfg.pass?
99
- http.request(request).body
76
+ req_uri = uri.request_uri
77
+ req_uri = "#{req_uri}/#{node_want}" if node_want
78
+ request = Net::HTTP::Get.new(req_uri, headers)
79
+ request.basic_auth(@cfg.user, @cfg.pass) if @cfg.user? && @cfg.pass?
80
+ http.request(request).body
81
+ end
100
82
  end
101
83
  end
102
84
  end
@@ -0,0 +1,63 @@
1
+ module Oxidized
2
+ module Source
3
+ class JSONFile < Source
4
+ require "json"
5
+ def initialize
6
+ @cfg = Oxidized.config.source.jsonfile
7
+ super
8
+ end
9
+
10
+ def setup
11
+ if @cfg.empty?
12
+ Oxidized.asetus.user.source.jsonfile.file = File.join(Oxidized::Config::ROOT,
13
+ 'router.json')
14
+ Oxidized.asetus.user.source.jsonfile.map.name = "name"
15
+ Oxidized.asetus.user.source.jsonfile.map.model = "model"
16
+ Oxidized.asetus.user.source.jsonfile.gpg = false
17
+ Oxidized.asetus.save :user
18
+ raise NoConfig, "No source json config, edit #{Oxidized::Config.configfile}"
19
+ end
20
+ require 'gpgme' if @cfg.gpg?
21
+
22
+ # map.name is mandatory
23
+ return if @cfg.map.has_key?('name')
24
+
25
+ raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
26
+ end
27
+
28
+ def load(*)
29
+ data = JSON.parse(open_file.read)
30
+ data = string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
31
+
32
+ transform_json(data)
33
+ end
34
+
35
+ private
36
+
37
+ def transform_json(data)
38
+ nodes = []
39
+ data.each do |node|
40
+ next if node.empty?
41
+
42
+ # map node parameters
43
+ keys = {}
44
+ @cfg.map.each do |key, want_position|
45
+ keys[key.to_sym] = node_var_interpolate string_navigate_object(node, want_position)
46
+ end
47
+ keys[:model] = map_model keys[:model] if keys.has_key? :model
48
+ keys[:group] = map_group keys[:group] if keys.has_key? :group
49
+
50
+ # map node specific vars
51
+ vars = {}
52
+ @cfg.vars_map.each do |key, want_position|
53
+ vars[key.to_sym] = node_var_interpolate string_navigate_object(node, want_position)
54
+ end
55
+ keys[:vars] = vars unless vars.empty?
56
+
57
+ nodes << keys
58
+ end
59
+ nodes
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,26 +1,81 @@
1
1
  module Oxidized
2
- class Source
3
- class NoConfig < OxidizedError; end
2
+ module Source
3
+ class Source
4
+ class NoConfig < OxidizedError; end
4
5
 
5
- def initialize
6
- @model_map = Oxidized.config.model_map || {}
7
- @group_map = Oxidized.config.group_map || {}
8
- end
6
+ def initialize
7
+ @model_map = Oxidized.config.model_map || {}
8
+ @group_map = Oxidized.config.group_map || {}
9
+ end
9
10
 
10
- def map_model(model)
11
- @model_map.has_key?(model) ? @model_map[model] : model
12
- end
11
+ # common code of #map_model and #map_group
12
+ def map_value(map_hash, original_value)
13
+ map_hash.each do |key, new_value|
14
+ mthd = key.instance_of?(Regexp) ? :match : :eql?
15
+ return new_value if original_value.send(mthd, key)
16
+ end
17
+ original_value
18
+ end
13
19
 
14
- def map_group(group)
15
- @group_map.has_key?(group) ? @group_map[group] : group
16
- end
20
+ # search a match for model in the configuration and returns it.
21
+ # If no match is found, return model
22
+ #
23
+ # model can be matched against a string or a regexp:
24
+ #
25
+ # model_map:
26
+ # cisco: ios
27
+ # juniper: junos
28
+ # !ruby/regexp /procurve/: procurve
29
+ def map_model(model)
30
+ map_value(@model_map, model)
31
+ end
32
+
33
+ # search a match for group in the configuration and returns it.
34
+ # If no match is found, return group
35
+ #
36
+ # group can be matched against a string or a regexp:
37
+ #
38
+ # group_map:
39
+ # alias1: groupA
40
+ # alias2: groupA
41
+ # alias3: groupB
42
+ # alias4: groupB
43
+ # !ruby/regexp /specialgroup/: groupS
44
+ # aliasN: groupZ
45
+ def map_group(group)
46
+ map_value(@group_map, group)
47
+ end
48
+
49
+ def node_var_interpolate(var)
50
+ case var
51
+ when "nil" then nil
52
+ when "false" then false
53
+ when "true" then true
54
+ else var
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def open_file
61
+ file = File.expand_path(@cfg.file)
62
+ if @cfg.gpg?
63
+ crypto = GPGME::Crypto.new password: @cfg.gpg_password
64
+ crypto.decrypt(File.open(file)).to_s
65
+ else
66
+ File.open(file)
67
+ end
68
+ end
17
69
 
18
- def node_var_interpolate(var)
19
- case var
20
- when "nil" then nil
21
- when "false" then false
22
- when "true" then true
23
- else var
70
+ def string_navigate_object(object, wants)
71
+ wants = wants.split(".").map do |want|
72
+ head, match, _tail = want.partition(/\[\d+\]/)
73
+ match.empty? ? head : [head, match[1..-2].to_i]
74
+ end
75
+ wants.flatten.each do |want|
76
+ object = object[want] if object.respond_to? :each
77
+ end
78
+ object
24
79
  end
25
80
  end
26
81
  end
@@ -1,75 +1,82 @@
1
1
  module Oxidized
2
- class SQL < Source
3
- begin
4
- require 'sequel'
5
- rescue LoadError
6
- raise OxidizedError, 'sequel not found: sudo gem install sequel'
7
- end
2
+ module Source
3
+ class SQL < Source
4
+ begin
5
+ require 'sequel'
6
+ rescue LoadError
7
+ raise OxidizedError, 'sequel not found: sudo gem install sequel'
8
+ end
8
9
 
9
- def setup
10
- return unless @cfg.empty?
10
+ def setup
11
+ if @cfg.empty?
12
+ Oxidized.asetus.user.source.sql.adapter = 'sqlite'
13
+ Oxidized.asetus.user.source.sql.database = File.join(Config::ROOT, 'sqlite.db')
14
+ Oxidized.asetus.user.source.sql.table = 'devices'
15
+ Oxidized.asetus.user.source.sql.map.name = 'name'
16
+ Oxidized.asetus.user.source.sql.map.model = 'rancid'
17
+ Oxidized.asetus.save :user
18
+ raise NoConfig, "No source sql config, edit #{Oxidized::Config.configfile}"
19
+ end
11
20
 
12
- Oxidized.asetus.user.source.sql.adapter = 'sqlite'
13
- Oxidized.asetus.user.source.sql.database = File.join(Config::ROOT, 'sqlite.db')
14
- Oxidized.asetus.user.source.sql.table = 'devices'
15
- Oxidized.asetus.user.source.sql.map.name = 'name'
16
- Oxidized.asetus.user.source.sql.map.model = 'rancid'
17
- Oxidized.asetus.save :user
18
- raise NoConfig, 'no source sql config, edit ~/.config/oxidized/config'
19
- end
21
+ # map.name is mandatory
22
+ return if @cfg.map.has_key?('name')
20
23
 
21
- def load(node_want = nil)
22
- nodes = []
23
- db = connect
24
- query = db[@cfg.table.to_sym]
25
- query = query.with_sql(@cfg.query) if @cfg.query?
24
+ raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
25
+ end
26
26
 
27
- query = query.where(@cfg.map.name.to_sym => node_want) if node_want
27
+ def load(node_want = nil)
28
+ nodes = []
29
+ db = connect
30
+ query = db[@cfg.table.to_sym]
31
+ query = query.with_sql(@cfg.query) if @cfg.query?
28
32
 
29
- query.each do |node|
30
- # map node parameters
31
- keys = {}
32
- @cfg.map.each { |key, sql_column| keys[key.to_sym] = node_var_interpolate node[sql_column.to_sym] }
33
- keys[:model] = map_model keys[:model] if keys.has_key? :model
34
- keys[:group] = map_group keys[:group] if keys.has_key? :group
33
+ query = query.where(@cfg.map.name.to_sym => node_want) if node_want
35
34
 
36
- # map node specific vars
37
- vars = {}
38
- @cfg.vars_map.each do |key, sql_column|
39
- vars[key.to_sym] = node_var_interpolate node[sql_column.to_sym]
40
- end
41
- keys[:vars] = vars unless vars.empty?
35
+ query.each do |node|
36
+ # map node parameters
37
+ keys = {}
38
+ @cfg.map.each { |key, sql_column| keys[key.to_sym] = node_var_interpolate node[sql_column.to_sym] }
39
+ keys[:model] = map_model keys[:model] if keys.has_key? :model
40
+ keys[:group] = map_group keys[:group] if keys.has_key? :group
42
41
 
43
- nodes << keys
42
+ # map node specific vars
43
+ vars = {}
44
+ @cfg.vars_map.each do |key, sql_column|
45
+ vars[key.to_sym] = node_var_interpolate node[sql_column.to_sym]
46
+ end
47
+ keys[:vars] = vars unless vars.empty?
48
+
49
+ nodes << keys
50
+ end
51
+ db.disconnect
52
+ nodes
44
53
  end
45
- db.disconnect
46
- nodes
47
- end
48
54
 
49
- private
55
+ private
50
56
 
51
- def initialize
52
- super
53
- @cfg = Oxidized.config.source.sql
54
- end
57
+ def initialize
58
+ super
59
+ @cfg = Oxidized.config.source.sql
60
+ end
55
61
 
56
- def connect
57
- options = {
58
- adapter: @cfg.adapter,
59
- host: @cfg.host?,
60
- user: @cfg.user?,
61
- password: @cfg.password?,
62
- database: @cfg.database,
63
- ssl_mode: @cfg.ssl_mode?
64
- }
65
- if @cfg.with_ssl?
66
- options.merge!(sslca: @cfg.ssl_ca?,
67
- sslcert: @cfg.ssl_cert?,
68
- sslkey: @cfg.ssl_key?)
62
+ def connect
63
+ options = {
64
+ adapter: @cfg.adapter,
65
+ host: @cfg.host?,
66
+ user: @cfg.user?,
67
+ password: @cfg.password?,
68
+ database: @cfg.database,
69
+ ssl_mode: @cfg.ssl_mode?
70
+ }
71
+ if @cfg.with_ssl?
72
+ options.merge!(sslca: @cfg.ssl_ca?,
73
+ sslcert: @cfg.ssl_cert?,
74
+ sslkey: @cfg.ssl_key?)
75
+ end
76
+ Sequel.connect(options)
77
+ rescue Sequel::AdapterNotFound => e
78
+ raise OxidizedError, "SQL adapter gem not installed: " + e.message
69
79
  end
70
- Sequel.connect(options)
71
- rescue Sequel::AdapterNotFound => e
72
- raise OxidizedError, "SQL adapter gem not installed: " + e.message
73
80
  end
74
81
  end
75
82
  end
@@ -1,6 +1,6 @@
1
1
  module Oxidized
2
- VERSION = '0.30.1'.freeze
3
- VERSION_FULL = '0.30.1'.freeze
2
+ VERSION = '0.32.0'.freeze
3
+ VERSION_FULL = '0.32.0'.freeze
4
4
  def self.version_set
5
5
  version_full = %x(git describe --tags).chop rescue ""
6
6
  version = %x(git describe --tags --abbrev=0).chop rescue ""
data/oxidized.gemspec CHANGED
@@ -13,35 +13,42 @@ Gem::Specification.new do |s|
13
13
  s.summary = 'feeble attempt at rancid'
14
14
  s.description = 'software to fetch configuration from network devices and store them'
15
15
  s.rubyforge_project = s.name
16
- s.files = %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ s.files = %x(git ls-files -z).split("\x0").reject { |f| f.match(/^(test|spec|features)\//) }
17
17
  s.executables = %w[oxidized]
18
18
  s.require_path = 'lib'
19
19
 
20
20
  s.metadata['rubygems_mfa_required'] = 'true'
21
21
 
22
- s.required_ruby_version = '>= 3.0'
22
+ s.required_ruby_version = '>= 3.1'
23
23
 
24
- s.add_runtime_dependency 'asetus', '~> 0.1'
25
- s.add_runtime_dependency 'bcrypt_pbkdf', '~> 1.0'
26
- s.add_runtime_dependency 'ed25519', '~> 1.2'
27
- s.add_runtime_dependency 'net-ftp', '~> 0.2'
28
- s.add_runtime_dependency 'net-scp', '~> 4.0'
29
- s.add_runtime_dependency 'net-ssh', '~> 7.1'
30
- s.add_runtime_dependency 'net-telnet', '~> 0.2'
31
- s.add_runtime_dependency 'psych', '~> 3.3.2'
32
- s.add_runtime_dependency 'rugged', '~> 1.6'
33
- s.add_runtime_dependency 'slop', '~> 4.6'
24
+ s.add_dependency 'asetus', '~> 0.1'
25
+ s.add_dependency 'bcrypt_pbkdf', '~> 1.0'
26
+ s.add_dependency 'ed25519', '~> 1.2'
27
+ s.add_dependency 'net-ftp', '~> 0.2'
28
+ s.add_dependency 'net-http-digest_auth', '~> 1.4'
29
+ s.add_dependency 'net-scp', '~> 4.1'
30
+ s.add_dependency 'net-ssh', '~> 7.3'
31
+ s.add_dependency 'net-telnet', '~> 0.2'
32
+ s.add_dependency 'ostruct', '~> 0.6'
33
+ s.add_dependency 'psych', '~> 5.0'
34
+ s.add_dependency 'rugged', '~> 1.6'
35
+ s.add_dependency 'slop', '~> 4.6'
34
36
 
35
37
  s.add_development_dependency 'bundler', '~> 2.2'
36
- s.add_development_dependency 'git', '~> 1'
37
- s.add_development_dependency 'minitest', '~> 5.18'
38
+ s.add_development_dependency 'git', '~> 2'
39
+ s.add_development_dependency 'minitest', '~> 5.25.4'
38
40
  s.add_development_dependency 'mocha', '~> 2.1'
39
- s.add_development_dependency 'pry', '~> 0.14.2'
41
+ s.add_development_dependency 'pry', '~> 0.15.0'
40
42
  s.add_development_dependency 'rake', '~> 13.0'
41
- s.add_development_dependency 'rubocop', '~> 1.62.0'
42
- s.add_development_dependency 'rubocop-minitest', '~> 0.35.0'
43
+ s.add_development_dependency 'rubocop', '~> 1.72.0'
44
+ s.add_development_dependency 'rubocop-minitest', '~> 0.36.0'
43
45
  s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
46
+ s.add_development_dependency 'rubocop-sequel', '~> 0.3.3'
44
47
  s.add_development_dependency 'simplecov', '~> 0.22.0'
45
48
  s.add_development_dependency 'simplecov-cobertura', '~> 2.1.0'
46
- s.add_development_dependency 'simplecov-html', '~> 0.12.3'
49
+ s.add_development_dependency 'simplecov-html', '~> 0.13.1'
50
+
51
+ # Dependencies on optional libraries, used for unit tests & development
52
+ s.add_development_dependency 'oxidized-web', '>= 0.15.0'
53
+ s.add_development_dependency 'sequel', '~> 5.88.0'
47
54
  end