oxidized 0.25.1 → 0.26.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/.rubocop.yml +30 -9
- data/.rubocop_todo.yml +16 -637
- data/.travis.yml +2 -3
- data/CHANGELOG.md +14 -0
- data/Dockerfile +7 -5
- data/README.md +18 -14
- data/Rakefile +2 -2
- data/bin/console +1 -1
- data/bin/oxidized +2 -2
- data/docs/Configuration.md +6 -0
- data/docs/Model-Notes/README.md +1 -0
- data/docs/Model-Notes/SmartAX-Huawei.md +35 -0
- data/docs/Supported-OS-Types.md +12 -0
- data/extra/nagios_check_failing_nodes.rb +1 -1
- data/extra/rest_client.rb +6 -8
- data/extra/syslog.rb +33 -33
- data/lib/oxidized/cli.rb +25 -26
- data/lib/oxidized/config.rb +9 -9
- data/lib/oxidized/config/vars.rb +3 -7
- data/lib/oxidized/core.rb +4 -7
- data/lib/oxidized/hook.rb +16 -17
- data/lib/oxidized/hook/awssns.rb +4 -4
- data/lib/oxidized/hook/exec.rb +16 -20
- data/lib/oxidized/hook/githubrepo.rb +8 -14
- data/lib/oxidized/hook/noophook.rb +1 -1
- data/lib/oxidized/hook/xmppdiff.rb +1 -1
- data/lib/oxidized/input/cli.rb +12 -12
- data/lib/oxidized/input/ftp.rb +8 -8
- data/lib/oxidized/input/http.rb +37 -14
- data/lib/oxidized/input/input.rb +6 -6
- data/lib/oxidized/input/ssh.rb +31 -31
- data/lib/oxidized/input/telnet.rb +24 -24
- data/lib/oxidized/input/tftp.rb +9 -10
- data/lib/oxidized/jobs.rb +7 -7
- data/lib/oxidized/manager.rb +13 -13
- data/lib/oxidized/model/acos.rb +2 -2
- data/lib/oxidized/model/aireos.rb +3 -3
- data/lib/oxidized/model/aos7.rb +1 -1
- data/lib/oxidized/model/aosw.rb +12 -14
- data/lib/oxidized/model/apc_aos.rb +1 -1
- data/lib/oxidized/model/aricentiss.rb +6 -8
- data/lib/oxidized/model/asa.rb +1 -1
- data/lib/oxidized/model/audiocodesmp.rb +28 -0
- data/lib/oxidized/model/awplus.rb +9 -9
- data/lib/oxidized/model/boss.rb +1 -1
- data/lib/oxidized/model/ciscosmb.rb +1 -1
- data/lib/oxidized/model/ciscovpn3k.rb +11 -0
- data/lib/oxidized/model/comware.rb +1 -1
- data/lib/oxidized/model/cumulus.rb +3 -1
- data/lib/oxidized/model/dellx.rb +5 -5
- data/lib/oxidized/model/edgeos.rb +1 -1
- data/lib/oxidized/model/edgeswitch.rb +1 -1
- data/lib/oxidized/model/fabricos.rb +1 -1
- data/lib/oxidized/model/fortios.rb +5 -5
- data/lib/oxidized/model/ftos.rb +1 -1
- data/lib/oxidized/model/gcombnps.rb +7 -7
- data/lib/oxidized/model/grandstream.rb +9 -0
- data/lib/oxidized/model/hatteras.rb +8 -8
- data/lib/oxidized/model/ios.rb +22 -40
- data/lib/oxidized/model/ironware.rb +1 -1
- data/lib/oxidized/model/junos.rb +1 -1
- data/lib/oxidized/model/mlnxos.rb +1 -1
- data/lib/oxidized/model/model.rb +32 -38
- data/lib/oxidized/model/netgearxs716.rb +23 -0
- data/lib/oxidized/model/netonix.rb +1 -1
- data/lib/oxidized/model/netscaler.rb +1 -1
- data/lib/oxidized/model/nos.rb +2 -2
- data/lib/oxidized/model/nxos.rb +1 -1
- data/lib/oxidized/model/openbsd.rb +3 -2
- data/lib/oxidized/model/outputs.rb +4 -4
- data/lib/oxidized/model/planet.rb +4 -4
- data/lib/oxidized/model/powerconnect.rb +8 -8
- data/lib/oxidized/model/procurve.rb +2 -1
- data/lib/oxidized/model/quantaos.rb +3 -3
- data/lib/oxidized/model/raisecom.rb +19 -0
- data/lib/oxidized/model/siklu.rb +1 -1
- data/lib/oxidized/model/slxos.rb +1 -1
- data/lib/oxidized/model/smartax.rb +25 -0
- data/lib/oxidized/model/sros.rb +4 -4
- data/lib/oxidized/model/tdre.rb +30 -0
- data/lib/oxidized/model/tmos.rb +3 -0
- data/lib/oxidized/model/trango.rb +17 -37
- data/lib/oxidized/model/voltaire.rb +1 -1
- data/lib/oxidized/model/voss.rb +1 -1
- data/lib/oxidized/model/vyatta.rb +1 -1
- data/lib/oxidized/model/xos.rb +1 -1
- data/lib/oxidized/model/zhoneolt.rb +1 -1
- data/lib/oxidized/node.rb +42 -46
- data/lib/oxidized/node/stats.rb +6 -6
- data/lib/oxidized/nodes.rb +42 -42
- data/lib/oxidized/output/file.rb +16 -20
- data/lib/oxidized/output/git.rb +68 -78
- data/lib/oxidized/output/gitcrypt.rb +77 -91
- data/lib/oxidized/output/http.rb +17 -19
- data/lib/oxidized/output/output.rb +1 -1
- data/lib/oxidized/source/csv.rb +3 -3
- data/lib/oxidized/source/http.rb +11 -14
- data/lib/oxidized/source/source.rb +3 -3
- data/lib/oxidized/source/sql.rb +16 -18
- data/lib/oxidized/string.rb +10 -10
- data/lib/oxidized/version.rb +4 -4
- data/lib/oxidized/worker.rb +15 -15
- data/oxidized.gemspec +6 -9
- metadata +32 -25
data/lib/oxidized/input/ftp.rb
CHANGED
|
@@ -5,17 +5,17 @@ module Oxidized
|
|
|
5
5
|
|
|
6
6
|
class FTP < Input
|
|
7
7
|
RescueFail = {
|
|
8
|
-
:
|
|
8
|
+
debug: [
|
|
9
9
|
# Net::SSH::Disconnect,
|
|
10
10
|
],
|
|
11
|
-
:
|
|
11
|
+
warn: [
|
|
12
12
|
# RuntimeError,
|
|
13
13
|
# Net::SSH::AuthenticationFailed,
|
|
14
|
-
]
|
|
15
|
-
}
|
|
14
|
+
]
|
|
15
|
+
}.freeze
|
|
16
16
|
include Input::CLI
|
|
17
17
|
|
|
18
|
-
def connect
|
|
18
|
+
def connect(node)
|
|
19
19
|
@node = node
|
|
20
20
|
@node.model.cfg['ftp'].each { |cb| instance_exec(&cb) }
|
|
21
21
|
@log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ftp", 'w') if Oxidized.config.input.debug?
|
|
@@ -26,16 +26,16 @@ module Oxidized
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def connected?
|
|
29
|
-
@ftp
|
|
29
|
+
@ftp && (not @ftp.closed?)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def cmd
|
|
32
|
+
def cmd(file)
|
|
33
33
|
Oxidized.logger.debug "FTP: #{file} @ #{@node.name}"
|
|
34
34
|
@ftp.getbinaryfile file, nil
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# meh not sure if this is the best way, but perhaps better than not implementing send
|
|
38
|
-
def send
|
|
38
|
+
def send(my_proc)
|
|
39
39
|
my_proc.call
|
|
40
40
|
end
|
|
41
41
|
|
data/lib/oxidized/input/http.rb
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require "mechanize"
|
|
6
|
-
rescue LoadError
|
|
7
|
-
raise OxidizedError, "mechanize not found: sudo gem install mechanize"
|
|
8
|
-
end
|
|
2
|
+
require "oxidized/input/cli"
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
9
5
|
|
|
10
6
|
class HTTP < Input
|
|
11
7
|
include Input::CLI
|
|
12
8
|
|
|
13
|
-
def connect
|
|
9
|
+
def connect(node)
|
|
14
10
|
@node = node
|
|
15
|
-
@
|
|
16
|
-
@log
|
|
17
|
-
|
|
11
|
+
@secure = false
|
|
12
|
+
@log = File.open(Oxidized::Config::Log + "/#{@node.ip}-http", "w") if Oxidized.config.input.debug?
|
|
18
13
|
@node.model.cfg["http"].each { |cb| instance_exec(&cb) }
|
|
19
14
|
|
|
15
|
+
return true unless @main_page && defined?(login)
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
require "mechanize"
|
|
19
|
+
rescue LoadError
|
|
20
|
+
raise OxidizedError, "mechanize not found: sudo gem install mechanize"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
@m = Mechanize.new
|
|
20
24
|
url = URI::HTTP.build host: @node.ip, path: @main_page
|
|
21
25
|
@m_page = @m.get(url.to_s)
|
|
22
26
|
login
|
|
23
27
|
end
|
|
24
28
|
|
|
25
|
-
def cmd
|
|
29
|
+
def cmd(callback_or_string)
|
|
30
|
+
return cmd_cb callback_or_string if callback_or_string.is_a?(Proc)
|
|
31
|
+
|
|
32
|
+
cmd_str callback_or_string
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def cmd_cb(callback)
|
|
26
36
|
instance_exec(&callback)
|
|
27
37
|
end
|
|
28
38
|
|
|
39
|
+
def cmd_str(string)
|
|
40
|
+
path = string % { password: @node.auth[:password] }
|
|
41
|
+
get_http path
|
|
42
|
+
end
|
|
43
|
+
|
|
29
44
|
private
|
|
30
45
|
|
|
31
|
-
def
|
|
32
|
-
@
|
|
46
|
+
def get_http(path)
|
|
47
|
+
schema = @secure ? "https://" : "http://"
|
|
48
|
+
uri = URI.join schema + @node.ip, path
|
|
49
|
+
http = Net::HTTP.new uri.host, uri.port
|
|
50
|
+
http.use_ssl = true if uri.scheme == "https"
|
|
51
|
+
http.get(uri).body
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def log(str)
|
|
55
|
+
@log&.write(str)
|
|
33
56
|
end
|
|
34
57
|
|
|
35
58
|
def disconnect
|
data/lib/oxidized/input/input.rb
CHANGED
|
@@ -4,10 +4,10 @@ module Oxidized
|
|
|
4
4
|
include Oxidized::Config::Vars
|
|
5
5
|
|
|
6
6
|
RescueFail = {
|
|
7
|
-
:
|
|
8
|
-
Errno::ECONNREFUSED
|
|
7
|
+
debug: [
|
|
8
|
+
Errno::ECONNREFUSED
|
|
9
9
|
],
|
|
10
|
-
:
|
|
10
|
+
warn: [
|
|
11
11
|
IOError,
|
|
12
12
|
PromptUndetect,
|
|
13
13
|
Timeout::Error,
|
|
@@ -15,8 +15,8 @@ module Oxidized
|
|
|
15
15
|
Errno::EHOSTUNREACH,
|
|
16
16
|
Errno::ENETUNREACH,
|
|
17
17
|
Errno::EPIPE,
|
|
18
|
-
Errno::ETIMEDOUT
|
|
19
|
-
]
|
|
20
|
-
}
|
|
18
|
+
Errno::ETIMEDOUT
|
|
19
|
+
]
|
|
20
|
+
}.freeze
|
|
21
21
|
end
|
|
22
22
|
end
|
data/lib/oxidized/input/ssh.rb
CHANGED
|
@@ -5,18 +5,18 @@ module Oxidized
|
|
|
5
5
|
require 'oxidized/input/cli'
|
|
6
6
|
class SSH < Input
|
|
7
7
|
RescueFail = {
|
|
8
|
-
:
|
|
9
|
-
Net::SSH::Disconnect
|
|
8
|
+
debug: [
|
|
9
|
+
Net::SSH::Disconnect
|
|
10
10
|
],
|
|
11
|
-
:
|
|
11
|
+
warn: [
|
|
12
12
|
RuntimeError,
|
|
13
|
-
Net::SSH::AuthenticationFailed
|
|
14
|
-
]
|
|
15
|
-
}
|
|
13
|
+
Net::SSH::AuthenticationFailed
|
|
14
|
+
]
|
|
15
|
+
}.freeze
|
|
16
16
|
include Input::CLI
|
|
17
17
|
class NoShell < OxidizedError; end
|
|
18
18
|
|
|
19
|
-
def connect
|
|
19
|
+
def connect(node)
|
|
20
20
|
@node = node
|
|
21
21
|
@output = ''
|
|
22
22
|
@pty_options = { term: "vt100" }
|
|
@@ -37,10 +37,10 @@ module Oxidized
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def connected?
|
|
40
|
-
@ssh
|
|
40
|
+
@ssh && (not @ssh.closed?)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def cmd
|
|
43
|
+
def cmd(cmd, expect = node.prompt)
|
|
44
44
|
Oxidized.logger.debug "lib/oxidized/input/ssh.rb #{cmd} @ #{node.name} with expect: #{expect.inspect}"
|
|
45
45
|
if @exec
|
|
46
46
|
@ssh.exec! cmd
|
|
@@ -49,15 +49,13 @@ module Oxidized
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
def send
|
|
52
|
+
def send(data)
|
|
53
53
|
@ses.send_data data
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
@output
|
|
58
|
-
end
|
|
56
|
+
attr_reader :output
|
|
59
57
|
|
|
60
|
-
def pty_options
|
|
58
|
+
def pty_options(hash)
|
|
61
59
|
@pty_options = @pty_options.merge hash
|
|
62
60
|
end
|
|
63
61
|
|
|
@@ -66,14 +64,14 @@ module Oxidized
|
|
|
66
64
|
def disconnect
|
|
67
65
|
disconnect_cli
|
|
68
66
|
# if disconnect does not disconnect us, give up after timeout
|
|
69
|
-
Timeout
|
|
70
|
-
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError
|
|
67
|
+
Timeout.timeout(Oxidized.config.timeout) { @ssh.loop }
|
|
68
|
+
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError # rubocop:disable Lint/HandleExceptions
|
|
71
69
|
ensure
|
|
72
70
|
@log.close if Oxidized.config.input.debug?
|
|
73
71
|
(@ssh.close rescue true) unless @ssh.closed?
|
|
74
72
|
end
|
|
75
73
|
|
|
76
|
-
def shell_open
|
|
74
|
+
def shell_open(ssh)
|
|
77
75
|
@ses = ssh.open_channel do |ch|
|
|
78
76
|
ch.on_data do |_ch, data|
|
|
79
77
|
if Oxidized.config.input.debug?
|
|
@@ -83,7 +81,7 @@ module Oxidized
|
|
|
83
81
|
@output << data
|
|
84
82
|
@output = @node.model.expects @output
|
|
85
83
|
end
|
|
86
|
-
ch.request_pty
|
|
84
|
+
ch.request_pty(@pty_options) do |_ch, success_pty|
|
|
87
85
|
raise NoShell, "Can't get PTY" unless success_pty
|
|
88
86
|
|
|
89
87
|
ch.send_channel_request 'shell' do |_ch, success_shell|
|
|
@@ -93,8 +91,10 @@ module Oxidized
|
|
|
93
91
|
end
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
def exec
|
|
97
|
-
|
|
94
|
+
def exec(state = nil)
|
|
95
|
+
return nil if vars(:ssh_no_exec)
|
|
96
|
+
|
|
97
|
+
state.nil? ? @exec : (@exec = state)
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def cmd_shell(cmd, expect_re)
|
|
@@ -105,10 +105,10 @@ module Oxidized
|
|
|
105
105
|
@output
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
def expect
|
|
108
|
+
def expect(*regexps)
|
|
109
109
|
regexps = [regexps].flatten
|
|
110
110
|
Oxidized.logger.debug "lib/oxidized/input/ssh.rb: expecting #{regexps.inspect} at #{node.name}"
|
|
111
|
-
Timeout
|
|
111
|
+
Timeout.timeout(Oxidized.config.timeout) do
|
|
112
112
|
@ssh.loop(0.1) do
|
|
113
113
|
sleep 0.1
|
|
114
114
|
match = regexps.find { |regexp| @output.match regexp }
|
|
@@ -122,22 +122,22 @@ module Oxidized
|
|
|
122
122
|
def make_ssh_opts
|
|
123
123
|
secure = Oxidized.config.input.ssh.secure?
|
|
124
124
|
ssh_opts = {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
password:
|
|
129
|
-
timeout:
|
|
130
|
-
|
|
125
|
+
number_of_password_prompts: 0,
|
|
126
|
+
keepalive: vars(:ssh_no_keepalive) ? false : true,
|
|
127
|
+
paranoid: secure,
|
|
128
|
+
password: @node.auth[:password],
|
|
129
|
+
timeout: Oxidized.config.timeout,
|
|
130
|
+
port: (vars(:ssh_port) || 22).to_i
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
auth_methods = vars(:auth_methods) || %w
|
|
133
|
+
auth_methods = vars(:auth_methods) || %w[none publickey password]
|
|
134
134
|
ssh_opts[:auth_methods] = auth_methods
|
|
135
135
|
Oxidized.logger.debug "AUTH METHODS::#{auth_methods}"
|
|
136
136
|
|
|
137
|
-
if proxy_host = vars(:ssh_proxy)
|
|
137
|
+
if (proxy_host = vars(:ssh_proxy))
|
|
138
138
|
proxy_command = "ssh "
|
|
139
139
|
proxy_command += "-o StrictHostKeyChecking=no " unless secure
|
|
140
|
-
if proxy_port = vars(:ssh_proxy_port)
|
|
140
|
+
if (proxy_port = vars(:ssh_proxy_port))
|
|
141
141
|
proxy_command += "-p #{proxy_port} "
|
|
142
142
|
end
|
|
143
143
|
proxy_command += "#{proxy_host} -W %h:%p"
|
|
@@ -2,22 +2,24 @@ module Oxidized
|
|
|
2
2
|
require 'net/telnet'
|
|
3
3
|
require 'oxidized/input/cli'
|
|
4
4
|
class Telnet < Input
|
|
5
|
-
RescueFail = {}
|
|
5
|
+
RescueFail = {}.freeze
|
|
6
6
|
include Input::CLI
|
|
7
7
|
attr_reader :telnet
|
|
8
8
|
|
|
9
|
-
def connect
|
|
9
|
+
def connect(node)
|
|
10
10
|
@node = node
|
|
11
11
|
@timeout = Oxidized.config.timeout
|
|
12
12
|
@node.model.cfg['telnet'].each { |cb| instance_exec(&cb) }
|
|
13
13
|
@log = File.open(Oxidized::Config::Log + "/#{@node.ip}-telnet", 'w') if Oxidized.config.input.debug?
|
|
14
14
|
port = vars(:telnet_port) || 23
|
|
15
15
|
|
|
16
|
-
telnet_opts = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
telnet_opts = {
|
|
17
|
+
'Host' => @node.ip,
|
|
18
|
+
'Port' => port.to_i,
|
|
19
|
+
'Timeout' => @timeout,
|
|
20
|
+
'Model' => @node.model,
|
|
21
|
+
'Log' => @log
|
|
22
|
+
}
|
|
21
23
|
|
|
22
24
|
@telnet = Net::Telnet.new telnet_opts
|
|
23
25
|
begin
|
|
@@ -29,10 +31,10 @@ module Oxidized
|
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def connected?
|
|
32
|
-
@telnet
|
|
34
|
+
@telnet && (not @telnet.sock.closed?)
|
|
33
35
|
end
|
|
34
36
|
|
|
35
|
-
def cmd
|
|
37
|
+
def cmd(cmd_str, expect = @node.prompt)
|
|
36
38
|
return send(cmd_str + "\n") unless expect
|
|
37
39
|
|
|
38
40
|
Oxidized.logger.debug "Telnet: #{cmd_str} @#{@node.name}"
|
|
@@ -42,7 +44,7 @@ module Oxidized
|
|
|
42
44
|
@telnet.cmd args
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
def send
|
|
47
|
+
def send(data)
|
|
46
48
|
@telnet.write data
|
|
47
49
|
end
|
|
48
50
|
|
|
@@ -52,19 +54,17 @@ module Oxidized
|
|
|
52
54
|
|
|
53
55
|
private
|
|
54
56
|
|
|
55
|
-
def expect
|
|
56
|
-
@telnet.oxidized_expect expect:
|
|
57
|
+
def expect(regex)
|
|
58
|
+
@telnet.oxidized_expect expect: regex, timeout: @timeout
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
def disconnect
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
(@telnet.close rescue true) unless @telnet.sock.closed?
|
|
67
|
-
end
|
|
62
|
+
disconnect_cli
|
|
63
|
+
@telnet.close
|
|
64
|
+
rescue Errno::ECONNRESET # rubocop:disable Lint/HandleExceptions
|
|
65
|
+
ensure
|
|
66
|
+
@log.close if Oxidized.config.input.debug?
|
|
67
|
+
(@telnet.close rescue true) unless @telnet.sock.closed?
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -73,14 +73,14 @@ class Net::Telnet
|
|
|
73
73
|
## how to do this, without redefining the whole damn thing
|
|
74
74
|
## FIXME: we also need output (not sure I'm going to support this)
|
|
75
75
|
attr_reader :output
|
|
76
|
-
def oxidized_expect(options)
|
|
76
|
+
def oxidized_expect(options)
|
|
77
77
|
model = @options["Model"]
|
|
78
78
|
@log = @options["Log"]
|
|
79
79
|
|
|
80
80
|
expects = [options[:expect]].flatten
|
|
81
81
|
time_out = options[:timeout] || @options["Timeout"] || Oxidized.config.timeout?
|
|
82
82
|
|
|
83
|
-
Timeout
|
|
83
|
+
Timeout.timeout(time_out) do
|
|
84
84
|
line = ""
|
|
85
85
|
rest = ""
|
|
86
86
|
buf = ""
|
|
@@ -93,8 +93,8 @@ class Net::Telnet
|
|
|
93
93
|
Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
|
|
94
94
|
buf = preprocess(c[0...c.rindex(/#{IAC}#{SB}/no)])
|
|
95
95
|
rest = c[c.rindex(/#{IAC}#{SB}/no)..-1]
|
|
96
|
-
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
|
|
97
|
-
c.rindex(/\r\z/no)
|
|
96
|
+
elsif (pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
|
|
97
|
+
c.rindex(/\r\z/no))
|
|
98
98
|
buf = preprocess(c[0...pt])
|
|
99
99
|
rest = c[pt..-1]
|
|
100
100
|
else
|
data/lib/oxidized/input/tftp.rb
CHANGED
|
@@ -1,41 +1,40 @@
|
|
|
1
1
|
module Oxidized
|
|
2
2
|
require 'stringio'
|
|
3
3
|
require_relative 'cli'
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
begin
|
|
6
6
|
require 'net/tftp'
|
|
7
7
|
rescue LoadError
|
|
8
8
|
raise OxidizedError, 'net/tftp not found: sudo gem install net-tftp'
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
class TFTP < Input
|
|
12
|
-
|
|
13
12
|
include Input::CLI
|
|
14
|
-
|
|
13
|
+
|
|
15
14
|
# TFTP utilizes UDP, there is not a connection. We simply specify an IP and send/receive data.
|
|
16
|
-
def connect
|
|
17
|
-
@node
|
|
15
|
+
def connect(node)
|
|
16
|
+
@node = node
|
|
18
17
|
|
|
19
18
|
@node.model.cfg['tftp'].each { |cb| instance_exec(&cb) }
|
|
20
19
|
@log = File.open(Oxidized::Config::Log + "/#{@node.ip}-tftp", 'w') if Oxidized.config.input.debug?
|
|
21
20
|
@tftp = Net::TFTP.new @node.ip
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
def cmd
|
|
23
|
+
def cmd(file)
|
|
25
24
|
Oxidized.logger.debug "TFTP: #{file} @ #{@node.name}"
|
|
26
25
|
config = StringIO.new
|
|
27
26
|
@tftp.getbinary file, config
|
|
28
27
|
config.rewind
|
|
29
28
|
config.read
|
|
30
29
|
end
|
|
31
|
-
|
|
30
|
+
|
|
32
31
|
private
|
|
33
|
-
|
|
32
|
+
|
|
34
33
|
def disconnect
|
|
35
34
|
# TFTP uses UDP, there is no connection to close
|
|
35
|
+
true
|
|
36
36
|
ensure
|
|
37
37
|
@log.close if Oxidized.config.input.debug?
|
|
38
38
|
end
|
|
39
|
-
|
|
40
39
|
end
|
|
41
40
|
end
|
data/lib/oxidized/jobs.rb
CHANGED
|
@@ -4,11 +4,11 @@ module Oxidized
|
|
|
4
4
|
MAX_INTER_JOB_GAP = 300 # add job if more than X from last job started
|
|
5
5
|
attr_accessor :interval, :max, :want
|
|
6
6
|
|
|
7
|
-
def initialize
|
|
7
|
+
def initialize(max, interval, nodes)
|
|
8
8
|
@max = max
|
|
9
9
|
# Set interval to 1 if interval is 0 (=disabled) so we don't break
|
|
10
10
|
# the 'ceil' function
|
|
11
|
-
@interval = interval
|
|
11
|
+
@interval = interval.zero? ? 1 : interval
|
|
12
12
|
@nodes = nodes
|
|
13
13
|
@last = Time.now.utc
|
|
14
14
|
@durations = Array.new @nodes.size, AVERAGE_DURATION
|
|
@@ -16,12 +16,12 @@ module Oxidized
|
|
|
16
16
|
super()
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def push
|
|
19
|
+
def push(arg)
|
|
20
20
|
@last = Time.now.utc
|
|
21
21
|
super
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def duration
|
|
24
|
+
def duration(last)
|
|
25
25
|
if @durations.size > @nodes.size
|
|
26
26
|
@durations.slice! @nodes.size...@durations.size
|
|
27
27
|
elsif @durations.size < @nodes.size
|
|
@@ -44,9 +44,9 @@ module Oxidized
|
|
|
44
44
|
# and b) we want less threads running than the total amount of nodes
|
|
45
45
|
# and c) there is more than MAX_INTER_JOB_GAP since last one was started
|
|
46
46
|
# then we want one more thread (rationale is to fix hanging thread causing HOLB)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return unless @want <= size && @want < @nodes.size
|
|
48
|
+
|
|
49
|
+
@want += 1 if (Time.now.utc - @last) > MAX_INTER_JOB_GAP
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|