oxidized 0.34.3 → 0.36.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/.coderabbit.yaml +21 -0
- data/.github/workflows/codeql.yml +4 -4
- data/.github/workflows/publishdocker.yml +88 -15
- data/.github/workflows/ruby.yml +2 -4
- data/.github/workflows/stale.yml +1 -1
- data/.rubocop.yml +14 -2
- data/.rubocop_todo.yml +21 -2
- data/CHANGELOG.md +86 -1
- data/Dockerfile +74 -66
- data/README.md +4 -5
- data/Rakefile +21 -3
- data/docs/Configuration.md +122 -1
- data/docs/Creating-Models.md +209 -28
- data/docs/Docker.md +2 -1
- data/docs/Inputs.md +29 -0
- data/docs/Model-Notes/APC.md +72 -0
- data/docs/Model-Notes/ExaLink.md +43 -0
- data/docs/Model-Notes/Fortinet.md +75 -0
- data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
- data/docs/Model-Notes/TrueNAS.md +19 -0
- data/docs/ModelUnitTests.md +23 -0
- data/docs/Outputs.md +18 -4
- data/docs/Release.md +1 -1
- data/docs/Ruby-API.md +134 -1
- data/docs/Supported-OS-Types.md +22 -8
- data/docs/Troubleshooting.md +1 -1
- data/extra/device2yaml.rb +2 -3
- data/extra/hooks/modelrules.rb +55 -0
- data/extra/hooks/modelrulesadvanced.rb +168 -0
- data/extra/hooks/srcipmap.rb +54 -0
- data/extra/oxidized.runit +1 -1
- data/lib/oxidized/core.rb +2 -1
- data/lib/oxidized/hook/githubrepo.rb +2 -1
- data/lib/oxidized/hook.rb +56 -8
- data/lib/oxidized/input/exec.rb +0 -4
- data/lib/oxidized/input/ftp.rb +0 -13
- data/lib/oxidized/input/http.rb +47 -15
- data/lib/oxidized/input/input.rb +33 -13
- data/lib/oxidized/input/scp.rb +11 -65
- data/lib/oxidized/input/ssh.rb +12 -62
- data/lib/oxidized/input/sshbase.rb +107 -0
- data/lib/oxidized/input/telnet.rb +2 -6
- data/lib/oxidized/input/tftp.rb +7 -3
- data/lib/oxidized/model/adva.rb +1 -1
- data/lib/oxidized/model/airfiber.rb +1 -1
- data/lib/oxidized/model/aoscx.rb +32 -45
- data/lib/oxidized/model/aosw.rb +11 -12
- data/lib/oxidized/model/apc_aos.rb +4 -0
- data/lib/oxidized/model/apcaos.rb +39 -0
- data/lib/oxidized/model/arubainstant.rb +29 -26
- data/lib/oxidized/model/asa.rb +7 -7
- data/lib/oxidized/model/asternos.rb +1 -1
- data/lib/oxidized/model/axos.rb +1 -1
- data/lib/oxidized/model/comtrol.rb +1 -1
- data/lib/oxidized/model/comware.rb +3 -1
- data/lib/oxidized/model/cumulus.rb +2 -7
- data/lib/oxidized/model/defacto.rb +26 -0
- data/lib/oxidized/model/dslcommands.rb +93 -0
- data/lib/oxidized/model/dslsetup.rb +102 -0
- data/lib/oxidized/model/eatonnetwork.rb +5 -0
- data/lib/oxidized/model/efos.rb +5 -5
- data/lib/oxidized/model/eltex.rb +1 -1
- data/lib/oxidized/model/enterasys800.rb +1 -1
- data/lib/oxidized/model/exalink.rb +36 -0
- data/lib/oxidized/model/fabricos.rb +1 -1
- data/lib/oxidized/model/fastiron.rb +2 -2
- data/lib/oxidized/model/firelinuxos.rb +1 -3
- data/lib/oxidized/model/fortigate.rb +160 -0
- data/lib/oxidized/model/fortios.rb +28 -69
- data/lib/oxidized/model/fsos.rb +2 -4
- data/lib/oxidized/model/garderos.rb +1 -6
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ios.rb +21 -15
- data/lib/oxidized/model/ironware.rb +6 -4
- data/lib/oxidized/model/ivanti.rb +54 -0
- data/lib/oxidized/model/macros.rb +60 -0
- data/lib/oxidized/model/mlnxos.rb +14 -17
- data/lib/oxidized/model/model.rb +89 -98
- data/lib/oxidized/model/ndms.rb +6 -0
- data/lib/oxidized/model/netgear.rb +6 -3
- data/lib/oxidized/model/netonix.rb +1 -1
- data/lib/oxidized/model/netscaler.rb +1 -1
- data/lib/oxidized/model/nxos.rb +9 -9
- data/lib/oxidized/model/onefinity.rb +1 -1
- data/lib/oxidized/model/opnsense.rb +8 -0
- data/lib/oxidized/model/outputs.rb +5 -0
- data/lib/oxidized/model/perle.rb +41 -0
- data/lib/oxidized/model/pfsense.rb +8 -0
- data/lib/oxidized/model/saos10.rb +1 -1
- data/lib/oxidized/model/siklu.rb +1 -1
- data/lib/oxidized/model/siklumhtg.rb +1 -1
- data/lib/oxidized/model/sixwind.rb +1 -1
- data/lib/oxidized/model/slxos.rb +1 -1
- data/lib/oxidized/model/smartbyte.rb +48 -0
- data/lib/oxidized/model/sonicos.rb +1 -1
- data/lib/oxidized/model/speedtouch.rb +1 -1
- data/lib/oxidized/model/telco.rb +1 -1
- data/lib/oxidized/model/tnsr.rb +7 -3
- data/lib/oxidized/model/trango.rb +1 -1
- data/lib/oxidized/model/truenas.rb +10 -1
- data/lib/oxidized/model/ucs.rb +1 -1
- data/lib/oxidized/model/voltaire.rb +1 -1
- data/lib/oxidized/model/voss.rb +3 -0
- data/lib/oxidized/model/vyatta.rb +1 -1
- data/lib/oxidized/model/vyos.rb +36 -0
- data/lib/oxidized/model/zhoneolt.rb +1 -1
- data/lib/oxidized/model/zynoscli.rb +1 -1
- data/lib/oxidized/node.rb +31 -24
- data/lib/oxidized/nodes.rb +2 -0
- data/lib/oxidized/output/file.rb +7 -1
- data/lib/oxidized/output/git.rb +11 -1
- data/lib/oxidized/output/gitcrypt.rb +1 -1
- data/lib/oxidized/output/http.rb +12 -3
- data/lib/oxidized/source/csv.rb +5 -0
- data/lib/oxidized/source/http.rb +10 -2
- data/lib/oxidized/source/jsonfile.rb +5 -0
- data/lib/oxidized/source/sql.rb +5 -0
- data/lib/oxidized/version.rb +2 -2
- data/lib/oxidized/worker.rb +36 -15
- data/lib/refinements.rb +18 -0
- data/oxidized.gemspec +28 -25
- metadata +98 -71
- data/docs/Model-Notes/APC_AOS.md +0 -65
- data/docs/Model-Notes/FortiOS.md +0 -44
- data/lib/oxidized/model/timos.rb +0 -10
data/lib/oxidized/input/ssh.rb
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
require 'net/ssh'
|
|
3
|
-
require 'net/ssh/proxy/command'
|
|
4
2
|
require 'timeout'
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
require_relative 'sshbase'
|
|
4
|
+
|
|
5
|
+
class SSH < SSHBase
|
|
6
|
+
class NoShell < OxidizedError; end
|
|
7
|
+
|
|
7
8
|
RESCUE_FAIL = {
|
|
8
|
-
|
|
9
|
-
Net::SSH::Disconnect
|
|
10
|
-
],
|
|
11
|
-
warn: [
|
|
12
|
-
RuntimeError,
|
|
13
|
-
Net::SSH::AuthenticationFailed
|
|
14
|
-
]
|
|
9
|
+
RuntimeError => :warn
|
|
15
10
|
}.freeze
|
|
16
|
-
include Input::CLI
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
def self.rescue_fail
|
|
13
|
+
super.merge(RESCUE_FAIL)
|
|
14
|
+
end
|
|
19
15
|
|
|
20
16
|
def connect(node) # rubocop:disable Naming/PredicateMethod
|
|
21
17
|
@node = node
|
|
@@ -41,10 +37,6 @@ module Oxidized
|
|
|
41
37
|
connected?
|
|
42
38
|
end
|
|
43
39
|
|
|
44
|
-
def connected?
|
|
45
|
-
@ssh && (not @ssh.closed?)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
40
|
def cmd(cmd, expect = node.prompt)
|
|
49
41
|
logger.debug "Sending '#{cmd.dump}' @ #{node.name} with expect: #{expect.inspect}"
|
|
50
42
|
if Oxidized.config.input.debug?
|
|
@@ -76,10 +68,11 @@ module Oxidized
|
|
|
76
68
|
|
|
77
69
|
private
|
|
78
70
|
|
|
71
|
+
# We need a specific disconnect for SSH in shell mode, see issue #3725
|
|
79
72
|
def disconnect
|
|
80
73
|
disconnect_cli
|
|
81
74
|
# if disconnect does not disconnect us, give up after timeout
|
|
82
|
-
Timeout.timeout(
|
|
75
|
+
Timeout.timeout(@node.timeout) { @ssh.loop }
|
|
83
76
|
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError => e
|
|
84
77
|
logger.debug 'The other side closed the connection while ' \
|
|
85
78
|
"disconnecting, raising #{e.class} with #{e.message}"
|
|
@@ -127,7 +120,7 @@ module Oxidized
|
|
|
127
120
|
def expect(*regexps)
|
|
128
121
|
regexps = [regexps].flatten
|
|
129
122
|
logger.debug "Expecting #{regexps.inspect} at #{node.name}"
|
|
130
|
-
Timeout.timeout(
|
|
123
|
+
Timeout.timeout(@node.timeout) do
|
|
131
124
|
@ssh.loop(0.1) do
|
|
132
125
|
sleep 0.1
|
|
133
126
|
match = regexps.find { |regexp| @output.match regexp }
|
|
@@ -137,48 +130,5 @@ module Oxidized
|
|
|
137
130
|
end
|
|
138
131
|
end
|
|
139
132
|
end
|
|
140
|
-
|
|
141
|
-
def make_ssh_opts
|
|
142
|
-
secure = Oxidized.config.input.ssh.secure?
|
|
143
|
-
ssh_opts = {
|
|
144
|
-
number_of_password_prompts: 0,
|
|
145
|
-
keepalive: vars(:ssh_no_keepalive) ? false : true,
|
|
146
|
-
verify_host_key: secure ? :always : :never,
|
|
147
|
-
append_all_supported_algorithms: true,
|
|
148
|
-
password: @node.auth[:password],
|
|
149
|
-
timeout: Oxidized.config.timeout,
|
|
150
|
-
port: (vars(:ssh_port) || 22).to_i,
|
|
151
|
-
forward_agent: false
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
auth_methods = vars(:auth_methods) || %w[none publickey password]
|
|
155
|
-
ssh_opts[:auth_methods] = auth_methods
|
|
156
|
-
logger.debug "AUTH METHODS::#{auth_methods}"
|
|
157
|
-
|
|
158
|
-
ssh_opts[:proxy] = make_ssh_proxy_command(vars(:ssh_proxy), vars(:ssh_proxy_port), secure) if vars(:ssh_proxy)
|
|
159
|
-
|
|
160
|
-
ssh_opts[:keys] = [vars(:ssh_keys)].flatten if vars(:ssh_keys)
|
|
161
|
-
ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex)
|
|
162
|
-
ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption)
|
|
163
|
-
ssh_opts[:host_key] = vars(:ssh_host_key).split(/,\s*/) if vars(:ssh_host_key)
|
|
164
|
-
ssh_opts[:hmac] = vars(:ssh_hmac).split(/,\s*/) if vars(:ssh_hmac)
|
|
165
|
-
|
|
166
|
-
# Use our logger for Net::SSH
|
|
167
|
-
ssh_logger = SemanticLogger[Net::SSH]
|
|
168
|
-
ssh_logger.level = Oxidized.config.input.debug? ? :debug : :fatal
|
|
169
|
-
ssh_opts[:logger] = ssh_logger
|
|
170
|
-
|
|
171
|
-
ssh_opts
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def make_ssh_proxy_command(proxy_host, proxy_port, secure)
|
|
175
|
-
return nil unless !proxy_host.nil? && !proxy_host.empty?
|
|
176
|
-
|
|
177
|
-
proxy_command = "ssh "
|
|
178
|
-
proxy_command += "-o StrictHostKeyChecking=no " unless secure
|
|
179
|
-
proxy_command += "-p #{proxy_port} " if proxy_port
|
|
180
|
-
proxy_command += "#{proxy_host} -W [%h]:%p"
|
|
181
|
-
Net::SSH::Proxy::Command.new(proxy_command)
|
|
182
|
-
end
|
|
183
133
|
end
|
|
184
134
|
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Oxidized
|
|
2
|
+
require 'net/ssh'
|
|
3
|
+
require 'net/ssh/proxy/command'
|
|
4
|
+
require 'timeout'
|
|
5
|
+
|
|
6
|
+
class SSHBase < Input
|
|
7
|
+
RESCUE_FAIL = {
|
|
8
|
+
Net::SSH::Disconnect => :debug,
|
|
9
|
+
Net::SSH::ConnectionTimeout => :debug,
|
|
10
|
+
Net::SSH::AuthenticationFailed => :warn,
|
|
11
|
+
Net::SSH::HostKeyUnknown => :warn
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
def self.rescue_fail
|
|
15
|
+
super.merge(RESCUE_FAIL)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def connect(node) # rubocop:disable Naming/PredicateMethod
|
|
19
|
+
@node = node
|
|
20
|
+
@node.model.cfg[config_name].each { |cb| instance_exec(&cb) }
|
|
21
|
+
setup_debug_logging
|
|
22
|
+
logger.debug "Connecting to #{@node.name}"
|
|
23
|
+
@ssh = Net::SSH.start(@node.ip, @node.auth[:username], make_ssh_opts)
|
|
24
|
+
connected?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def connected?
|
|
28
|
+
@ssh && (not @ssh.closed?)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def setup_debug_logging
|
|
32
|
+
return unless Oxidized.config.input.debug?
|
|
33
|
+
|
|
34
|
+
logfile = Oxidized::Config::LOG + "/#{@node.ip}-#{config_name}"
|
|
35
|
+
@log = File.open(logfile, 'w')
|
|
36
|
+
logger.debug "I/O Debugging to #{logfile}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def make_ssh_opts
|
|
40
|
+
ssh_opts = {
|
|
41
|
+
number_of_password_prompts: 0,
|
|
42
|
+
keepalive: vars(:ssh_no_keepalive) ? false : true,
|
|
43
|
+
verify_host_key: must_secure? ? :always : :never,
|
|
44
|
+
append_all_supported_algorithms: true,
|
|
45
|
+
password: @node.auth[:password],
|
|
46
|
+
timeout: @node.timeout,
|
|
47
|
+
port: (vars(:ssh_port) || 22).to_i,
|
|
48
|
+
forward_agent: false
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
auth_methods = vars(:auth_methods) || %w[none publickey password]
|
|
52
|
+
ssh_opts[:auth_methods] = auth_methods
|
|
53
|
+
logger.debug "AUTH METHODS::#{auth_methods}"
|
|
54
|
+
|
|
55
|
+
if vars(:ssh_proxy)
|
|
56
|
+
ssh_opts[:proxy] = make_ssh_proxy_command(
|
|
57
|
+
vars(:ssh_proxy), vars(:ssh_proxy_port), must_secure?
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
ssh_opts[:keys] = [vars(:ssh_keys)].flatten if vars(:ssh_keys)
|
|
61
|
+
ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex)
|
|
62
|
+
ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption)
|
|
63
|
+
ssh_opts[:host_key] = vars(:ssh_host_key).split(/,\s*/) if vars(:ssh_host_key)
|
|
64
|
+
ssh_opts[:hmac] = vars(:ssh_hmac).split(/,\s*/) if vars(:ssh_hmac)
|
|
65
|
+
|
|
66
|
+
# Use our logger for Net::SSH
|
|
67
|
+
ssh_logger = SemanticLogger[Net::SSH]
|
|
68
|
+
ssh_logger.level = Oxidized.config.input.debug? ? :debug : :fatal
|
|
69
|
+
ssh_opts[:logger] = ssh_logger
|
|
70
|
+
|
|
71
|
+
ssh_opts
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def must_secure?
|
|
75
|
+
Oxidized.config.input[config_name].secure? == true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def make_ssh_proxy_command(proxy_host, proxy_port, secure)
|
|
79
|
+
return nil unless !proxy_host.nil? && !proxy_host.empty?
|
|
80
|
+
|
|
81
|
+
proxy_command = "ssh "
|
|
82
|
+
proxy_command += "-o StrictHostKeyChecking=no " unless secure
|
|
83
|
+
proxy_command += "-p #{proxy_port} " if proxy_port
|
|
84
|
+
proxy_command += "#{proxy_host} -W [%h]:%p"
|
|
85
|
+
Net::SSH::Proxy::Command.new(proxy_command)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def disconnect
|
|
89
|
+
disconnect_cli
|
|
90
|
+
Timeout.timeout(@node.timeout) do
|
|
91
|
+
@ssh.close
|
|
92
|
+
end
|
|
93
|
+
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError => e
|
|
94
|
+
logger.debug 'The other side closed the connection while ' \
|
|
95
|
+
"disconnecting, raising #{e.class} with #{e.message}"
|
|
96
|
+
rescue Timeout::Error
|
|
97
|
+
logger.debug "#{@node.name} timed out while disconnecting"
|
|
98
|
+
ensure
|
|
99
|
+
@log.close if Oxidized.config.input.debug?
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Methods to implement in subclasses
|
|
103
|
+
def cmd(**_args)
|
|
104
|
+
raise NotImplementedError, "Subclasses must implement cmd"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
module Oxidized
|
|
2
2
|
require 'net/telnet'
|
|
3
|
-
require 'oxidized/input/cli'
|
|
4
3
|
class Telnet < Input
|
|
5
|
-
RESCUE_FAIL = {}.freeze
|
|
6
|
-
include Input::CLI
|
|
7
|
-
|
|
8
4
|
attr_reader :telnet
|
|
9
5
|
|
|
10
6
|
def connect(node) # rubocop:disable Naming/PredicateMethod
|
|
11
7
|
@node = node
|
|
12
|
-
@timeout =
|
|
8
|
+
@timeout = @node.timeout
|
|
13
9
|
@node.model.cfg['telnet'].each { |cb| instance_exec(&cb) }
|
|
14
10
|
@log = File.open(Oxidized::Config::LOG + "/#{@node.ip}-telnet", 'w') if Oxidized.config.input.debug?
|
|
15
11
|
port = vars(:telnet_port) || 23
|
|
@@ -84,7 +80,7 @@ module Net
|
|
|
84
80
|
@log = @options["Log"]
|
|
85
81
|
|
|
86
82
|
expects = [options[:expect]].flatten
|
|
87
|
-
time_out = options[:timeout] || @options["Timeout"]
|
|
83
|
+
time_out = options[:timeout] || @options["Timeout"]
|
|
88
84
|
|
|
89
85
|
Timeout.timeout(time_out) do
|
|
90
86
|
line = ""
|
data/lib/oxidized/input/tftp.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
module Oxidized
|
|
2
2
|
require 'stringio'
|
|
3
|
-
require_relative 'cli'
|
|
4
|
-
|
|
5
3
|
begin
|
|
6
4
|
require 'net/tftp'
|
|
7
5
|
rescue LoadError
|
|
@@ -9,7 +7,13 @@ module Oxidized
|
|
|
9
7
|
end
|
|
10
8
|
|
|
11
9
|
class TFTP < Input
|
|
12
|
-
|
|
10
|
+
RESCUE_FAIL = {
|
|
11
|
+
Net::TFTPTimeout => :warn
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
def self.rescue_fail
|
|
15
|
+
super.merge(RESCUE_FAIL)
|
|
16
|
+
end
|
|
13
17
|
|
|
14
18
|
# TFTP utilizes UDP, there is not a connection. We simply specify an IP and send/receive data.
|
|
15
19
|
def connect(node)
|
data/lib/oxidized/model/adva.rb
CHANGED
data/lib/oxidized/model/aoscx.rb
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
class Aoscx < Oxidized::Model
|
|
2
2
|
using Refinements
|
|
3
|
+
# HPE Aruba Networking - ArubaOS-CX models
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# telnet switchs may start with various vt100 control characters, regex (\e\[24;[0-9][hH]), follwed by the prompt, followed
|
|
7
|
-
# by at least 3 other vt100 characters
|
|
8
|
-
prompt /(^\r|\e\[24;[0-9][hH])?([\w\s.-]+[#>] )($|(\e\[24;[0-9][0-9]?[hH]){3})/
|
|
5
|
+
prompt /^[\w\s.-]+[#>] $/
|
|
6
|
+
clean :escape_codes
|
|
9
7
|
|
|
10
8
|
comment '! '
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
expect /(\e\[1M\e\[\??\d+(;\d+)*[A-Za-z]\e\[1L)|(\eE)/ do |data, re|
|
|
14
|
-
data.gsub re, "\n"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# replace all used vt100 control sequences
|
|
18
|
-
expect /\e\[\??\d+(;\d+)*[A-Za-z]/ do |data, re|
|
|
19
|
-
data.gsub re, ''
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
expect /Press any key to continue(\e\[\??\d+(;\d+)*[A-Za-z])*$/ do
|
|
10
|
+
expect /Press any key to continue$/ do
|
|
23
11
|
send ' '
|
|
24
12
|
""
|
|
25
13
|
end
|
|
@@ -30,19 +18,15 @@ class Aoscx < Oxidized::Model
|
|
|
30
18
|
end
|
|
31
19
|
|
|
32
20
|
cmd :all do |cfg|
|
|
33
|
-
cfg
|
|
34
|
-
cfg = cfg.gsub /^\r/, ''
|
|
35
|
-
# Additional filtering for elder switches sending vt100 control chars via telnet
|
|
36
|
-
cfg.gsub! /\e\[\??\d+(;\d+)*[A-Za-z]/, ''
|
|
37
|
-
# Additional filtering for power usage reporting which obviously changes over time
|
|
38
|
-
cfg.gsub! /^(.*AC [0-9]{3}V\/?([0-9]{3}V)?) *([0-9]{1,3}) (.*)/, '\\1 <removed> \\4'
|
|
39
|
-
cfg
|
|
21
|
+
cfg.cut_both
|
|
40
22
|
end
|
|
41
23
|
|
|
42
24
|
cmd :secret do |cfg|
|
|
25
|
+
cfg.gsub! /^(user .* group .*(?: ciphertext)?) \S+/, '\\1 <secret hidden>'
|
|
43
26
|
cfg.gsub! /^(snmp-server community) \S+(.*)/, '\\1 <secret hidden> \\2'
|
|
44
27
|
cfg.gsub! /^(snmp-server host \S+) \S+(.*)/, '\\1 <secret hidden> \\2'
|
|
45
|
-
cfg.gsub! /^(
|
|
28
|
+
cfg.gsub! /^(snmpv3 user).*?(auth (?:md5|sha(?:\d{1,3})?) auth-pass ciphertext).*?(priv (?:des|aes(?:\d{1,3})?) priv-pass ciphertext).*/, '\\1 <user> \\2 <auth-pass> \\3 <priv-pass>'
|
|
29
|
+
cfg.gsub! /^(radius-server host \S+ key(?: ciphertext)?) \S+ (.*)/, '\\1 <secret hidden> \\2'
|
|
46
30
|
cfg.gsub! /^(radius-server key).*/, '\\1 <configuration removed>'
|
|
47
31
|
cfg.gsub! /^(tacacs-server host \S+ key) \S+(.*)/, '\\1 <secret hidden> \\2'
|
|
48
32
|
cfg.gsub! /^(tacacs-server key).*/, '\\1 <secret hidden>'
|
|
@@ -54,27 +38,30 @@ class Aoscx < Oxidized::Model
|
|
|
54
38
|
end
|
|
55
39
|
|
|
56
40
|
cmd 'show environment' do |cfg|
|
|
57
|
-
cfg
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
41
|
+
def with_section(cfg, section, &block)
|
|
42
|
+
cfg.sub!(/(show environment #{section}.*?-{10,}\n)(.*?)(?=\nshow environment|\z)/m) do
|
|
43
|
+
header = ::Regexp.last_match(1)
|
|
44
|
+
content = ::Regexp.last_match(2)
|
|
45
|
+
block.call(content) if block_given?
|
|
46
|
+
header + content
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
with_section(cfg, 'fan') do |content|
|
|
51
|
+
content.gsub!(/^((?:\S+ +){3})(slow |normal|medium|fast |max |N\/A ) (.*?)\d+ +$/, '\\1<speed> \\3<rpm>')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
with_section(cfg, 'power-consumption') do |content|
|
|
55
|
+
content.gsub!(/^(.*?) (?:\d+\.\d+ +)+\d+\.\d+$/, '\\1 <power hidden>')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
with_section(cfg, 'power-allocation') do |content|
|
|
59
|
+
content.gsub!(/^(.*) \d+ W$/, '\\1 <power>')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
with_section(cfg, 'temperature') do |content|
|
|
63
|
+
content.gsub!(/^(.*) -?\d+\.\d+ C (.*)$/, '\\1 <hidden>\\2')
|
|
64
|
+
end
|
|
78
65
|
comment cfg
|
|
79
66
|
end
|
|
80
67
|
|
data/lib/oxidized/model/aosw.rb
CHANGED
|
@@ -13,7 +13,7 @@ class AOSW < Oxidized::Model
|
|
|
13
13
|
|
|
14
14
|
comment '# '
|
|
15
15
|
# see /spec/model/aosw_spec.rb for prompt examples
|
|
16
|
-
prompt /^\(?[\w
|
|
16
|
+
prompt /^\(?[\w:.@-]+\)? ?[*^]?(\[[\w\/]+\] ?)?[#>] ?$/
|
|
17
17
|
|
|
18
18
|
# Ignore cariage returns - also for the prompt
|
|
19
19
|
expect "\r" do |data, re|
|
|
@@ -48,8 +48,11 @@ class AOSW < Oxidized::Model
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
cmd 'show version' do |cfg|
|
|
51
|
-
cfg = cfg.
|
|
52
|
-
|
|
51
|
+
cfg = cfg.reject_lines [
|
|
52
|
+
/(Switch|AP) uptime/i,
|
|
53
|
+
/Reboot Time and Cause/i
|
|
54
|
+
]
|
|
55
|
+
rstrip_cfg comment cfg
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
cmd 'show inventory' do |cfg|
|
|
@@ -77,15 +80,11 @@ class AOSW < Oxidized::Model
|
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
cmd 'show running-config' do |cfg|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
out << line.strip
|
|
86
|
-
end
|
|
87
|
-
out = out.join "\n"
|
|
88
|
-
out << "\n"
|
|
83
|
+
cfg = cfg.reject_lines [
|
|
84
|
+
/^controller config \d+$/,
|
|
85
|
+
/^Building Configuration/
|
|
86
|
+
]
|
|
87
|
+
rstrip_cfg cfg
|
|
89
88
|
end
|
|
90
89
|
|
|
91
90
|
cfg :telnet do
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
class Apc_aos < Oxidized::Model # rubocop:disable Naming/ClassAndModuleCamelCase
|
|
2
2
|
using Refinements
|
|
3
3
|
|
|
4
|
+
comment '; '
|
|
5
|
+
|
|
4
6
|
cmd 'config.ini' do |cfg|
|
|
7
|
+
logger.warn "Apc_aos is deprecated, use ApcAos instead."
|
|
8
|
+
|
|
5
9
|
cfg.gsub!(/^; Configuration file, generated on.*\n/, '')
|
|
6
10
|
cfg
|
|
7
11
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class ApcAos < Oxidized::Model
|
|
2
|
+
using Refinements
|
|
3
|
+
|
|
4
|
+
# Prompt can be short (apc>) or long (username@apc>)
|
|
5
|
+
prompt /^(:?\S+@)?apc>/
|
|
6
|
+
comment '; '
|
|
7
|
+
|
|
8
|
+
def clean(cfg)
|
|
9
|
+
cfg = cfg.cut_both(2, 1)
|
|
10
|
+
cfg.gsub("\r", "")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
cmd 'about', input: :ssh do |cfg|
|
|
14
|
+
cfg = clean(cfg)
|
|
15
|
+
cfg = cfg.reject_lines [/^Management Uptime: /, /^Date: /, /^Time: /]
|
|
16
|
+
comment cfg
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
cmd 'upsabout', input: :ssh do |cfg|
|
|
20
|
+
cfg = clean(cfg)
|
|
21
|
+
comment cfg
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
cmd 'detstatus -ss', input: :ssh do |cfg|
|
|
25
|
+
cfg = clean(cfg)
|
|
26
|
+
comment cfg
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
cmd 'config.ini', input: %i[scp ftp] do |cfg|
|
|
30
|
+
cfg = cfg.reject_lines [/^; Configuration file, generated on /]
|
|
31
|
+
"; ========== config.ini ==========\n" + cfg
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
inputs [:ssh, %i[scp ftp]]
|
|
35
|
+
|
|
36
|
+
cfg :ssh do
|
|
37
|
+
pre_logout 'exit'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -4,7 +4,7 @@ class ArubaInstant < Oxidized::Model
|
|
|
4
4
|
# Aruba IAP, Instant Controller
|
|
5
5
|
|
|
6
6
|
comment '# '
|
|
7
|
-
prompt(/^ ?[\w
|
|
7
|
+
prompt(/^ ?[\w:.@-]+[#>] $/)
|
|
8
8
|
|
|
9
9
|
cmd :all do |cfg|
|
|
10
10
|
# Remove command echo and prompt
|
|
@@ -31,41 +31,44 @@ class ArubaInstant < Oxidized::Model
|
|
|
31
31
|
|
|
32
32
|
# get software version
|
|
33
33
|
cmd 'show version' do |cfg|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
out += line
|
|
41
|
-
end
|
|
42
|
-
comment out
|
|
34
|
+
cfg = cfg.reject_lines [
|
|
35
|
+
/^(Switch|AP) uptime is /,
|
|
36
|
+
/^Reboot Time and Cause/
|
|
37
|
+
]
|
|
38
|
+
comment cfg
|
|
43
39
|
end
|
|
44
40
|
|
|
45
41
|
# Get serial number
|
|
46
42
|
cmd 'show activate status' do |cfg|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
next if line =~ /^Cloud Activation Key/
|
|
54
|
-
|
|
55
|
-
out += line
|
|
56
|
-
end
|
|
57
|
-
comment out + "\n"
|
|
43
|
+
cfg = cfg.reject_lines [
|
|
44
|
+
/^Activate /,
|
|
45
|
+
/^Provision interval/,
|
|
46
|
+
/^Cloud Activation Key/
|
|
47
|
+
]
|
|
48
|
+
comment cfg + "\n"
|
|
58
49
|
end
|
|
59
50
|
|
|
60
51
|
# Get controlled WLAN-AP
|
|
61
52
|
cmd 'show aps' do |cfg|
|
|
62
53
|
out = ''
|
|
63
54
|
cfg.each_line do |line|
|
|
64
|
-
out +=
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
out += line.sub(
|
|
56
|
+
/^(?'Name'(?:.+?|-{2,})\s{2,}) # \s{2,} = separator between columns
|
|
57
|
+
(?'IPv4'(?:
|
|
58
|
+
IP\ Address|-{2,}| # Header
|
|
59
|
+
(?:\d+\.){3}\S+ # Match an IPv4 to catch AP-Names with two spaces
|
|
60
|
+
)\s{2,})
|
|
61
|
+
(?:(?:.+?|-{2,})\s{2,}){3} # Ignore Mode, Spectrum, Clients
|
|
62
|
+
(?'Type'(?:.+?|-{2,})\s{2,})
|
|
63
|
+
(?'IPv6'(?:.+?|-{2,})\s{2,})
|
|
64
|
+
(?:(?:.+?|-{2,})\s{2,}) # Ignore Mesh Role
|
|
65
|
+
(?'Zone'(?:.+?|-{2,})\s{2,})
|
|
66
|
+
(?'Serial'(?:.+?|-{2,}))
|
|
67
|
+
\s{2,} # Last separator
|
|
68
|
+
.*$ # Ignore the rest
|
|
69
|
+
/x,
|
|
70
|
+
'\k<Name>\k<IPv4>\k<Type>\k<IPv6>\k<Zone>\k<Serial>'
|
|
71
|
+
)
|
|
69
72
|
end
|
|
70
73
|
comment out + "\n"
|
|
71
74
|
end
|
data/lib/oxidized/model/asa.rb
CHANGED
|
@@ -32,13 +32,13 @@ class ASA < Oxidized::Model
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
cmd 'show version' do |cfg|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
comment cfg.reject_lines [
|
|
36
|
+
# avoid commits due to uptime / ixo-router01 up 2 mins 28 secs / ixo-router01 up 1 days 2 hours
|
|
37
|
+
/(\s+up\s+\d+\s+)|(.*days.*)/,
|
|
38
|
+
/^Configuration has not been modified since last system restart.*/,
|
|
39
|
+
/^Configuration last modified by.*/,
|
|
40
|
+
/^Start-up time.*/
|
|
41
|
+
]
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
cmd 'show inventory' do |cfg|
|
data/lib/oxidized/model/axos.rb
CHANGED
|
@@ -21,8 +21,10 @@ class Comware < Oxidized::Model
|
|
|
21
21
|
|
|
22
22
|
cmd :secret do |cfg|
|
|
23
23
|
cfg.gsub! /^( snmp-agent community).*/, '\\1 <configuration removed>'
|
|
24
|
-
cfg.gsub!
|
|
24
|
+
cfg.gsub! /(password hash).*/, '\\1 <configuration removed>'
|
|
25
25
|
cfg.gsub! /^( password cipher).*/, '\\1 <configuration removed>'
|
|
26
|
+
cfg.gsub! /(key (authentication )?cipher) \S+/, '\\1 <configuration removed>'
|
|
27
|
+
cfg.gsub! /(cipher authentication-mode (md5|sha)).\S+ (privacy-mode (des56|3des|aes\d{0,3})) .\S+/, '\\1 <auth-pass> \\3 <priv-pass>'
|
|
26
28
|
cfg
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
class Cumulus < Oxidized::Model
|
|
2
2
|
using Refinements
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
expect /\e\[[0-?]*[ -\/]*[@-~]\r?/ do |data, re|
|
|
6
|
-
data.gsub re, ''
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
# The prompt contains ANSI escape codes, which have already been removed
|
|
10
|
-
# from the expect call above
|
|
4
|
+
# Regular expression explanation:
|
|
11
5
|
# ^ : match begin of line, to have the most specific prompt
|
|
12
6
|
# [\w.-]+@[\w.-]+ : user@hostname
|
|
13
7
|
# (:mgmt)? : optional when logged in out of band
|
|
14
8
|
# :~[#$] $ : end of prompt, containing the linux path,
|
|
15
9
|
# which is always "~" in our context
|
|
16
10
|
prompt /^[\w.-]+@[\w.-]+(:mgmt)?:~[#$] $/
|
|
11
|
+
clean :escape_codes
|
|
17
12
|
comment '# '
|
|
18
13
|
|
|
19
14
|
# add a comment in the final conf
|