oxidized 0.33.0 → 0.34.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/ISSUE_TEMPLATE/bug_report.md +4 -1
- data/.github/ISSUE_TEMPLATE/support-request.md +4 -1
- data/.github/workflows/ruby.yml +4 -2
- data/.gitignore +1 -0
- data/.rubocop.yml +29 -6
- data/.rubocop_todo.yml +2 -35
- data/CHANGELOG.md +49 -0
- data/CONTRIBUTING.md +10 -3
- data/Dockerfile +4 -4
- data/README.md +52 -55
- data/Rakefile +2 -3
- data/docs/Configuration.md +97 -0
- data/docs/DeviceSimulation.md +19 -7
- data/docs/Docker.md +9 -4
- data/docs/Issues.md +11 -2
- data/docs/ModelUnitTests.md +35 -25
- data/docs/Outputs.md +83 -2
- data/docs/Release.md +30 -22
- data/docs/Supported-OS-Types.md +4 -0
- data/docs/Troubleshooting.md +4 -18
- data/extra/device2yaml.rb +24 -9
- data/extra/rest_client.rb +2 -1
- data/extra/syslog.rb +8 -3
- data/lib/oxidized/cli.rb +7 -3
- data/lib/oxidized/config/vars.rb +7 -3
- data/lib/oxidized/config.rb +0 -1
- data/lib/oxidized/core.rb +5 -4
- data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
- data/lib/oxidized/hook/exec.rb +5 -4
- data/lib/oxidized/hook/githubrepo.rb +23 -17
- data/lib/oxidized/hook/noophook.rb +2 -2
- data/lib/oxidized/hook/slackdiff.rb +9 -8
- data/lib/oxidized/hook/xmppdiff.rb +9 -9
- data/lib/oxidized/hook.rb +10 -8
- data/lib/oxidized/input/cli.rb +8 -3
- data/lib/oxidized/input/exec.rb +1 -1
- data/lib/oxidized/input/ftp.rb +2 -2
- data/lib/oxidized/input/http.rb +5 -5
- data/lib/oxidized/input/input.rb +1 -0
- data/lib/oxidized/input/scp.rb +2 -2
- data/lib/oxidized/input/ssh.rb +21 -14
- data/lib/oxidized/input/telnet.rb +3 -3
- data/lib/oxidized/input/tftp.rb +1 -1
- data/lib/oxidized/job.rb +7 -4
- data/lib/oxidized/logger.rb +51 -0
- data/lib/oxidized/model/acos.rb +1 -0
- data/lib/oxidized/model/aos7.rb +6 -0
- data/lib/oxidized/model/aoscx.rb +2 -0
- data/lib/oxidized/model/aosw.rb +22 -17
- data/lib/oxidized/model/aricentiss.rb +2 -2
- data/lib/oxidized/model/asa.rb +3 -3
- data/lib/oxidized/model/awplus.rb +13 -10
- data/lib/oxidized/model/edgecos.rb +2 -1
- data/lib/oxidized/model/edgeos.rb +7 -6
- data/lib/oxidized/model/edgeswitch.rb +3 -1
- data/lib/oxidized/model/efos.rb +41 -0
- data/lib/oxidized/model/eltex.rb +1 -1
- data/lib/oxidized/model/fabricos.rb +1 -1
- data/lib/oxidized/model/fastiron.rb +3 -1
- data/lib/oxidized/model/firelinuxos.rb +12 -3
- data/lib/oxidized/model/fortios.rb +2 -1
- data/lib/oxidized/model/gaiaos.rb +4 -4
- data/lib/oxidized/model/ios.rb +15 -5
- data/lib/oxidized/model/ironware.rb +1 -1
- data/lib/oxidized/model/junos.rb +4 -0
- data/lib/oxidized/model/linksyssrw.rb +3 -3
- data/lib/oxidized/model/mlnxos.rb +14 -7
- data/lib/oxidized/model/model.rb +4 -3
- data/lib/oxidized/model/netgear.rb +2 -0
- data/lib/oxidized/model/nsxdfw.rb +2 -1
- data/lib/oxidized/model/nsxfirewall.rb +2 -1
- data/lib/oxidized/model/nxos.rb +2 -2
- data/lib/oxidized/model/openwrt.rb +6 -6
- data/lib/oxidized/model/procurve.rb +3 -1
- data/lib/oxidized/model/qtech.rb +3 -1
- data/lib/oxidized/model/quantaos.rb +8 -6
- data/lib/oxidized/model/routeros.rb +3 -2
- data/lib/oxidized/model/saos10.rb +38 -0
- data/lib/oxidized/model/sixwind.rb +28 -0
- data/lib/oxidized/model/sonicos.rb +1 -1
- data/lib/oxidized/model/supermicro.rb +1 -1
- data/lib/oxidized/model/timos.rb +1 -1
- data/lib/oxidized/model/tmos.rb +1 -0
- data/lib/oxidized/model/tnsr.rb +53 -0
- data/lib/oxidized/model/trango.rb +3 -1
- data/lib/oxidized/model/unifiap.rb +7 -5
- data/lib/oxidized/model/vrp.rb +3 -1
- data/lib/oxidized/model/xos.rb +3 -1
- data/lib/oxidized/model/zhoneolt.rb +3 -1
- data/lib/oxidized/model/zynos.rb +3 -3
- data/lib/oxidized/node.rb +44 -27
- data/lib/oxidized/nodes.rb +8 -4
- data/lib/oxidized/output/file.rb +28 -0
- data/lib/oxidized/output/git.rb +66 -9
- data/lib/oxidized/output/gitcrypt.rb +15 -13
- data/lib/oxidized/output/http.rb +5 -4
- data/lib/oxidized/output/output.rb +14 -0
- data/lib/oxidized/source/http.rb +4 -2
- data/lib/oxidized/version.rb +2 -2
- data/lib/oxidized/worker.rb +11 -8
- data/lib/oxidized.rb +3 -24
- data/oxidized.gemspec +8 -5
- metadata +54 -21
data/lib/oxidized/input/ssh.rb
CHANGED
@@ -16,7 +16,7 @@ module Oxidized
|
|
16
16
|
include Input::CLI
|
17
17
|
class NoShell < OxidizedError; end
|
18
18
|
|
19
|
-
def connect(node)
|
19
|
+
def connect(node) # rubocop:disable Naming/PredicateMethod
|
20
20
|
@node = node
|
21
21
|
@output = String.new('')
|
22
22
|
@pty_options = { term: "vt100" }
|
@@ -24,10 +24,10 @@ module Oxidized
|
|
24
24
|
if Oxidized.config.input.debug?
|
25
25
|
logfile = Oxidized::Config::LOG + "/#{@node.ip}-ssh"
|
26
26
|
@log = File.open(logfile, 'w')
|
27
|
-
|
27
|
+
logger.debug "I/O Debuging to #{logfile}"
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
logger.debug "Connecting to #{@node.name}"
|
31
31
|
@ssh = Net::SSH.start(@node.ip, @node.auth[:username], make_ssh_opts)
|
32
32
|
unless @exec
|
33
33
|
shell_open @ssh
|
@@ -45,9 +45,9 @@ module Oxidized
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def cmd(cmd, expect = node.prompt)
|
48
|
-
|
48
|
+
logger.debug "Sending '#{cmd.dump}' @ #{node.name} with expect: #{expect.inspect}"
|
49
49
|
if Oxidized.config.input.debug?
|
50
|
-
@log.puts "sent #{cmd.dump}"
|
50
|
+
@log.puts "sent cmd #{@exec ? cmd.dump : (cmd + newline).dump}"
|
51
51
|
@log.flush
|
52
52
|
end
|
53
53
|
cmd_output = if @exec
|
@@ -60,6 +60,10 @@ module Oxidized
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def send(data)
|
63
|
+
if Oxidized.config.input.debug?
|
64
|
+
@log.puts "sent data #{data.dump}"
|
65
|
+
@log.flush
|
66
|
+
end
|
63
67
|
@ses.send_data data
|
64
68
|
end
|
65
69
|
|
@@ -75,8 +79,11 @@ module Oxidized
|
|
75
79
|
disconnect_cli
|
76
80
|
# if disconnect does not disconnect us, give up after timeout
|
77
81
|
Timeout.timeout(Oxidized.config.timeout) { @ssh.loop }
|
78
|
-
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError
|
79
|
-
|
82
|
+
rescue Errno::ECONNRESET, Net::SSH::Disconnect, IOError => e
|
83
|
+
logger.debug 'The other side closed the connection while ' \
|
84
|
+
"disconnecting, rasing #{e.class} with #{e.messages}"
|
85
|
+
rescue Timeout::Error
|
86
|
+
logger.debug "#{@node.name} timed out while disconnecting"
|
80
87
|
ensure
|
81
88
|
@log.close if Oxidized.config.input.debug?
|
82
89
|
(@ssh.close rescue true) unless @ssh.closed?
|
@@ -110,7 +117,7 @@ module Oxidized
|
|
110
117
|
|
111
118
|
def cmd_shell(cmd, expect_re)
|
112
119
|
@output = String.new('')
|
113
|
-
@ses.send_data cmd +
|
120
|
+
@ses.send_data cmd + newline
|
114
121
|
@ses.process
|
115
122
|
expect expect_re if expect_re
|
116
123
|
@output
|
@@ -118,7 +125,7 @@ module Oxidized
|
|
118
125
|
|
119
126
|
def expect(*regexps)
|
120
127
|
regexps = [regexps].flatten
|
121
|
-
|
128
|
+
logger.debug "Expecting #{regexps.inspect} at #{node.name}"
|
122
129
|
Timeout.timeout(Oxidized.config.timeout) do
|
123
130
|
@ssh.loop(0.1) do
|
124
131
|
sleep 0.1
|
@@ -145,7 +152,7 @@ module Oxidized
|
|
145
152
|
|
146
153
|
auth_methods = vars(:auth_methods) || %w[none publickey password]
|
147
154
|
ssh_opts[:auth_methods] = auth_methods
|
148
|
-
|
155
|
+
logger.debug "AUTH METHODS::#{auth_methods}"
|
149
156
|
|
150
157
|
ssh_opts[:proxy] = make_ssh_proxy_command(vars(:ssh_proxy), vars(:ssh_proxy_port), secure) if vars(:ssh_proxy)
|
151
158
|
|
@@ -155,10 +162,10 @@ module Oxidized
|
|
155
162
|
ssh_opts[:host_key] = vars(:ssh_host_key).split(/,\s*/) if vars(:ssh_host_key)
|
156
163
|
ssh_opts[:hmac] = vars(:ssh_hmac).split(/,\s*/) if vars(:ssh_hmac)
|
157
164
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
165
|
+
# Use our logger for Net:SSH
|
166
|
+
ssh_logger = SemanticLogger[Net::SSH]
|
167
|
+
ssh_logger.level = Oxidized.config.input.debug? ? :debug : :error
|
168
|
+
ssh_opts[:logger] = ssh_logger
|
162
169
|
|
163
170
|
ssh_opts
|
164
171
|
end
|
@@ -6,7 +6,7 @@ module Oxidized
|
|
6
6
|
include Input::CLI
|
7
7
|
attr_reader :telnet
|
8
8
|
|
9
|
-
def connect(node)
|
9
|
+
def connect(node) # rubocop:disable Naming/PredicateMethod
|
10
10
|
@node = node
|
11
11
|
@timeout = Oxidized.config.timeout
|
12
12
|
@node.model.cfg['telnet'].each { |cb| instance_exec(&cb) }
|
@@ -35,7 +35,7 @@ module Oxidized
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def cmd(cmd_str, expect = @node.prompt)
|
38
|
-
|
38
|
+
logger.debug "Telnet: #{cmd_str} @#{@node.name}"
|
39
39
|
return send(cmd_str + "\r\n") unless expect
|
40
40
|
|
41
41
|
# create a string to be passed to oxidized_expect and modified _there_
|
@@ -78,7 +78,7 @@ module Net
|
|
78
78
|
## FIXME: we also need output (not sure I'm going to support this)
|
79
79
|
attr_reader :output
|
80
80
|
|
81
|
-
def oxidized_expect(options)
|
81
|
+
def oxidized_expect(options)
|
82
82
|
model = @options["Model"]
|
83
83
|
@log = @options["Log"]
|
84
84
|
|
data/lib/oxidized/input/tftp.rb
CHANGED
data/lib/oxidized/job.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
module Oxidized
|
2
2
|
class Job < Thread
|
3
|
+
include SemanticLogger::Loggable
|
4
|
+
|
3
5
|
attr_reader :start, :end, :status, :time, :node, :config
|
4
6
|
|
5
7
|
def initialize(node)
|
6
|
-
@node
|
7
|
-
@start
|
8
|
+
@node = node
|
9
|
+
@start = Time.now.utc
|
10
|
+
self.name = "Oxidized::Job '#{@node.name}'"
|
8
11
|
super do
|
9
|
-
|
12
|
+
logger.debug "Starting fetching process for #{@node.name} at #{Time.now.utc}"
|
10
13
|
@status, @config = @node.run
|
11
14
|
@end = Time.now.utc
|
12
15
|
@time = @end - @start
|
13
|
-
|
16
|
+
logger.debug "Config fetched for #{@node.name} at #{@end}"
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'semantic_logger'
|
2
|
+
|
3
|
+
module Oxidized
|
4
|
+
module Logger
|
5
|
+
include SemanticLogger::Loggable
|
6
|
+
|
7
|
+
def self.setup
|
8
|
+
config = Oxidized.config
|
9
|
+
FileUtils.mkdir_p(Config::LOG) unless File.directory?(Config::LOG)
|
10
|
+
|
11
|
+
SemanticLogger.add_signal_handler
|
12
|
+
|
13
|
+
if config.use_syslog?
|
14
|
+
SemanticLogger.add_appender(appender: :syslog)
|
15
|
+
logger.warn("The configuration 'use_syslog' is deprecated. " \
|
16
|
+
"Remove it and use 'logger' instead")
|
17
|
+
elsif config.log?
|
18
|
+
SemanticLogger.add_appender(file_name: File.expand_path(config.log))
|
19
|
+
logger.warn("The configuration 'log' is deprecated. " \
|
20
|
+
"Remove it and use 'logger' instead")
|
21
|
+
elsif config.logger?
|
22
|
+
SemanticLogger.default_level = config.logger.level if config.logger.level?
|
23
|
+
config.logger.appenders.each { |a| add_appender a } if config.logger.has_key?('appenders')
|
24
|
+
end
|
25
|
+
|
26
|
+
# No appenders configured
|
27
|
+
SemanticLogger.add_appender(io: $stderr) if SemanticLogger.appenders.empty?
|
28
|
+
|
29
|
+
return if %i[trace debug].include?(SemanticLogger.default_level)
|
30
|
+
|
31
|
+
SemanticLogger.default_level = :debug if config.debug?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.add_appender(appender)
|
35
|
+
case appender['type']
|
36
|
+
when 'file'
|
37
|
+
params = { file_name: File.expand_path(appender['file']) }
|
38
|
+
when 'stderr'
|
39
|
+
params = { io: $stderr }
|
40
|
+
when 'stdout'
|
41
|
+
params = { io: $stdout }
|
42
|
+
when 'syslog'
|
43
|
+
params = { appender: :syslog, application: "oxidized" }
|
44
|
+
else
|
45
|
+
raise InvalidConfig, "Unknown logger #{appender['type']}, edit #{Oxidized::Config.configfile}"
|
46
|
+
end
|
47
|
+
params[:level] = appender['level'] if appender.has_key?('level')
|
48
|
+
SemanticLogger.add_appender(**params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/oxidized/model/acos.rb
CHANGED
@@ -20,6 +20,7 @@ class ACOS < Oxidized::Model
|
|
20
20
|
cfg.gsub! /\s(Memory).*/, ' \\1 <removed>'
|
21
21
|
cfg.gsub! /\s(Current time is).*/, ' \\1 <removed>'
|
22
22
|
cfg.gsub! /\s(The system has been up).*/, ' \\1 <removed>'
|
23
|
+
cfg.gsub! /\s(Hardware: \d+ CPUs\(Stepping \d+\). Single \d+G drive. Free storage is).*/, ' \\1 <removed>'
|
23
24
|
comment cfg
|
24
25
|
end
|
25
26
|
|
data/lib/oxidized/model/aos7.rb
CHANGED
@@ -33,10 +33,16 @@ class AOS7 < Oxidized::Model
|
|
33
33
|
end
|
34
34
|
|
35
35
|
cmd 'show running-directory' do |cfg|
|
36
|
+
# Remove extra lines occuring when the command runs slow
|
37
|
+
cfg.gsub! /^Please wait...\n/, ''
|
38
|
+
cfg.gsub! /^\n\n/, "\n"
|
36
39
|
comment cfg
|
37
40
|
end
|
38
41
|
|
39
42
|
cmd 'show configuration snapshot' do |cfg|
|
43
|
+
# Remove extra lines occuring when the command runs slow
|
44
|
+
cfg.gsub! /^Please wait...\n/, ''
|
45
|
+
cfg.gsub! /^\n\n/, "\n"
|
40
46
|
cfg
|
41
47
|
end
|
42
48
|
|
data/lib/oxidized/model/aoscx.rb
CHANGED
@@ -58,6 +58,8 @@ class Aoscx < Oxidized::Model
|
|
58
58
|
cfg.gsub! /^(\d\/\d\/\d.*\s+)\d+\s+$/, '\\1<hidden>'
|
59
59
|
cfg.gsub! /^(\d+\/?\S+\s+\S+\s+)\d+\.\d+\s+C\s+(.*)/, '\\1<hidden> \\2'
|
60
60
|
cfg.gsub! /^(LC.*\s+)\d+\.\d+\s+(C.*)$/, '\\1 <hidden> \\2'
|
61
|
+
# match show environment No speed shown for switches CX83xx, e.g. "PSU-1/1/1 N/A N/A N/A front-to-back ok 7360"
|
62
|
+
cfg.gsub! /^PSU(\S+\s+\S+\s+\s+\S+\s+)(slow|normal|medium|fast|max|N\/A)\s+(\S+\s+\S+\s+)\d+[[:blank:]]+/, '\\1<speed> \\3<rpm>'
|
61
63
|
cfg.gsub! /^(\S+\s+\S+\s+\s+\S+\s+)(slow|normal|medium|fast|max)\s+(\S+\s+\S+\s+)\d+[[:blank:]]+/, '\\1<speed> \\3<rpm>'
|
62
64
|
# match show environment power-consumption on VSF or standadlone, non-chassis and non-6400 switch, e.g. "2 6300M 48G 4SFP56 Swch 156.00 155.94"
|
63
65
|
cfg.gsub! /^(\d+\s+.+\s+)(\s{2}\d{2}\.\d{2}|\s{1}\d{3}\.\d{2}|\d{4}\.\d{2})(\s+)(\s{2}\d{2}\.\d{2}|\s{1}\d{3}\.\d{2}|\d{4}\.\d{2})$/, '\\1<power>\\3<power>'
|
data/lib/oxidized/model/aosw.rb
CHANGED
@@ -25,24 +25,25 @@ class AOSW < Oxidized::Model
|
|
25
25
|
end
|
26
26
|
|
27
27
|
cmd :secret do |cfg|
|
28
|
-
cfg.gsub!(/secret (\S+)
|
29
|
-
cfg.gsub!(/enable secret (\S+)
|
30
|
-
cfg.gsub!(/PRE-SHARE (\S+)
|
31
|
-
cfg.gsub!(/ipsec (\S+)
|
32
|
-
cfg.gsub!(/community (\S+)
|
28
|
+
cfg.gsub!(/secret (\S+)\s?$/, 'secret <secret removed>')
|
29
|
+
cfg.gsub!(/enable secret (\S+)\s?$/, 'enable secret <secret removed>')
|
30
|
+
cfg.gsub!(/PRE-SHARE (\S+)\s?$/, 'PRE-SHARE <secret removed>')
|
31
|
+
cfg.gsub!(/ipsec (\S+)\s?$/, 'ipsec <secret removed>')
|
32
|
+
cfg.gsub!(/community (\S+)\s?$/, 'community <secret removed>')
|
33
33
|
cfg.gsub!(/ sha (\S+)/, ' sha <secret removed>')
|
34
34
|
cfg.gsub!(/ des (\S+)/, ' des <secret removed>')
|
35
35
|
cfg.gsub!(/mobility-manager (\S+) user (\S+) (\S+)/, 'mobility-manager \1 user \2 <secret removed>')
|
36
|
-
cfg.gsub!(/mgmt-user (\S+) (root|guest-provisioning|network-operations|read-only|location-api-mgmt) (\S+)
|
37
|
-
cfg.gsub!(/mgmt-user (\S+) (\S+)( (read-only|guest-mgmt))?$/, 'mgmt-user \1 <secret removed> \3') # IAP
|
36
|
+
cfg.gsub!(/mgmt-user (\S+) (root|guest-provisioning|network-operations|read-only|location-api-mgmt) (\S+)\s?$/, 'mgmt-user \1 \2 <secret removed>') # MAS & Wireless Controler
|
37
|
+
cfg.gsub!(/mgmt-user (\S+) (\S+)( (read-only|guest-mgmt))?\s?$/, 'mgmt-user \1 <secret removed> \3') # IAP
|
38
38
|
# MAS format: mgmt-user <username> <accesslevel> <password hash>
|
39
39
|
# IAP format (root user): mgmt-user <username> <password hash>
|
40
40
|
# IAP format: mgmt-user <username> <password hash> <access level>
|
41
|
-
cfg.gsub!(/key (\S+)
|
42
|
-
cfg.gsub!(/
|
43
|
-
cfg.gsub!(/
|
44
|
-
cfg.gsub!(/
|
45
|
-
cfg.gsub!(/
|
41
|
+
cfg.gsub!(/key (\S+)\s?$/, 'key <secret removed>')
|
42
|
+
cfg.gsub!(/vrrp-passphrase (\S+)\s?$/, 'vrrp-passphrase <secret removed>')
|
43
|
+
cfg.gsub!(/wpa-passphrase (\S+)\s?$/, 'wpa-passphrase <secret removed>')
|
44
|
+
cfg.gsub!(/bkup-passwords (\S+)\s?$/, 'bkup-passwords <secret removed>')
|
45
|
+
cfg.gsub!(/ap-console-password (\S+)\s?$/, 'ap-console-password <secret removed>')
|
46
|
+
cfg.gsub!(/virtual-controller-key (\S+)\s?$/, 'virtual-controller-key <secret removed>')
|
46
47
|
cfg
|
47
48
|
end
|
48
49
|
|
@@ -52,22 +53,26 @@ class AOSW < Oxidized::Model
|
|
52
53
|
end
|
53
54
|
|
54
55
|
cmd 'show inventory' do |cfg|
|
55
|
-
|
56
|
+
# Don't show for unsupported devices (IAP and MAS)
|
57
|
+
cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
|
56
58
|
rstrip_cfg clean cfg
|
57
59
|
end
|
58
60
|
|
59
61
|
cmd 'show slots' do |cfg|
|
60
|
-
|
62
|
+
# Don't show for unsupported devices (IAP and MAS)
|
63
|
+
cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
|
61
64
|
rstrip_cfg comment cfg
|
62
65
|
end
|
63
66
|
|
64
67
|
cmd 'show license' do |cfg|
|
65
|
-
|
68
|
+
# Don't show for unsupported devices (IAP and MAS)
|
69
|
+
cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
|
66
70
|
rstrip_cfg comment cfg
|
67
71
|
end
|
68
72
|
|
69
73
|
cmd 'show license passphrase' do |cfg|
|
70
|
-
|
74
|
+
# Don't show for unsupported devices (IAP and MAS)
|
75
|
+
cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/
|
71
76
|
rstrip_cfg comment cfg
|
72
77
|
end
|
73
78
|
|
@@ -117,7 +122,7 @@ class AOSW < Oxidized::Model
|
|
117
122
|
next if line =~ /Output \d Config/i
|
118
123
|
next if line =~ /(Tachometers|Temperatures|Voltages)/
|
119
124
|
next if line =~ /((Card|CPU) Temperature|Chassis Fan|VMON1[0-9])/
|
120
|
-
next if line =~ /[0-9]
|
125
|
+
next if line =~ /[0-9.]{1,6}\s+(RPMS?|m?V|C|W)/i
|
121
126
|
|
122
127
|
out << line.strip
|
123
128
|
end
|
@@ -37,7 +37,7 @@ class AricentISS < Oxidized::Model
|
|
37
37
|
cmd 'show system information' do |cfg|
|
38
38
|
cfg.sub! /^Device Up Time.*\n/, ''
|
39
39
|
cfg.delete! "\r"
|
40
|
-
comment(cfg).
|
40
|
+
comment(cfg).rstrip
|
41
41
|
end
|
42
42
|
|
43
43
|
cmd 'show running-config' do |cfg|
|
@@ -53,6 +53,6 @@ class AricentISS < Oxidized::Model
|
|
53
53
|
end
|
54
54
|
|
55
55
|
l
|
56
|
-
end.join.
|
56
|
+
end.join.rstrip
|
57
57
|
end
|
58
58
|
end
|
data/lib/oxidized/model/asa.rb
CHANGED
@@ -16,8 +16,7 @@ class ASA < Oxidized::Model
|
|
16
16
|
cfg.gsub! /^passwd (\S+) (.*)/, 'passwd <secret hidden> \2'
|
17
17
|
cfg.gsub! /username (\S+) password (\S+) (.*)/, 'username \1 password <secret hidden> \3'
|
18
18
|
cfg.gsub! /(ikev[12] ((remote|local)-authentication )?pre-shared-key( hex)?) (\S+)/, '\1 <secret hidden>'
|
19
|
-
cfg.gsub! /^(aaa-server
|
20
|
-
cfg.gsub! /^(aaa-server \S+ \(\S+\) host[^\n]*\n(\s+[^\n]+\n)*\s+key) \S+$/mi, '\1 <secret hidden>'
|
19
|
+
cfg.gsub! /^(aaa-server \S+(?: \(\S+\))? host \S+\n(?: [^\n]+\n)* +key) \S+$/mi, '\1 <secret hidden>'
|
21
20
|
cfg.gsub! /ldap-login-password (\S+)/, 'ldap-login-password <secret hidden>'
|
22
21
|
cfg.gsub! /^snmp-server host (.*) community (\S+)/, 'snmp-server host \1 community <secret hidden>'
|
23
22
|
cfg.gsub! /^(failover key) .+/, '\1 <secret hidden>'
|
@@ -97,7 +96,8 @@ class ASA < Oxidized::Model
|
|
97
96
|
contexts = systemcfg.scan(/^context (\S+)$/)
|
98
97
|
files = systemcfg.scan(/config-url (\S+)$/)
|
99
98
|
contexts.each_with_index do |cont, i|
|
100
|
-
allcfg = allcfg + "\n\n----------========== [ CONTEXT " + cont.join(" ") +
|
99
|
+
allcfg = allcfg + "\n\n----------========== [ CONTEXT " + cont.join(" ") +
|
100
|
+
" FILE " + files[i].join(" ") + " ] ==========----------\n\n"
|
101
101
|
cmd "more " + files[i].join(" ") do |cfgcontext|
|
102
102
|
allcfg = allcfg + "\n\n" + cfgcontext
|
103
103
|
end
|
@@ -61,25 +61,28 @@ class AWPlus < Oxidized::Model
|
|
61
61
|
cfg
|
62
62
|
end
|
63
63
|
|
64
|
-
# Config required for telnet to detect username prompt
|
64
|
+
# Config required for telnet to detect username & password prompt.
|
65
65
|
cfg :telnet do
|
66
66
|
username /login:\s/
|
67
|
+
password /^Password:\s/
|
67
68
|
end
|
68
69
|
|
69
|
-
#
|
70
|
+
# Config required for ssh to specify newline characters.
|
70
71
|
cfg :telnet, :ssh do
|
72
|
+
newline "\r\n"
|
73
|
+
|
71
74
|
post_login do
|
72
|
-
if vars
|
73
|
-
|
74
|
-
|
75
|
-
cmd
|
76
|
-
|
77
|
-
cmd 'enable' # Required for Priv-Exec users without enable PW to be put into "enable mode".
|
75
|
+
if vars(:enable) == true
|
76
|
+
cmd "enable"
|
77
|
+
elsif vars(:enable)
|
78
|
+
cmd "enable", /^[pP]assword:/
|
79
|
+
cmd vars(:enable)
|
78
80
|
end
|
79
|
-
#
|
81
|
+
# cmd 'terminal length 0' # set so the entire config is output without intervention.
|
80
82
|
end
|
83
|
+
|
81
84
|
pre_logout do
|
82
|
-
#
|
85
|
+
# cmd 'terminal no length' # sets term length back to default on exit.
|
83
86
|
send "exit\r\n"
|
84
87
|
end
|
85
88
|
end
|
@@ -32,7 +32,8 @@ class EdgeCOS < Oxidized::Model
|
|
32
32
|
cmd 'show system' do |cfg|
|
33
33
|
cfg.gsub! /^.*\sUp Time\s*:.*\n/i, ''
|
34
34
|
cfg.gsub! /(\sTemperature \d*:)\s*\d+ degrees/, '\\1 <temperature values hidden>'
|
35
|
-
cfg.gsub! /^!?\s*Fan \d+ speed:\s+\d+ rpm\s+Fan \d+ speed:\s+\d+ rpm\s+Fan \d+ speed:\s+\d+ rpm$/,
|
35
|
+
cfg.gsub! /^!?\s*Fan \d+ speed:\s+\d+ rpm\s+Fan \d+ speed:\s+\d+ rpm\s+Fan \d+ speed:\s+\d+ rpm$/,
|
36
|
+
'<fan speeds hidden>'
|
36
37
|
comment cfg
|
37
38
|
end
|
38
39
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Edgeos < Oxidized::Model
|
2
2
|
using Refinements
|
3
3
|
|
4
|
-
# EdgeOS #
|
4
|
+
# Ubiquiti EdgeOS #
|
5
5
|
|
6
6
|
prompt /@.*?:~\$\s/
|
7
7
|
|
@@ -10,11 +10,12 @@ class Edgeos < Oxidized::Model
|
|
10
10
|
end
|
11
11
|
|
12
12
|
cmd :secret do |cfg|
|
13
|
-
cfg.gsub!
|
14
|
-
cfg.gsub!
|
15
|
-
cfg.gsub!
|
16
|
-
cfg.gsub!
|
17
|
-
cfg.gsub!
|
13
|
+
cfg.gsub!(/(encrypted-password) \S+/, '\1 <secret removed>')
|
14
|
+
cfg.gsub!(/(plaintext-password) \S+/, '\1 <secret removed>')
|
15
|
+
cfg.gsub!(/(password) \S+/, '\1 <secret removed>')
|
16
|
+
cfg.gsub!(/(pre-shared-secret) \S+/, '\1 <secret removed>')
|
17
|
+
cfg.gsub!(/(community) \S+ {/, '\1 <hidden> {')
|
18
|
+
cfg.gsub!(/(commit-archive location) \S+/, '\1 <secret removed>')
|
18
19
|
cfg
|
19
20
|
end
|
20
21
|
|
@@ -8,7 +8,9 @@ class EdgeSwitch < Oxidized::Model
|
|
8
8
|
prompt /\(.*\)\s[#>]/
|
9
9
|
|
10
10
|
cmd 'show running-config' do |cfg|
|
11
|
-
cfg.each_line.to_a[2..-2].reject
|
11
|
+
cfg.each_line.to_a[2..-2].reject do |line|
|
12
|
+
line.match(/System Up Time.*/) || line.match(/Current SNTP Synchronized Time.*/)
|
13
|
+
end.join
|
12
14
|
end
|
13
15
|
|
14
16
|
cfg :telnet do
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class EFOS < Oxidized::Model
|
2
|
+
using Refinements
|
3
|
+
|
4
|
+
# Enhanced Fabric OS - Broadcom
|
5
|
+
comment '! '
|
6
|
+
prompt /^([\w.@()-]+[#>]\s?)$/
|
7
|
+
|
8
|
+
cmd :all do |cfg|
|
9
|
+
# Remove the echo of the entered command and the prompt after it
|
10
|
+
cfg.cut_both
|
11
|
+
end
|
12
|
+
|
13
|
+
cmd 'show bootvar' do |cfg|
|
14
|
+
comment cfg
|
15
|
+
end
|
16
|
+
|
17
|
+
cmd 'show fiber-ports optical-transceiver-info all' do |cfg|
|
18
|
+
comment cfg
|
19
|
+
end
|
20
|
+
|
21
|
+
cmd 'show running-config' do |cfg|
|
22
|
+
cfg.each_line
|
23
|
+
.reject { |line| line.match(/System Up Time/) }
|
24
|
+
.reject { |line| line.match(/Current System Time:/) }
|
25
|
+
.reject { |line| line.match(/Current SNTP Synchronized Time:/) }
|
26
|
+
.join
|
27
|
+
end
|
28
|
+
|
29
|
+
cfg :telnet, :ssh do
|
30
|
+
post_login do
|
31
|
+
if vars(:enable) == true
|
32
|
+
cmd 'enable'
|
33
|
+
elsif vars(:enable)
|
34
|
+
cmd 'enable', /^[pP]assword:/
|
35
|
+
cmd vars(:enable)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
post_login 'terminal length 0'
|
39
|
+
pre_logout 'logout'
|
40
|
+
end
|
41
|
+
end
|
data/lib/oxidized/model/eltex.rb
CHANGED
@@ -16,7 +16,7 @@ class Eltex < Oxidized::Model
|
|
16
16
|
cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>'
|
17
17
|
cfg.gsub! /^(\s+(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
|
18
18
|
cfg.gsub! /^(tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
|
19
|
-
cfg.gsub! /^((tacacs|radius) server [^\n]+\n(
|
19
|
+
cfg.gsub! /^((tacacs|radius) server [^\n]+\n( +[^\n]+\n)*\s+key) [^\n]+$/m, '\1 <secret hidden>'
|
20
20
|
cfg.gsub! /username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
|
21
21
|
cfg.gsub! /^username \S+ password \d \S+/, '<secret hidden>'
|
22
22
|
cfg.gsub! /^enable password \d \S+/, '<secret hidden>'
|
@@ -8,7 +8,7 @@ class FabricOS < Oxidized::Model
|
|
8
8
|
comment '# '
|
9
9
|
|
10
10
|
cmd 'chassisShow' do |cfg|
|
11
|
-
comment cfg.each_line.reject { |line| line.match(/Time Awake:/) || line.match(/Power Usage \(Watts\):/) || line.match(/Power Usage:/) || line.match(/Time Alive:/) || line.match(/Update:/) }.join
|
11
|
+
comment cfg.each_line.reject { |line| line.match(/Time Awake:/) || line.match(/Power Usage \(Watts\):/) || line.match(/Power Usage:/) || line.match(/Time Alive:/) || line.match(/Update:/) || line.match(/PS Voltage input:/) }.join
|
12
12
|
end
|
13
13
|
|
14
14
|
cmd 'configShow -all' do |cfg|
|
@@ -19,7 +19,9 @@ class FastIron < Oxidized::Model
|
|
19
19
|
lines.each_with_index do |line, _i|
|
20
20
|
comments << "Version: #{Regexp.last_match(1)}" if line =~ /^\s+SW: Version (.*)$/
|
21
21
|
|
22
|
-
|
22
|
+
if line =~ /^\s+Compressed Boot-Monitor Image size = \d+, Version:(.*)$/
|
23
|
+
comments << "Boot-Monitor Version: #{Regexp.last_match(1)}"
|
24
|
+
end
|
23
25
|
|
24
26
|
comments << "Serial: #{Regexp.last_match(1)}" if line =~ /^\s+Serial #:(.*)$/
|
25
27
|
end
|
@@ -3,12 +3,21 @@ class FireLinuxOS < Oxidized::Model
|
|
3
3
|
|
4
4
|
# Fire Linux OS is what the new FTD (FirePOWER) series devices from Cisco run. At the backend, it's mostly identical to ASA's.
|
5
5
|
|
6
|
-
prompt /^[#>]\(?.+\)
|
7
|
-
comment
|
6
|
+
prompt /^[#>]\(?.+\)? ?$/
|
7
|
+
comment '! '
|
8
|
+
|
9
|
+
expect /^Syntax error: .*\n.*$/ do |data, re|
|
10
|
+
# The firepower does not remove the entered command, so
|
11
|
+
# Send CTRL-U and \n for a fresh prompt
|
12
|
+
send "\x15\n"
|
13
|
+
data.sub re, ''
|
14
|
+
end
|
8
15
|
|
9
16
|
cmd :all do |cfg|
|
10
17
|
cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
|
11
|
-
|
18
|
+
# Ged rid of ANSI escape codes
|
19
|
+
cfg.gsub! /\e\[[0-?]*[ -\/]*[@-~]\r?/, ''
|
20
|
+
cfg.cut_both
|
12
21
|
end
|
13
22
|
|
14
23
|
cmd :secret do |cfg|
|
@@ -96,7 +96,8 @@ class FortiOS < Oxidized::Model
|
|
96
96
|
|
97
97
|
commandlist.each do |fullcmd|
|
98
98
|
fullcfg = cmd(fullcmd)
|
99
|
-
|
99
|
+
# Don't show for unsupported devices (e.g. FortiAnalyzer, FortiManager, FortiMail)
|
100
|
+
next if fullcfg.lines[1..3].join =~ /(Parsing error at|command parse error)/
|
100
101
|
|
101
102
|
fullcfg.gsub! /(set comments "Error \(No order (found )?for (account )?ID \d+\) on).*/, '\\1 <stripped>"'
|
102
103
|
|
@@ -26,7 +26,7 @@ class GaiaOS < Oxidized::Model
|
|
26
26
|
# check for vsx / multiple context
|
27
27
|
cmd 'show vsx' do |cfg|
|
28
28
|
@is_vsx = cfg.include? 'VSX Enabled'
|
29
|
-
|
29
|
+
logger.debug cfg
|
30
30
|
end
|
31
31
|
|
32
32
|
cmd 'show asset all' do |cfg|
|
@@ -46,7 +46,7 @@ class GaiaOS < Oxidized::Model
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def single_context
|
49
|
-
|
49
|
+
logger.debug 'Single context tasks'
|
50
50
|
cmd 'show configuration' do |cfg|
|
51
51
|
cfg.gsub! /^# Exported by \S+ on .*/, '# '
|
52
52
|
cfg
|
@@ -54,7 +54,7 @@ class GaiaOS < Oxidized::Model
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def multiple_context
|
57
|
-
|
57
|
+
logger.debug 'Multi context tasks'
|
58
58
|
cmd 'show virtual-system all' do |systems|
|
59
59
|
vs_items = systems.scan(/^(?<VSID>\d+)\s+(?<VSNAME>.*[^\s])/)
|
60
60
|
allcfg = ''
|
@@ -62,7 +62,7 @@ class GaiaOS < Oxidized::Model
|
|
62
62
|
allcfg += "\n\n\n#--------======== [ VS #{item[0]} - #{item[1]} ] ========--------\n\n"
|
63
63
|
allcfg += "set virtual-system #{item[0]}\n\n"
|
64
64
|
cmd "set virtual-system #{item[0]}" do |vs|
|
65
|
-
|
65
|
+
logger.debug vs
|
66
66
|
cmd 'show configuration' do |vscfg|
|
67
67
|
vscfg.gsub! /^# Exported by \S+ on .*/, '# '
|
68
68
|
allcfg += vscfg
|
data/lib/oxidized/model/ios.rb
CHANGED
@@ -69,17 +69,25 @@ class IOS < Oxidized::Model
|
|
69
69
|
|
70
70
|
comments << "Image:#{slave} Compiled: #{Regexp.last_match(1)}" if line =~ /^Compiled (.*)$/
|
71
71
|
|
72
|
-
|
72
|
+
if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
|
73
|
+
comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}"
|
74
|
+
end
|
73
75
|
|
74
|
-
|
76
|
+
if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
|
77
|
+
comments << "ROM Bootstrap: #{Regexp.last_match(3)}"
|
78
|
+
end
|
75
79
|
|
76
80
|
comments << "BOOTFLASH: #{Regexp.last_match(1)}" if line =~ /^BOOTFLASH: .*(Version.*)$/
|
77
81
|
|
78
82
|
comments << "Memory: nvram #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/
|
79
83
|
|
80
|
-
|
84
|
+
if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
|
85
|
+
comments << "Memory: flash #{Regexp.last_match(1)}"
|
86
|
+
end
|
81
87
|
|
82
|
-
|
88
|
+
if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i
|
89
|
+
comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}"
|
90
|
+
end
|
83
91
|
|
84
92
|
if line =~ /(\S+(?:\sseries)?)\s+(?:\(([\S ]+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
|
85
93
|
sproc = Regexp.last_match(1)
|
@@ -120,7 +128,9 @@ class IOS < Oxidized::Model
|
|
120
128
|
cmd cmd_line do |cfg|
|
121
129
|
cfg = cfg.each_line.to_a[3..-1]
|
122
130
|
cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
|
123
|
-
cfg = cfg.each_line.reject
|
131
|
+
cfg = cfg.each_line.reject do |line|
|
132
|
+
line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/
|
133
|
+
end.join
|
124
134
|
cfg.gsub! /^Current configuration : [^\n]*\n/, ''
|
125
135
|
cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
|
126
136
|
(?: [^\n]*\n*)*
|