oxidized 0.32.1 → 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 +45 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
- data/.github/workflows/publishdocker.yml +35 -16
- data/.github/workflows/ruby.yml +4 -2
- data/.gitignore +2 -0
- data/.rubocop.yml +29 -8
- data/.rubocop_todo.yml +1 -60
- data/CHANGELOG.md +103 -2
- data/CONTRIBUTING.md +20 -10
- data/Dockerfile +37 -64
- data/README.md +47 -141
- data/Rakefile +9 -11
- data/docs/Configuration.md +236 -27
- data/docs/DeviceSimulation.md +19 -7
- data/docs/Docker.md +245 -0
- data/docs/Issues.md +27 -1
- data/docs/Model-Notes/EatonNetwork.md +18 -0
- data/docs/Model-Notes/HPEAruba.md +3 -2
- data/docs/ModelUnitTests.md +35 -25
- data/docs/Outputs.md +83 -2
- data/docs/Release.md +34 -24
- data/docs/Supported-OS-Types.md +7 -0
- data/docs/Troubleshooting.md +4 -13
- data/extra/device2yaml.rb +24 -9
- data/extra/rest_client.rb +3 -2
- data/extra/syslog.rb +8 -3
- data/lib/oxidized/cli.rb +7 -3
- data/lib/oxidized/config/vars.rb +22 -14
- data/lib/oxidized/config.rb +3 -2
- data/lib/oxidized/core.rb +30 -8
- 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 +6 -6
- 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 +9 -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/eatonnetwork.rb +65 -0
- 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 +5 -4
- data/lib/oxidized/model/gaiaos.rb +4 -4
- data/lib/oxidized/model/ingate.rb +47 -0
- data/lib/oxidized/model/ios.rb +16 -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 +8 -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/powerconnect.rb +31 -10
- 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/srosmd.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 +144 -0
- 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 +148 -41
- data/lib/oxidized/output/gitcrypt.rb +18 -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 +6 -4
- data/lib/oxidized/worker.rb +13 -13
- data/lib/oxidized.rb +3 -24
- data/lib/refinements.rb +2 -0
- data/oxidized.gemspec +10 -8
- metadata +74 -41
- data/examples/podman-compose/Makefile +0 -103
- data/examples/podman-compose/README.md +0 -94
- data/examples/podman-compose/docker-compose.yml +0 -30
- data/examples/podman-compose/gitserver/.gitignore +0 -1
- data/examples/podman-compose/gitserver/Dockerfile +0 -14
- data/examples/podman-compose/model-simulation/Dockerfile-model +0 -13
- data/examples/podman-compose/model-simulation/asternos.sh +0 -36
- data/examples/podman-compose/oxidized-config/.gitignore +0 -10
- data/examples/podman-compose/oxidized-config/config +0 -46
- data/examples/podman-compose/oxidized-config/config_csv-file +0 -46
- data/examples/podman-compose/oxidized-config/config_csv-gitserver +0 -56
- data/examples/podman-compose/oxidized-config/router.db +0 -1
- data/examples/podman-compose/oxidized-ssh/.gitignore +0 -1
- data/examples/podman-compose/oxidized-ssh/README.md +0 -14
@@ -0,0 +1,65 @@
|
|
1
|
+
class EatonNetwork < Oxidized::Model
|
2
|
+
using Refinements
|
3
|
+
# Eaton Gigabit Network Card M3
|
4
|
+
|
5
|
+
# -p option is a passphrase used to encrypted parts of the config data, the
|
6
|
+
# encrypted data is nondeterministic and changes with each run. Use auth
|
7
|
+
# password as the passphrase.
|
8
|
+
#
|
9
|
+
# See docs/Model-Notes/EatonNetwork.md for more info
|
10
|
+
post do
|
11
|
+
# Get config in post to allow passing auth password to cmd.
|
12
|
+
cfg = cmd "save_configuration -p #{@node.auth[:password]}"
|
13
|
+
cfg
|
14
|
+
end
|
15
|
+
|
16
|
+
cmd :all do |cfg|
|
17
|
+
# `save_configuration` echos the command back, outputs date time info, with
|
18
|
+
# last line is the prompt again.
|
19
|
+
json_str = cfg.each_line.select { |line| line.match /^\{/ }.join
|
20
|
+
json = JSON.parse(json_str)
|
21
|
+
|
22
|
+
json['features']['userAndSessionManagement']['data']['settings']['all']['1.0']['local']['1.0']['predefinedAccounts'].each do |n|
|
23
|
+
n.delete('attemptLogin')
|
24
|
+
n['password'].delete('history')
|
25
|
+
end
|
26
|
+
json['features']['userAndSessionManagement']['data']['settings']['all']['1.0']['local']['1.0']['createdAccounts'].each do |n|
|
27
|
+
n.delete('attemptLogin')
|
28
|
+
n['password'].delete('history')
|
29
|
+
end
|
30
|
+
|
31
|
+
cfg = JSON.pretty_generate(json)
|
32
|
+
cfg
|
33
|
+
end
|
34
|
+
|
35
|
+
cmd :secret do |cfg|
|
36
|
+
# Re-parse json to remove secrets by json path
|
37
|
+
json = JSON.parse(cfg)
|
38
|
+
|
39
|
+
json.delete('passphrase')
|
40
|
+
json['features']['rms']['data']['settings'].delete('proxyUsername')
|
41
|
+
json['features']['rms']['data']['settings'].delete('proxyPassword')
|
42
|
+
json['features']['rms']['data']['settings'].delete('username')
|
43
|
+
json['features']['rms']['data']['settings'].delete('password')
|
44
|
+
json['features']['rms']['data']['settings'].delete('defaultPassword')
|
45
|
+
|
46
|
+
json['features']['smtp']['data']['dmeData'].delete('password')
|
47
|
+
|
48
|
+
json['features']['snmp']['data']['dmeData']['v3']['users'].each do |n|
|
49
|
+
n['auth'].delete('password')
|
50
|
+
n['priv'].delete('password')
|
51
|
+
end
|
52
|
+
|
53
|
+
json['features']['userAndSessionManagement']['data']['settings']['all']['1.0']['ldap']['1.0']['settings']['connectivity']['bind'].delete('password')
|
54
|
+
json['features']['userAndSessionManagement']['data']['settings']['all']['1.0']['radius']['1.0']['settings']['connectivity']['primaryServer'].delete('secret')
|
55
|
+
json['features']['userAndSessionManagement']['data']['settings']['all']['1.0']['radius']['1.0']['settings']['connectivity']['secondaryServer'].delete('secret')
|
56
|
+
|
57
|
+
cfg = JSON.pretty_generate(json)
|
58
|
+
cfg
|
59
|
+
end
|
60
|
+
|
61
|
+
cfg :ssh do
|
62
|
+
exec true
|
63
|
+
pre_logout 'logout'
|
64
|
+
end
|
65
|
+
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|
|
@@ -3,7 +3,7 @@ class FortiOS < Oxidized::Model
|
|
3
3
|
|
4
4
|
comment '# '
|
5
5
|
|
6
|
-
prompt /^([-\w.~]+(\s[(\w\-.)]+)?~?\s?[#>$]\s?)$/
|
6
|
+
prompt /^(\(\w\) )?([-\w.~]+(\s[(\w\-.)]+)?~?\s?[#>$]\s?)$/
|
7
7
|
|
8
8
|
# When a post-login-banner is enabled, you have to press "a" to log in
|
9
9
|
expect /^\(Press\s'a'\sto\saccept\):/ do |data, re|
|
@@ -39,11 +39,11 @@ class FortiOS < Oxidized::Model
|
|
39
39
|
|
40
40
|
cmd 'get system status' do |cfg|
|
41
41
|
@vdom_enabled = cfg.match /Virtual domain configuration: (enable|multiple)/
|
42
|
-
cfg.gsub! /(System time:)
|
42
|
+
cfg.gsub! /(System time:).*/i, '\\1 <stripped>'
|
43
43
|
cfg.gsub! /(Cluster (?:uptime|state change time):).*/, '\\1 <stripped>'
|
44
44
|
cfg.gsub! /(Current Time\s+:\s+)(.*)/, '\1<stripped>'
|
45
45
|
cfg.gsub! /(Uptime:\s+)(.*)/, '\1<stripped>\3'
|
46
|
-
cfg.gsub! /(Last reboot:\s+)(.*)
|
46
|
+
cfg.gsub! /(Last reboot:\s+)(.*)/i, '\1<stripped>\3'
|
47
47
|
cfg.gsub! /(Disk Usage\s+:\s+)(.*)/, '\1<stripped>'
|
48
48
|
cfg.gsub! /(^\S+ (?:disk|DB):\s+)(.*)/, '\1<stripped>\3'
|
49
49
|
cfg.gsub! /(VM Registration:\s+)(.*)/, '\1<stripped>\3'
|
@@ -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
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Ingate < Oxidized::Model
|
2
|
+
using Refinements
|
3
|
+
|
4
|
+
cfg_cb = lambda do
|
5
|
+
cfg = @m.post(
|
6
|
+
@main_url,
|
7
|
+
{
|
8
|
+
'page' => 'save',
|
9
|
+
'db.webgui.testmode/1/timelimit' => '30',
|
10
|
+
'db.webgui.testmode/__KEEP_ROWS_ALIVE' => '1',
|
11
|
+
'db.webgui.pending_apply/1/verbosity' => 'always',
|
12
|
+
'db.webgui.pending_apply/__KEEP_ROWS_ALIVE' => '1',
|
13
|
+
'action.admin.download_config_cli' => 'Save config to CLI file',
|
14
|
+
'upload.config_file;filename=type' => 'application/octet-stream',
|
15
|
+
'upload.clicmd_file;filename;type' => 'application/octet-stream',
|
16
|
+
'security' => '',
|
17
|
+
'got_complete_form' => 'yes'
|
18
|
+
},
|
19
|
+
'Accept' => 'application/x-config-database'
|
20
|
+
)
|
21
|
+
cfg.body
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd cfg_cb do |cfg|
|
25
|
+
cfg.gsub! /^# Timestamp:.*$/, ''
|
26
|
+
cfg
|
27
|
+
end
|
28
|
+
|
29
|
+
cfg :http do
|
30
|
+
@secure = true
|
31
|
+
@main_page = "/"
|
32
|
+
define_singleton_method :login do
|
33
|
+
@main_url = URI::HTTP.build host: @node.ip, path: @main_page
|
34
|
+
@m.post(
|
35
|
+
@main_url,
|
36
|
+
{
|
37
|
+
'security_user' => @node.auth[:username],
|
38
|
+
'security_password' => @node.auth[:password],
|
39
|
+
'page' => 'login',
|
40
|
+
'goal' => 'save',
|
41
|
+
'got_complete_form' => 'yes',
|
42
|
+
'security' => ''
|
43
|
+
}
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/oxidized/model/ios.rb
CHANGED
@@ -50,6 +50,7 @@ class IOS < Oxidized::Model
|
|
50
50
|
cfg.gsub! /^( +client \S+ server-key \d) (.*)$/, '\\1 <secret hidden>'
|
51
51
|
cfg.gsub! /^( +domain-password) \S+ ?(.*)/, '\\1 <secret hidden> \\2'
|
52
52
|
cfg.gsub! /^( +pre-shared-key).*/, '\\1 <configuration removed>'
|
53
|
+
cfg.gsub! /^(.*server-key(?: \d)?) \S+/, '\\1 <secret hidden>'
|
53
54
|
cfg
|
54
55
|
end
|
55
56
|
|
@@ -68,17 +69,25 @@ class IOS < Oxidized::Model
|
|
68
69
|
|
69
70
|
comments << "Image:#{slave} Compiled: #{Regexp.last_match(1)}" if line =~ /^Compiled (.*)$/
|
70
71
|
|
71
|
-
|
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
|
72
75
|
|
73
|
-
|
76
|
+
if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
|
77
|
+
comments << "ROM Bootstrap: #{Regexp.last_match(3)}"
|
78
|
+
end
|
74
79
|
|
75
80
|
comments << "BOOTFLASH: #{Regexp.last_match(1)}" if line =~ /^BOOTFLASH: .*(Version.*)$/
|
76
81
|
|
77
82
|
comments << "Memory: nvram #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/
|
78
83
|
|
79
|
-
|
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
|
80
87
|
|
81
|
-
|
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
|
82
91
|
|
83
92
|
if line =~ /(\S+(?:\sseries)?)\s+(?:\(([\S ]+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
|
84
93
|
sproc = Regexp.last_match(1)
|
@@ -119,7 +128,9 @@ class IOS < Oxidized::Model
|
|
119
128
|
cmd cmd_line do |cfg|
|
120
129
|
cfg = cfg.each_line.to_a[3..-1]
|
121
130
|
cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
|
122
|
-
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
|
123
134
|
cfg.gsub! /^Current configuration : [^\n]*\n/, ''
|
124
135
|
cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
|
125
136
|
(?: [^\n]*\n*)*
|
@@ -37,7 +37,7 @@ class IronWare < Oxidized::Model
|
|
37
37
|
cfg.gsub! /Fan \d* - STATUS: OK \D*\d*./, '' # Fix for ADX Fan speed reporting
|
38
38
|
cfg.gsub! /\d* deg C/, '' # Fix for ADX temperature reporting
|
39
39
|
cfg.gsub! /([\[]*)1([\]]*)<->([\[]*)2([\]]*)(<->([\[]*)3([\]]*))*/, ''
|
40
|
-
cfg.gsub! /\d
|
40
|
+
cfg.gsub! /\d+\.\d deg-C/, 'XX.X deg-C'
|
41
41
|
if cfg.include? "TEMPERATURE"
|
42
42
|
sc = StringScanner.new cfg
|
43
43
|
out = ''
|
data/lib/oxidized/model/junos.rb
CHANGED
@@ -32,6 +32,10 @@ class JunOS < Oxidized::Model
|
|
32
32
|
out << cmd('show chassis fabric reachability') { |cfg| comment cfg }
|
33
33
|
when /^(ex22|ex3[34]|ex4|ex8|qfx)/
|
34
34
|
out << cmd('show virtual-chassis') { |cfg| comment cfg }
|
35
|
+
when /^srx/
|
36
|
+
out << cmd('show chassis cluster status') do |cfg|
|
37
|
+
cfg.lines.count <= 1 && cfg.include?("error:") ? '' : comment(cfg)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
out
|
37
41
|
end
|
@@ -8,7 +8,7 @@ class LinksysSRW < Oxidized::Model
|
|
8
8
|
# Graphical login screen
|
9
9
|
# Just login to get to Main Menu
|
10
10
|
expect /Login Screen/ do
|
11
|
-
|
11
|
+
logger.debug "#{self.class.name}: Login Screen"
|
12
12
|
# This is to ensure the whole thing have rendered before we send stuff
|
13
13
|
sleep 0.2
|
14
14
|
send 0x18.chr # CAN Cancel
|
@@ -21,14 +21,14 @@ class LinksysSRW < Oxidized::Model
|
|
21
21
|
|
22
22
|
# Main menu, escape into Pre-cli-shell
|
23
23
|
expect /Switch Main Menu/ do
|
24
|
-
|
24
|
+
logger.debug "#{self.class.name}: Switch menu"
|
25
25
|
send 0x1a.chr # SUB Substitite ^z
|
26
26
|
''
|
27
27
|
end
|
28
28
|
|
29
29
|
# Pre-cli-shell, start lcli which is ios-ish
|
30
30
|
expect />/ do
|
31
|
-
|
31
|
+
logger.debug "#{self.class.name}: >"
|
32
32
|
send "lcli\r"
|
33
33
|
''
|
34
34
|
end
|
@@ -1,21 +1,27 @@
|
|
1
1
|
class MLNXOS < Oxidized::Model
|
2
2
|
using Refinements
|
3
3
|
|
4
|
-
prompt
|
4
|
+
prompt /^\r?(\e.+\e>\r)?\S* \[\S+: (master|standby)\] [#>] $/
|
5
5
|
comment '## '
|
6
6
|
|
7
7
|
# Pager Handling
|
8
|
-
|
8
|
+
# "Normal" pager: "lines 183-204 "
|
9
|
+
# Last pager: "lines 256-269/269 (END) "
|
10
|
+
expect /\e\[7mlines \d+-\d+( |\/\d+ \(END\) )/ do |data, re|
|
9
11
|
send ' '
|
10
12
|
data.sub re, ''
|
11
13
|
end
|
12
14
|
|
15
|
+
# Remove ANSI escape codes
|
16
|
+
expect /\e\[[0-?]*[ -\/]*[@-~]\r?/ do |data, re|
|
17
|
+
data.sub re, ''
|
18
|
+
end
|
19
|
+
|
13
20
|
cmd :all do |cfg|
|
14
|
-
cfg.gsub!
|
15
|
-
cfg.gsub!
|
16
|
-
cfg.gsub!
|
17
|
-
cfg.gsub!
|
18
|
-
cfg.gsub! /\s/, '' # Linebreak Handling
|
21
|
+
cfg.gsub! "\e[m", '' # Remove reset formating
|
22
|
+
cfg.gsub! "\e[K", '' # Remove erase in line
|
23
|
+
cfg.gsub! /.\x08/, '' # Remove Backspace char
|
24
|
+
cfg.gsub! "\r", '' # Remove Cariage Return
|
19
25
|
cfg.gsub! /^CPU load averages:\s.+/, '' # Omit constantly changing CPU info
|
20
26
|
cfg.gsub! /^System memory:\s.+/, '' # Omit constantly changing memory info
|
21
27
|
cfg.gsub! /^Uptime:\s.+/, '' # Omit constantly changing uptime info
|
@@ -45,6 +51,7 @@ class MLNXOS < Oxidized::Model
|
|
45
51
|
|
46
52
|
cfg :ssh do
|
47
53
|
password /^Password:\s*/
|
54
|
+
post_login 'no cli session paging enable'
|
48
55
|
pre_logout "\nexit"
|
49
56
|
end
|
50
57
|
end
|
data/lib/oxidized/model/model.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative 'outputs'
|
|
3
3
|
|
4
4
|
module Oxidized
|
5
5
|
class Model
|
6
|
+
include SemanticLogger::Loggable
|
6
7
|
using Refinements
|
7
8
|
|
8
9
|
include Oxidized::Config::Vars
|
@@ -56,7 +57,7 @@ module Oxidized
|
|
56
57
|
else
|
57
58
|
process_args_block(@cmd[:cmd], args, [cmd_arg, block])
|
58
59
|
end
|
59
|
-
|
60
|
+
logger.debug "Added #{cmd_arg} to the commands list"
|
60
61
|
end
|
61
62
|
|
62
63
|
def cmds
|
@@ -118,7 +119,7 @@ module Oxidized
|
|
118
119
|
attr_accessor :input, :node
|
119
120
|
|
120
121
|
def cmd(string, &block)
|
121
|
-
|
122
|
+
logger.debug "Executing #{string}"
|
122
123
|
out = @input.cmd(string)
|
123
124
|
return false unless out
|
124
125
|
|
@@ -165,7 +166,7 @@ module Oxidized
|
|
165
166
|
end
|
166
167
|
|
167
168
|
def get
|
168
|
-
|
169
|
+
logger.debug 'Collecting commands\' outputs'
|
169
170
|
outputs = Outputs.new
|
170
171
|
procs = self.class.procs
|
171
172
|
self.class.cmds[:cmd].each do |command, block|
|
@@ -4,6 +4,12 @@ class Netgear < Oxidized::Model
|
|
4
4
|
comment '!'
|
5
5
|
prompt /^\(?[\w \-+.]+\)? ?[#>] ?$/
|
6
6
|
|
7
|
+
# Handle pager for "show version" on old Netgear models: #2394
|
8
|
+
expect /^--More-- or \(q\)uit$/ do |data, re|
|
9
|
+
send ' '
|
10
|
+
data.sub re, ''
|
11
|
+
end
|
12
|
+
|
7
13
|
cmd :secret do |cfg|
|
8
14
|
cfg.gsub!(/password (\S+)/, 'password <hidden>')
|
9
15
|
cfg.gsub!(/encrypted (\S+)/, 'encrypted <hidden>')
|
@@ -53,5 +59,7 @@ class Netgear < Oxidized::Model
|
|
53
59
|
cmd 'show running-config' do |cfg|
|
54
60
|
cfg.gsub! /(System Up Time\s+).*/, '\\1 <removed>'
|
55
61
|
cfg.gsub! /(Current SNTP Synchronized Time:).*/, '\\1 <removed>'
|
62
|
+
cfg.gsub! /(Current System Time:).*/, '\\1 <removed>'
|
63
|
+
cfg
|
56
64
|
end
|
57
65
|
end
|
@@ -8,7 +8,8 @@ class NSXDfw < Oxidized::Model
|
|
8
8
|
domains.each do |domain|
|
9
9
|
domain_config[domain['id']] = {}
|
10
10
|
policies_data = cmd "/policy/api/v1/infra/domains/#{domain['id']}/security-policies/"
|
11
|
-
policies = JSON.parse(policies_data.encode('UTF-8',
|
11
|
+
policies = JSON.parse(policies_data.encode('UTF-8',
|
12
|
+
{ invalid: :replace, undef: :replace, replace: '?' }))["results"]
|
12
13
|
policies_config = {}
|
13
14
|
policies.each do |policy|
|
14
15
|
rules_data = cmd "/policy/api/v1/infra/domains/#{domain['id']}/security-policies/#{policy['id']}/rules"
|
@@ -8,7 +8,8 @@ class NSXFirewall < Oxidized::Model
|
|
8
8
|
edges.each do |edge|
|
9
9
|
firewall_config = cmd "/api/4.0/edges/#{edge['id']}/firewall/config"
|
10
10
|
json_config = {}
|
11
|
-
json_config["#{edge['id']} #{edge['name']}"] =
|
11
|
+
json_config["#{edge['id']} #{edge['name']}"] =
|
12
|
+
JSON.parse(firewall_config.encode('UTF-8', { invalid: :replace, undef: :replace, replace: '?' }))
|
12
13
|
data.push(json_config)
|
13
14
|
end
|
14
15
|
JSON.pretty_generate(data)
|
data/lib/oxidized/model/nxos.rb
CHANGED
@@ -22,11 +22,11 @@ class NXOS < Oxidized::Model
|
|
22
22
|
|
23
23
|
cmd 'show version' do |cfg|
|
24
24
|
cfg = filter cfg
|
25
|
-
cfg = cfg.each_line.take_while { |line| not line.match(/uptime/i) }
|
25
|
+
cfg = cfg.each_line.take_while { |line| not line.match(/uptime|bootflash:\s+\d+\skB|sysmgrcli_show_flash_size/i) }
|
26
26
|
comment cfg.join
|
27
27
|
end
|
28
28
|
|
29
|
-
cmd 'show inventory' do |cfg|
|
29
|
+
cmd 'show inventory all' do |cfg|
|
30
30
|
cfg = filter cfg
|
31
31
|
comment cfg
|
32
32
|
end
|
@@ -38,26 +38,26 @@ class OpenWrt < Oxidized::Model
|
|
38
38
|
filename = sysupgradefile.split('/')[-1]
|
39
39
|
cfg << comment("#### File: #{sysupgradefile} #####")
|
40
40
|
uciexport = cmd("uci export #{filename}")
|
41
|
-
|
41
|
+
logger.debug "Exporting uci config - #{filename}"
|
42
42
|
if vars(:remove_secret) && !(non_sensitive_files.include? filename)
|
43
|
-
|
43
|
+
logger.debug "Scrubbing uci config - #{filename}"
|
44
44
|
uciexport.gsub!(/^(\s+option\s+(password|key)\s+')[^']+'/, '\\1<secret hidden>\'')
|
45
45
|
end
|
46
46
|
cfg << uciexport
|
47
47
|
end
|
48
48
|
elsif binary_files.include? sysupgradefile
|
49
|
-
|
49
|
+
logger.debug "Exporting binary file - #{sysupgradefile}"
|
50
50
|
cfg << comment("#### Binary file: #{sysupgradefile} #####")
|
51
51
|
cfg << comment("Decode using 'echo -en <data> | gzip -dc > #{sysupgradefile}'")
|
52
52
|
cfg << cmd("gzip -c #{sysupgradefile} | hexdump -ve '1/1 \"_x%.2x\"' | tr _ \\")
|
53
53
|
elsif vars(:remove_secret) && sysupgradefile == '/etc/shadow'
|
54
|
-
|
54
|
+
logger.debug 'Exporting and scrubbing /etc/shadow'
|
55
55
|
cfg << comment("#### File: #{sysupgradefile} #####")
|
56
56
|
shadow = cmd("cat #{sysupgradefile}")
|
57
57
|
shadow.gsub!(/^([^:]+:)[^:]*(:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:)/, '\\1\\2')
|
58
58
|
cfg << shadow
|
59
59
|
else
|
60
|
-
|
60
|
+
logger.debug "Exporting file - #{sysupgradefile}"
|
61
61
|
cfg << comment("#### File: #{sysupgradefile} #####")
|
62
62
|
cfg << cmd("cat #{sysupgradefile}")
|
63
63
|
end
|
@@ -65,7 +65,7 @@ class OpenWrt < Oxidized::Model
|
|
65
65
|
@mtdpartitions.scan(/(\w+):\s+\w+\s+\w+\s+"(.*)"/).each do |partition, name|
|
66
66
|
next unless vars(:openwrt_backup_partitions) && partitions_to_backup.include?(name)
|
67
67
|
|
68
|
-
|
68
|
+
logger.debug "Exporting partition - #{name}(#{partition})"
|
69
69
|
cfg << comment("#### Partition: #{name} /dev/#{partition} #####")
|
70
70
|
cfg << comment("Decode using 'echo -en <data> | gzip -dc > #{name}'")
|
71
71
|
cfg << cmd("dd if=/dev/#{partition} 2>/dev/null | gzip -c | hexdump -ve '1/1 \"%.2x\"'")
|