oxidized 0.28.0 → 0.29.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.
- checksums.yaml +4 -4
- data/.github/workflows/publishdocker.yml +8 -1
- data/.github/workflows/ruby.yml +42 -0
- data/.rubocop.yml +30 -10
- data/.rubocop_todo.yml +95 -41
- data/CHANGELOG.md +139 -2
- data/Dockerfile +13 -9
- data/README.md +66 -32
- data/Rakefile +2 -0
- data/docs/Configuration.md +49 -7
- data/docs/Creating-Models.md +10 -4
- data/docs/Hooks.md +35 -6
- data/docs/Model-Notes/ADVA.md +12 -0
- data/docs/Model-Notes/Cumulus.md +7 -1
- data/docs/Model-Notes/IOS.md +36 -0
- data/docs/Model-Notes/JunOS.md +3 -3
- data/docs/Model-Notes/LenovoNOS.md +29 -0
- data/docs/Model-Notes/LinksysSRW.md +15 -0
- data/docs/Model-Notes/Nokia.md +3 -0
- data/docs/Model-Notes/OS10.md +33 -0
- data/docs/Model-Notes/PanOS_API.md +28 -0
- data/docs/Model-Notes/README.md +2 -0
- data/docs/Sources.md +18 -0
- data/docs/Supported-OS-Types.md +51 -6
- data/docs/Troubleshooting.md +1 -1
- data/extra/gitdiff-msteams.sh +91 -0
- data/extra/nagios_check_failing_nodes.rb +6 -9
- data/extra/oxidized-report-git-commits +71 -14
- data/extra/oxidized.init +2 -5
- data/extra/oxidized.logrotate +1 -0
- data/extra/oxidized.runit +4 -1
- data/extra/oxidized.service +5 -8
- data/extra/rest_client.rb +1 -1
- data/extra/syslog.rb +2 -2
- data/lib/oxidized/cli.rb +1 -1
- data/lib/oxidized/config/vars.rb +5 -2
- data/lib/oxidized/config.rb +6 -3
- data/lib/oxidized/core.rb +1 -1
- data/lib/oxidized/hook/exec.rb +6 -6
- data/lib/oxidized/hook/githubrepo.rb +42 -11
- data/lib/oxidized/hook/slackdiff.rb +2 -2
- data/lib/oxidized/hook/xmppdiff.rb +45 -25
- data/lib/oxidized/hook.rb +4 -8
- data/lib/oxidized/input/exec.rb +1 -1
- data/lib/oxidized/input/input.rb +1 -0
- data/lib/oxidized/input/ssh.rb +23 -20
- data/lib/oxidized/input/telnet.rb +52 -44
- data/lib/oxidized/job.rb +1 -0
- data/lib/oxidized/jobs.rb +11 -6
- data/lib/oxidized/manager.rb +1 -0
- data/lib/oxidized/model/acmepacket.rb +38 -0
- data/lib/oxidized/model/adtran.rb +5 -3
- data/lib/oxidized/model/adva.rb +66 -0
- data/lib/oxidized/model/airfiber.rb +1 -1
- data/lib/oxidized/model/aoscx.rb +96 -0
- data/lib/oxidized/model/aosw.rb +1 -1
- data/lib/oxidized/model/asa.rb +2 -0
- data/lib/oxidized/model/awplus.rb +1 -1
- data/lib/oxidized/model/bdcom.rb +49 -0
- data/lib/oxidized/model/cambiumepmp.rb +17 -0
- data/lib/oxidized/model/casa.rb +4 -1
- data/lib/oxidized/model/ciscoce.rb +12 -0
- data/lib/oxidized/model/ciscosmb.rb +2 -0
- data/lib/oxidized/model/comware.rb +16 -1
- data/lib/oxidized/model/cumulus.rb +58 -44
- data/lib/oxidized/model/dellx.rb +1 -3
- data/lib/oxidized/model/dlink.rb +2 -1
- data/lib/oxidized/model/edgecos.rb +22 -2
- data/lib/oxidized/model/edgeswitch.rb +4 -4
- data/lib/oxidized/model/eltex.rb +48 -0
- data/lib/oxidized/model/enterasys.rb +18 -3
- data/lib/oxidized/model/enterasys800.rb +29 -0
- data/lib/oxidized/model/eos.rb +2 -1
- data/lib/oxidized/model/fabricos.rb +1 -1
- data/lib/oxidized/model/fastiron.rb +3 -2
- data/lib/oxidized/model/fortios.rb +24 -11
- data/lib/oxidized/model/fortiwlc.rb +24 -0
- data/lib/oxidized/model/gaiaos.rb +40 -3
- data/lib/oxidized/model/h3c.rb +40 -0
- data/lib/oxidized/model/hatteras.rb +2 -2
- data/lib/oxidized/model/hios.rb +38 -0
- data/lib/oxidized/model/hpebladesystem.rb +1 -1
- data/lib/oxidized/model/ios.rb +13 -10
- data/lib/oxidized/model/iosxe.rb +1 -1
- data/lib/oxidized/model/ironware.rb +8 -4
- data/lib/oxidized/model/junos.rb +5 -1
- data/lib/oxidized/model/lancom.rb +23 -0
- data/lib/oxidized/model/lenovonos.rb +82 -0
- data/lib/oxidized/model/linksyssrw.rb +71 -0
- data/lib/oxidized/model/mlnxos.rb +2 -0
- data/lib/oxidized/model/model.rb +29 -3
- data/lib/oxidized/model/necix.rb +30 -0
- data/lib/oxidized/model/netgear.rb +5 -2
- data/lib/oxidized/model/netscaler.rb +38 -1
- data/lib/oxidized/model/nodegrid.rb +23 -0
- data/lib/oxidized/model/nxos.rb +3 -2
- data/lib/oxidized/model/openbsd.rb +9 -0
- data/lib/oxidized/model/opengear.rb +1 -1
- data/lib/oxidized/model/opnsense.rb +12 -4
- data/lib/oxidized/model/panos_api.rb +71 -0
- data/lib/oxidized/model/pfsense.rb +12 -7
- data/lib/oxidized/model/powerconnect.rb +1 -3
- data/lib/oxidized/model/procurve.rb +2 -2
- data/lib/oxidized/model/purityos.rb +8 -1
- data/lib/oxidized/model/quantaos.rb +1 -5
- data/lib/oxidized/model/routeros.rb +15 -2
- data/lib/oxidized/model/slxos.rb +1 -0
- data/lib/oxidized/model/smartcs.rb +40 -0
- data/lib/oxidized/model/sonicos.rb +9 -1
- data/lib/oxidized/model/srosmd.rb +97 -0
- data/lib/oxidized/model/stoneos.rb +6 -2
- data/lib/oxidized/model/supermicro.rb +1 -1
- data/lib/oxidized/model/swos.rb +9 -0
- data/lib/oxidized/model/timos.rb +1 -1
- data/lib/oxidized/model/tmos.rb +2 -1
- data/lib/oxidized/model/tplink.rb +2 -0
- data/lib/oxidized/model/trango.rb +11 -11
- data/lib/oxidized/model/truenas.rb +20 -0
- data/lib/oxidized/model/vrp.rb +1 -1
- data/lib/oxidized/model/xos.rb +4 -3
- data/lib/oxidized/model/yamaha.rb +57 -0
- data/lib/oxidized/model/zteolt.rb +52 -0
- data/lib/oxidized/model/zy1308.rb +11 -0
- data/lib/oxidized/node/stats.rb +1 -0
- data/lib/oxidized/node.rb +16 -11
- data/lib/oxidized/nodes.rb +7 -6
- data/lib/oxidized/output/file.rb +2 -1
- data/lib/oxidized/output/git.rb +4 -3
- data/lib/oxidized/output/gitcrypt.rb +5 -8
- data/lib/oxidized/output/http.rb +2 -0
- data/lib/oxidized/source/csv.rb +1 -0
- data/lib/oxidized/source/http.rb +4 -0
- data/lib/oxidized/source/source.rb +7 -2
- data/lib/oxidized/source/sql.rb +15 -5
- data/lib/oxidized/string.rb +9 -3
- data/lib/oxidized/version.rb +2 -2
- data/lib/oxidized/worker.rb +5 -5
- data/oxidized.gemspec +22 -16
- metadata +116 -29
- data/.travis.yml +0 -10
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class TrueNAS < Oxidized::Model
|
|
2
|
+
comment '# '
|
|
3
|
+
|
|
4
|
+
cmd('uname -a') { |cfg| comment cfg }
|
|
5
|
+
cmd('cat /etc/version') { |cfg| comment cfg }
|
|
6
|
+
cmd('sqlite3 "file:///data/freenas-v1.db?mode=ro&immutable=1" .dump') do |cfg|
|
|
7
|
+
cfg.lines.reject do |line|
|
|
8
|
+
line.match(/^INSERT INTO storage_replication /) ||
|
|
9
|
+
line.match(/^INSERT INTO system_alert /)
|
|
10
|
+
end.join
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
cfg :ssh do
|
|
14
|
+
exec true # don't run shell, run each command in exec channel
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
cfg :ssh do
|
|
18
|
+
pre_logout 'exit'
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/oxidized/model/vrp.rb
CHANGED
data/lib/oxidized/model/xos.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class XOS < Oxidized::Model
|
|
2
2
|
# Extreme Networks XOS
|
|
3
3
|
|
|
4
|
-
prompt
|
|
4
|
+
prompt /^\s?\*?\s?[-\w]+\s?[-\w.~]+(:\d+)? [#>] $/
|
|
5
5
|
comment '# '
|
|
6
6
|
|
|
7
7
|
cmd :all do |cfg|
|
|
@@ -23,7 +23,8 @@ class XOS < Oxidized::Model
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
cmd 'show switch' do |cfg|
|
|
26
|
-
|
|
26
|
+
cfg.gsub! /Next periodic save on.*/, ''
|
|
27
|
+
comment cfg.each_line.reject { |line| line.match(/Time:/) || line.match(/boot/i) || line.match(/Next periodic/) }.join
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
cmd 'show configuration' do |cfg|
|
|
@@ -43,7 +44,7 @@ class XOS < Oxidized::Model
|
|
|
43
44
|
cfg :telnet, :ssh do
|
|
44
45
|
post_login do
|
|
45
46
|
data = cmd 'disable clipaging session'
|
|
46
|
-
match = data.match /^disable clipaging session\n
|
|
47
|
+
match = data.match /^disable clipaging session\n\r?\*?\s?[-\w]+\s?[-\w.~]+(:\d+)? [#>] $/m
|
|
47
48
|
next if match
|
|
48
49
|
|
|
49
50
|
cmd 'disable clipaging'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
class Yamaha < Oxidized::Model
|
|
2
|
+
prompt /^([\w.@()-]+[#>]\s?)$/
|
|
3
|
+
comment '# '
|
|
4
|
+
|
|
5
|
+
expect /^---more---$/ do |data, re|
|
|
6
|
+
send ' '
|
|
7
|
+
data.sub re, ''
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# non-preferred way to handle additional PW prompt
|
|
11
|
+
# expect /^[\w.]+>$/ do |data|
|
|
12
|
+
# send "enable\n"
|
|
13
|
+
# send vars(:enable) + "\n"
|
|
14
|
+
# data
|
|
15
|
+
# end
|
|
16
|
+
|
|
17
|
+
expect /^Save new configuration/ do |data, re|
|
|
18
|
+
send "N\n"
|
|
19
|
+
data.sub re, ''
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
cmd :all do |cfg|
|
|
23
|
+
# cfg.gsub! /\cH+\s{8}/, '' # example how to handle pager
|
|
24
|
+
# cfg.gsub! /\cH+/, '' # example how to handle pager
|
|
25
|
+
# get rid of errors for commands that don't work on some devices
|
|
26
|
+
cfg.gsub! /^Error: Invalid command name$|^\s+\^$/, ''
|
|
27
|
+
cfg.cut_both
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
cmd 'show config' do |cfg|
|
|
31
|
+
cfg.gsub! /^(# Reporting Date:\s+)(.*)$/, '\1<stripped>'
|
|
32
|
+
cfg
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
cfg :telnet do
|
|
36
|
+
password /^Password:/i
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
cfg :telnet, :ssh do
|
|
40
|
+
# preferred way to handle additional passwords
|
|
41
|
+
post_login 'console lines infinity'
|
|
42
|
+
post_login 'console columns 200'
|
|
43
|
+
post_login 'console character ascii'
|
|
44
|
+
post_login do
|
|
45
|
+
if vars(:enable) == true
|
|
46
|
+
cmd "administrator"
|
|
47
|
+
elsif vars(:enable)
|
|
48
|
+
cmd "administrator", /^[pP]assword:/
|
|
49
|
+
cmd vars(:enable)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
pre_logout do
|
|
53
|
+
cmd 'exit'
|
|
54
|
+
end
|
|
55
|
+
pre_logout 'exit'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class ZTEOLT < Oxidized::Model
|
|
2
|
+
# Tested with C320 and C300 olt, firware 1.2.5P3 and 2.1.0
|
|
3
|
+
|
|
4
|
+
prompt /^([\w.@()-]+[#>]\s?)$/
|
|
5
|
+
comment '! '
|
|
6
|
+
|
|
7
|
+
cmd :all do |cfg|
|
|
8
|
+
cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
|
|
9
|
+
cfg.cut_both
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
cmd :secret do |cfg|
|
|
13
|
+
cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
|
|
14
|
+
cfg.gsub! /^(tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
|
|
15
|
+
cfg.gsub! /^username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
|
|
16
|
+
cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>'
|
|
17
|
+
cfg
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
cmd 'show version-running' do |cfg|
|
|
21
|
+
comment cfg
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
cmd 'show patch-running' do |cfg|
|
|
25
|
+
comment cfg
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
cmd 'show running-config' do |cfg|
|
|
29
|
+
cfg.gsub! /^timestamp_write: .*\n/, ''
|
|
30
|
+
cfg
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
cfg :telnet do
|
|
34
|
+
username /^Username:/i
|
|
35
|
+
password /^Password:/i
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
cfg :telnet, :ssh do
|
|
39
|
+
# preferred way to handle additional passwords
|
|
40
|
+
post_login do
|
|
41
|
+
if vars(:enable) == true
|
|
42
|
+
cmd "enable"
|
|
43
|
+
elsif vars(:enable)
|
|
44
|
+
cmd "enable", /^[pP]assword:/
|
|
45
|
+
cmd vars(:enable)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
post_login 'terminal length 0'
|
|
49
|
+
pre_logout 'disable'
|
|
50
|
+
pre_logout 'exit'
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/oxidized/node/stats.rb
CHANGED
data/lib/oxidized/node.rb
CHANGED
|
@@ -4,9 +4,10 @@ module Oxidized
|
|
|
4
4
|
require_relative 'node/stats'
|
|
5
5
|
class MethodNotFound < OxidizedError; end
|
|
6
6
|
class ModelNotFound < OxidizedError; end
|
|
7
|
+
|
|
7
8
|
class Node
|
|
8
9
|
attr_reader :name, :ip, :model, :input, :output, :group, :auth, :prompt, :vars, :last, :repo
|
|
9
|
-
attr_accessor :running, :user, :email, :msg, :from, :stats, :retry
|
|
10
|
+
attr_accessor :running, :user, :email, :msg, :from, :stats, :retry, :err_type, :err_reason
|
|
10
11
|
alias running? running
|
|
11
12
|
|
|
12
13
|
def initialize(opt)
|
|
@@ -28,6 +29,8 @@ module Oxidized
|
|
|
28
29
|
@stats = Stats.new
|
|
29
30
|
@retry = 0
|
|
30
31
|
@repo = resolve_repo opt
|
|
32
|
+
@err_type = nil
|
|
33
|
+
@err_reason = nil
|
|
31
34
|
|
|
32
35
|
# model instance needs to access node instance
|
|
33
36
|
@model.node = self
|
|
@@ -73,6 +76,8 @@ module Oxidized
|
|
|
73
76
|
resc = " (rescued #{resc})"
|
|
74
77
|
end
|
|
75
78
|
Oxidized.logger.send(level, '%s raised %s%s with msg "%s"' % [ip, err.class, resc, err.message])
|
|
79
|
+
@err_type = err.class.to_s
|
|
80
|
+
@err_reason = err.message.to_s
|
|
76
81
|
false
|
|
77
82
|
rescue StandardError => err
|
|
78
83
|
crashdir = Oxidized.config.crash.directory
|
|
@@ -86,6 +91,8 @@ module Oxidized
|
|
|
86
91
|
fh.puts err.backtrace
|
|
87
92
|
end
|
|
88
93
|
Oxidized.logger.error '%s raised %s with msg "%s", %s saved' % [ip, err.class, err.message, crashfile]
|
|
94
|
+
@err_type = err.class.to_s
|
|
95
|
+
@err_reason = err.message.to_s
|
|
89
96
|
false
|
|
90
97
|
end
|
|
91
98
|
end
|
|
@@ -153,6 +160,7 @@ module Oxidized
|
|
|
153
160
|
inputs = resolve_key :input, opt, Oxidized.config.input.default
|
|
154
161
|
inputs.split(/\s*,\s*/).map do |input|
|
|
155
162
|
Oxidized.mgr.add_input(input) || raise(MethodNotFound, "#{input} not found for node #{ip}") unless Oxidized.mgr.input[input]
|
|
163
|
+
|
|
156
164
|
Oxidized.mgr.input[input]
|
|
157
165
|
end
|
|
158
166
|
end
|
|
@@ -160,6 +168,7 @@ module Oxidized
|
|
|
160
168
|
def resolve_output(opt)
|
|
161
169
|
output = resolve_key :output, opt, Oxidized.config.output.default
|
|
162
170
|
Oxidized.mgr.add_output(output) || raise(MethodNotFound, "#{output} not found for node #{ip}") unless Oxidized.mgr.output[output]
|
|
171
|
+
|
|
163
172
|
Oxidized.mgr.output[output]
|
|
164
173
|
end
|
|
165
174
|
|
|
@@ -202,19 +211,15 @@ module Oxidized
|
|
|
202
211
|
end
|
|
203
212
|
|
|
204
213
|
# group
|
|
205
|
-
if Oxidized.config.groups.has_key?(@group)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from group"
|
|
209
|
-
end
|
|
214
|
+
if Oxidized.config.groups.has_key?(@group) && Oxidized.config.groups[@group].has_key?(key_str)
|
|
215
|
+
value = Oxidized.config.groups[@group][key_str]
|
|
216
|
+
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from group"
|
|
210
217
|
end
|
|
211
218
|
|
|
212
219
|
# model
|
|
213
|
-
if Oxidized.config.models.has_key?(@model.class.name.to_s.downcase)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model"
|
|
217
|
-
end
|
|
220
|
+
if Oxidized.config.models.has_key?(@model.class.name.to_s.downcase) && Oxidized.config.models[@model.class.name.to_s.downcase].has_key?(key_str)
|
|
221
|
+
value = Oxidized.config.models[@model.class.name.to_s.downcase][key_str]
|
|
222
|
+
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model"
|
|
218
223
|
end
|
|
219
224
|
|
|
220
225
|
# node
|
data/lib/oxidized/nodes.rb
CHANGED
|
@@ -3,6 +3,7 @@ module Oxidized
|
|
|
3
3
|
require 'oxidized/node'
|
|
4
4
|
class Oxidized::NotSupported < OxidizedError; end
|
|
5
5
|
class Oxidized::NodeNotFound < OxidizedError; end
|
|
6
|
+
|
|
6
7
|
class Nodes < Array
|
|
7
8
|
attr_accessor :source, :jobs
|
|
8
9
|
alias put unshift
|
|
@@ -36,6 +37,7 @@ module Oxidized
|
|
|
36
37
|
|
|
37
38
|
node_want_ip = (IPAddr.new(node_want) rescue false)
|
|
38
39
|
name_is_ip = (IPAddr.new(node[:name]) rescue false)
|
|
40
|
+
# rubocop:todo Lint/DuplicateBranch
|
|
39
41
|
if name_is_ip && (node_want_ip == node[:name])
|
|
40
42
|
true
|
|
41
43
|
elsif node[:ip] && (node_want_ip == node[:ip])
|
|
@@ -43,6 +45,7 @@ module Oxidized
|
|
|
43
45
|
elsif node_want.match node[:name]
|
|
44
46
|
true unless name_is_ip
|
|
45
47
|
end
|
|
48
|
+
# rubocop:enable Lint/DuplicateBranch
|
|
46
49
|
end
|
|
47
50
|
|
|
48
51
|
def list
|
|
@@ -159,13 +162,11 @@ module Oxidized
|
|
|
159
162
|
old = dup
|
|
160
163
|
replace(nodes)
|
|
161
164
|
each do |node|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
node.last = old[i].last
|
|
166
|
-
end
|
|
167
|
-
rescue Oxidized::NodeNotFound
|
|
165
|
+
if (i = old.find_node_index(node.name))
|
|
166
|
+
node.stats = old[i].stats
|
|
167
|
+
node.last = old[i].last
|
|
168
168
|
end
|
|
169
|
+
rescue Oxidized::NodeNotFound
|
|
169
170
|
end
|
|
170
171
|
sort_by! { |x| x.last.nil? ? Time.new(0) : x.last.end }
|
|
171
172
|
end
|
data/lib/oxidized/output/file.rb
CHANGED
|
@@ -5,6 +5,7 @@ module Oxidized
|
|
|
5
5
|
attr_reader :commitref
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
|
+
super
|
|
8
9
|
@cfg = Oxidized.config.output.file
|
|
9
10
|
end
|
|
10
11
|
|
|
@@ -21,7 +22,7 @@ module Oxidized
|
|
|
21
22
|
file = File.join File.dirname(file), opt[:group] if opt[:group]
|
|
22
23
|
FileUtils.mkdir_p file
|
|
23
24
|
file = File.join file, node
|
|
24
|
-
File.
|
|
25
|
+
File.write(file, outputs.to_cfg)
|
|
25
26
|
@commitref = file
|
|
26
27
|
end
|
|
27
28
|
|
data/lib/oxidized/output/git.rb
CHANGED
|
@@ -10,6 +10,7 @@ module Oxidized
|
|
|
10
10
|
attr_reader :commitref
|
|
11
11
|
|
|
12
12
|
def initialize
|
|
13
|
+
super
|
|
13
14
|
@cfg = Oxidized.config.output.git
|
|
14
15
|
end
|
|
15
16
|
|
|
@@ -78,7 +79,7 @@ module Oxidized
|
|
|
78
79
|
i = -1
|
|
79
80
|
tab = []
|
|
80
81
|
walker.each do |commit|
|
|
81
|
-
next if commit.diff(paths: [path]).
|
|
82
|
+
next if commit.diff(paths: [path]).empty?
|
|
82
83
|
|
|
83
84
|
hash = {}
|
|
84
85
|
hash[:date] = commit.time.to_s
|
|
@@ -158,11 +159,11 @@ module Oxidized
|
|
|
158
159
|
begin
|
|
159
160
|
repo = Rugged::Repository.new repo
|
|
160
161
|
update_repo repo, file, data
|
|
161
|
-
rescue Rugged::OSError, Rugged::RepositoryError =>
|
|
162
|
+
rescue Rugged::OSError, Rugged::RepositoryError => e
|
|
162
163
|
begin
|
|
163
164
|
Rugged::Repository.init_at repo, :bare
|
|
164
165
|
rescue StandardError => create_error
|
|
165
|
-
raise GitError, "first '#{
|
|
166
|
+
raise GitError, "first '#{e.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
|
|
166
167
|
end
|
|
167
168
|
retry
|
|
168
169
|
end
|
|
@@ -10,6 +10,7 @@ module Oxidized
|
|
|
10
10
|
attr_reader :commitref
|
|
11
11
|
|
|
12
12
|
def initialize
|
|
13
|
+
super
|
|
13
14
|
@cfg = Oxidized.config.output.gitcrypt
|
|
14
15
|
@gitcrypt_cmd = "/usr/bin/git-crypt"
|
|
15
16
|
@gitcrypt_init = @gitcrypt_cmd + " init"
|
|
@@ -194,13 +195,13 @@ module Oxidized
|
|
|
194
195
|
|
|
195
196
|
begin
|
|
196
197
|
update_repo repo, file, data, @msg, @user, @email
|
|
197
|
-
rescue Git::GitExecuteError, ArgumentError =>
|
|
198
|
-
Oxidized.logger.debug "open_error #{
|
|
198
|
+
rescue Git::GitExecuteError, ArgumentError => e
|
|
199
|
+
Oxidized.logger.debug "open_error #{e} #{file}"
|
|
199
200
|
begin
|
|
200
201
|
grepo = Git.init repo
|
|
201
202
|
crypt_init grepo
|
|
202
203
|
rescue StandardError => create_error
|
|
203
|
-
raise GitCryptError, "first '#{
|
|
204
|
+
raise GitCryptError, "first '#{e.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
|
|
204
205
|
end
|
|
205
206
|
retry
|
|
206
207
|
end
|
|
@@ -214,11 +215,7 @@ module Oxidized
|
|
|
214
215
|
unlock grepo
|
|
215
216
|
File.write(file, data)
|
|
216
217
|
grepo.add(file)
|
|
217
|
-
if grepo.status[file].nil?
|
|
218
|
-
grepo.commit(msg)
|
|
219
|
-
@commitref = grepo.log(1).first.objectish
|
|
220
|
-
true
|
|
221
|
-
elsif !grepo.status[file].type.nil?
|
|
218
|
+
if grepo.status[file].nil? || !grepo.status[file].type.nil?
|
|
222
219
|
grepo.commit(msg)
|
|
223
220
|
@commitref = grepo.log(1).first.objectish
|
|
224
221
|
true
|
data/lib/oxidized/output/http.rb
CHANGED
data/lib/oxidized/source/csv.rb
CHANGED
data/lib/oxidized/source/http.rb
CHANGED
|
@@ -29,6 +29,7 @@ module Oxidized
|
|
|
29
29
|
keys[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
|
|
30
30
|
end
|
|
31
31
|
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
32
|
+
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
32
33
|
|
|
33
34
|
# map node specific vars
|
|
34
35
|
vars = {}
|
|
@@ -61,6 +62,9 @@ module Oxidized
|
|
|
61
62
|
http.use_ssl = true if uri.scheme == 'https'
|
|
62
63
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
|
|
63
64
|
|
|
65
|
+
# Add read_timeout to handle case of big list of nodes (default value is 60 seconds)
|
|
66
|
+
http.read_timeout = Integer(@cfg.read_timeout) if @cfg.has_key? "read_timeout"
|
|
67
|
+
|
|
64
68
|
# map headers
|
|
65
69
|
headers = {}
|
|
66
70
|
@cfg.headers.each do |header, value|
|
|
@@ -3,11 +3,16 @@ module Oxidized
|
|
|
3
3
|
class NoConfig < OxidizedError; end
|
|
4
4
|
|
|
5
5
|
def initialize
|
|
6
|
-
@
|
|
6
|
+
@model_map = (Oxidized.config.model_map || {})
|
|
7
|
+
@group_map = (Oxidized.config.group_map || {})
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def map_model(model)
|
|
10
|
-
@
|
|
11
|
+
@model_map.has_key?(model) ? @model_map[model] : model
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def map_group(group)
|
|
15
|
+
@group_map.has_key?(group) ? @group_map[group] : group
|
|
11
16
|
end
|
|
12
17
|
|
|
13
18
|
def node_var_interpolate(var)
|
data/lib/oxidized/source/sql.rb
CHANGED
|
@@ -31,6 +31,7 @@ module Oxidized
|
|
|
31
31
|
keys = {}
|
|
32
32
|
@cfg.map.each { |key, sql_column| keys[key.to_sym] = node_var_interpolate node[sql_column.to_sym] }
|
|
33
33
|
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
34
|
+
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
34
35
|
|
|
35
36
|
# map node specific vars
|
|
36
37
|
vars = {}
|
|
@@ -53,11 +54,20 @@ module Oxidized
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
def connect
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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?)
|
|
69
|
+
end
|
|
70
|
+
Sequel.connect(options)
|
|
61
71
|
rescue Sequel::AdapterNotFound => error
|
|
62
72
|
raise OxidizedError, "SQL adapter gem not installed: " + error.message
|
|
63
73
|
end
|
data/lib/oxidized/string.rb
CHANGED
|
@@ -5,17 +5,23 @@ module Oxidized
|
|
|
5
5
|
|
|
6
6
|
# @return [Oxidized::String] copy of self with last line removed
|
|
7
7
|
def cut_tail(lines = 1)
|
|
8
|
-
Oxidized::String.new
|
|
8
|
+
return Oxidized::String.new("") if length.zero?
|
|
9
|
+
|
|
10
|
+
Oxidized::String.new each_line.to_a[0..(-1 - lines)].join
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
# @return [Oxidized::String] copy of self with first line removed
|
|
12
14
|
def cut_head(lines = 1)
|
|
15
|
+
return Oxidized::String.new("") if length.zero?
|
|
16
|
+
|
|
13
17
|
Oxidized::String.new each_line.to_a[lines..-1].join
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
# @return [Oxidized::String] copy of self with first and last lines removed
|
|
17
21
|
def cut_both(head = 1, tail = 1)
|
|
18
|
-
Oxidized::String.new
|
|
22
|
+
return Oxidized::String.new("") if length.zero?
|
|
23
|
+
|
|
24
|
+
Oxidized::String.new each_line.to_a[head..(-1 - tail)].join
|
|
19
25
|
end
|
|
20
26
|
|
|
21
27
|
# sets @cmd and @name unless @name is already set
|
|
@@ -26,7 +32,7 @@ module Oxidized
|
|
|
26
32
|
|
|
27
33
|
def initialize(str = '')
|
|
28
34
|
super
|
|
29
|
-
return unless str.
|
|
35
|
+
return unless str.instance_of?(Oxidized::String)
|
|
30
36
|
|
|
31
37
|
@cmd = str.cmd
|
|
32
38
|
@name = str.name
|
data/lib/oxidized/version.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
VERSION = '0.
|
|
3
|
-
VERSION_FULL = '0.
|
|
2
|
+
VERSION = '0.29.0'.freeze
|
|
3
|
+
VERSION_FULL = '0.29.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/lib/oxidized/worker.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Oxidized
|
|
|
5
5
|
def initialize(nodes)
|
|
6
6
|
@jobs_done = 0
|
|
7
7
|
@nodes = nodes
|
|
8
|
-
@jobs = Jobs.new(Oxidized.config.threads, Oxidized.config.interval, @nodes)
|
|
8
|
+
@jobs = Jobs.new(Oxidized.config.threads, Oxidized.config.use_max_threads, Oxidized.config.interval, @nodes)
|
|
9
9
|
@nodes.jobs = @jobs
|
|
10
10
|
Thread.abort_on_exception = true
|
|
11
11
|
end
|
|
@@ -56,7 +56,7 @@ module Oxidized
|
|
|
56
56
|
|
|
57
57
|
def process_success(node, job)
|
|
58
58
|
@jobs_done += 1 # needed for :nodes_done hook
|
|
59
|
-
Oxidized.
|
|
59
|
+
Oxidized.hooks.handle :node_success, node: node,
|
|
60
60
|
job: job
|
|
61
61
|
msg = "update #{node.group}/#{node.name}"
|
|
62
62
|
msg += " from #{node.from}" if node.from
|
|
@@ -66,7 +66,7 @@ module Oxidized
|
|
|
66
66
|
msg: msg, email: node.email, user: node.user, group: node.group
|
|
67
67
|
node.modified
|
|
68
68
|
Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
|
|
69
|
-
Oxidized.
|
|
69
|
+
Oxidized.hooks.handle :post_store, node: node,
|
|
70
70
|
job: job,
|
|
71
71
|
commitref: output.commitref
|
|
72
72
|
end
|
|
@@ -87,7 +87,7 @@ module Oxidized
|
|
|
87
87
|
@jobs_done += 1
|
|
88
88
|
msg += ", retries exhausted, giving up"
|
|
89
89
|
node.retry = 0
|
|
90
|
-
Oxidized.
|
|
90
|
+
Oxidized.hooks.handle :node_fail, node: node,
|
|
91
91
|
job: job
|
|
92
92
|
end
|
|
93
93
|
Oxidized.logger.warn msg
|
|
@@ -103,7 +103,7 @@ module Oxidized
|
|
|
103
103
|
|
|
104
104
|
def run_done_hook
|
|
105
105
|
Oxidized.logger.debug "lib/oxidized/worker.rb: Running :nodes_done hook"
|
|
106
|
-
Oxidized.
|
|
106
|
+
Oxidized.hooks.handle :nodes_done
|
|
107
107
|
rescue StandardError => e
|
|
108
108
|
# swallow the hook erros and continue as normal
|
|
109
109
|
Oxidized.logger.error "lib/oxidized/worker.rb: #{e.message}"
|
data/oxidized.gemspec
CHANGED
|
@@ -17,22 +17,28 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.executables = %w[oxidized]
|
|
18
18
|
s.require_path = 'lib'
|
|
19
19
|
|
|
20
|
-
s.
|
|
21
|
-
|
|
20
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
21
|
+
|
|
22
|
+
s.required_ruby_version = '>= 3.0'
|
|
23
|
+
|
|
24
|
+
s.add_runtime_dependency 'asetus', '~> 0.1'
|
|
22
25
|
s.add_runtime_dependency 'bcrypt_pbkdf', '~> 1.0'
|
|
23
|
-
s.add_runtime_dependency 'ed25519',
|
|
24
|
-
s.add_runtime_dependency 'net-ssh',
|
|
25
|
-
s.add_runtime_dependency 'net-telnet',
|
|
26
|
-
s.add_runtime_dependency 'rugged',
|
|
27
|
-
s.add_runtime_dependency 'slop',
|
|
26
|
+
s.add_runtime_dependency 'ed25519', '~> 1.2'
|
|
27
|
+
s.add_runtime_dependency 'net-ssh', '~> 7.1'
|
|
28
|
+
s.add_runtime_dependency 'net-telnet', '~> 0.2'
|
|
29
|
+
s.add_runtime_dependency 'rugged', '~> 1.6'
|
|
30
|
+
s.add_runtime_dependency 'slop', '~> 4.6'
|
|
28
31
|
|
|
29
|
-
s.add_development_dependency 'bundler',
|
|
30
|
-
s.add_development_dependency '
|
|
31
|
-
s.add_development_dependency '
|
|
32
|
-
s.add_development_dependency '
|
|
33
|
-
s.add_development_dependency '
|
|
34
|
-
s.add_development_dependency '
|
|
35
|
-
s.add_development_dependency '
|
|
36
|
-
s.add_development_dependency 'rubocop',
|
|
37
|
-
s.add_development_dependency '
|
|
32
|
+
s.add_development_dependency 'bundler', '~> 2.2'
|
|
33
|
+
s.add_development_dependency 'git', '~> 1'
|
|
34
|
+
s.add_development_dependency 'minitest', '~> 5.18'
|
|
35
|
+
s.add_development_dependency 'mocha', '~> 1.2'
|
|
36
|
+
s.add_development_dependency 'pry', '~> 0.14.2'
|
|
37
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
|
38
|
+
s.add_development_dependency 'rubocop', '~> 1.48.0'
|
|
39
|
+
s.add_development_dependency 'rubocop-minitest', '~> 0.29.0'
|
|
40
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
|
41
|
+
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
42
|
+
s.add_development_dependency 'simplecov-cobertura', '~> 2.1.0'
|
|
43
|
+
s.add_development_dependency 'simplecov-html', '~> 0.12.3'
|
|
38
44
|
end
|