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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +45 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  4. data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
  5. data/.github/workflows/publishdocker.yml +35 -16
  6. data/.github/workflows/ruby.yml +4 -2
  7. data/.gitignore +2 -0
  8. data/.rubocop.yml +29 -8
  9. data/.rubocop_todo.yml +1 -60
  10. data/CHANGELOG.md +103 -2
  11. data/CONTRIBUTING.md +20 -10
  12. data/Dockerfile +37 -64
  13. data/README.md +47 -141
  14. data/Rakefile +9 -11
  15. data/docs/Configuration.md +236 -27
  16. data/docs/DeviceSimulation.md +19 -7
  17. data/docs/Docker.md +245 -0
  18. data/docs/Issues.md +27 -1
  19. data/docs/Model-Notes/EatonNetwork.md +18 -0
  20. data/docs/Model-Notes/HPEAruba.md +3 -2
  21. data/docs/ModelUnitTests.md +35 -25
  22. data/docs/Outputs.md +83 -2
  23. data/docs/Release.md +34 -24
  24. data/docs/Supported-OS-Types.md +7 -0
  25. data/docs/Troubleshooting.md +4 -13
  26. data/extra/device2yaml.rb +24 -9
  27. data/extra/rest_client.rb +3 -2
  28. data/extra/syslog.rb +8 -3
  29. data/lib/oxidized/cli.rb +7 -3
  30. data/lib/oxidized/config/vars.rb +22 -14
  31. data/lib/oxidized/config.rb +3 -2
  32. data/lib/oxidized/core.rb +30 -8
  33. data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
  34. data/lib/oxidized/hook/exec.rb +5 -4
  35. data/lib/oxidized/hook/githubrepo.rb +23 -17
  36. data/lib/oxidized/hook/noophook.rb +2 -2
  37. data/lib/oxidized/hook/slackdiff.rb +9 -8
  38. data/lib/oxidized/hook/xmppdiff.rb +9 -9
  39. data/lib/oxidized/hook.rb +10 -8
  40. data/lib/oxidized/input/cli.rb +8 -3
  41. data/lib/oxidized/input/exec.rb +1 -1
  42. data/lib/oxidized/input/ftp.rb +2 -2
  43. data/lib/oxidized/input/http.rb +6 -6
  44. data/lib/oxidized/input/input.rb +1 -0
  45. data/lib/oxidized/input/scp.rb +2 -2
  46. data/lib/oxidized/input/ssh.rb +21 -14
  47. data/lib/oxidized/input/telnet.rb +3 -3
  48. data/lib/oxidized/input/tftp.rb +1 -1
  49. data/lib/oxidized/job.rb +7 -4
  50. data/lib/oxidized/logger.rb +51 -0
  51. data/lib/oxidized/model/acos.rb +1 -0
  52. data/lib/oxidized/model/aos7.rb +9 -0
  53. data/lib/oxidized/model/aoscx.rb +2 -0
  54. data/lib/oxidized/model/aosw.rb +22 -17
  55. data/lib/oxidized/model/aricentiss.rb +2 -2
  56. data/lib/oxidized/model/asa.rb +3 -3
  57. data/lib/oxidized/model/awplus.rb +13 -10
  58. data/lib/oxidized/model/eatonnetwork.rb +65 -0
  59. data/lib/oxidized/model/edgecos.rb +2 -1
  60. data/lib/oxidized/model/edgeos.rb +7 -6
  61. data/lib/oxidized/model/edgeswitch.rb +3 -1
  62. data/lib/oxidized/model/efos.rb +41 -0
  63. data/lib/oxidized/model/eltex.rb +1 -1
  64. data/lib/oxidized/model/fabricos.rb +1 -1
  65. data/lib/oxidized/model/fastiron.rb +3 -1
  66. data/lib/oxidized/model/firelinuxos.rb +12 -3
  67. data/lib/oxidized/model/fortios.rb +5 -4
  68. data/lib/oxidized/model/gaiaos.rb +4 -4
  69. data/lib/oxidized/model/ingate.rb +47 -0
  70. data/lib/oxidized/model/ios.rb +16 -5
  71. data/lib/oxidized/model/ironware.rb +1 -1
  72. data/lib/oxidized/model/junos.rb +4 -0
  73. data/lib/oxidized/model/linksyssrw.rb +3 -3
  74. data/lib/oxidized/model/mlnxos.rb +14 -7
  75. data/lib/oxidized/model/model.rb +4 -3
  76. data/lib/oxidized/model/netgear.rb +8 -0
  77. data/lib/oxidized/model/nsxdfw.rb +2 -1
  78. data/lib/oxidized/model/nsxfirewall.rb +2 -1
  79. data/lib/oxidized/model/nxos.rb +2 -2
  80. data/lib/oxidized/model/openwrt.rb +6 -6
  81. data/lib/oxidized/model/powerconnect.rb +31 -10
  82. data/lib/oxidized/model/procurve.rb +3 -1
  83. data/lib/oxidized/model/qtech.rb +3 -1
  84. data/lib/oxidized/model/quantaos.rb +8 -6
  85. data/lib/oxidized/model/routeros.rb +3 -2
  86. data/lib/oxidized/model/saos10.rb +38 -0
  87. data/lib/oxidized/model/sixwind.rb +28 -0
  88. data/lib/oxidized/model/sonicos.rb +1 -1
  89. data/lib/oxidized/model/srosmd.rb +1 -1
  90. data/lib/oxidized/model/supermicro.rb +1 -1
  91. data/lib/oxidized/model/timos.rb +1 -1
  92. data/lib/oxidized/model/tmos.rb +1 -0
  93. data/lib/oxidized/model/tnsr.rb +53 -0
  94. data/lib/oxidized/model/trango.rb +3 -1
  95. data/lib/oxidized/model/unifiap.rb +144 -0
  96. data/lib/oxidized/model/vrp.rb +3 -1
  97. data/lib/oxidized/model/xos.rb +3 -1
  98. data/lib/oxidized/model/zhoneolt.rb +3 -1
  99. data/lib/oxidized/model/zynos.rb +3 -3
  100. data/lib/oxidized/node.rb +44 -27
  101. data/lib/oxidized/nodes.rb +8 -4
  102. data/lib/oxidized/output/file.rb +28 -0
  103. data/lib/oxidized/output/git.rb +148 -41
  104. data/lib/oxidized/output/gitcrypt.rb +18 -13
  105. data/lib/oxidized/output/http.rb +5 -4
  106. data/lib/oxidized/output/output.rb +14 -0
  107. data/lib/oxidized/source/http.rb +4 -2
  108. data/lib/oxidized/version.rb +6 -4
  109. data/lib/oxidized/worker.rb +13 -13
  110. data/lib/oxidized.rb +3 -24
  111. data/lib/refinements.rb +2 -0
  112. data/oxidized.gemspec +10 -8
  113. metadata +74 -41
  114. data/examples/podman-compose/Makefile +0 -103
  115. data/examples/podman-compose/README.md +0 -94
  116. data/examples/podman-compose/docker-compose.yml +0 -30
  117. data/examples/podman-compose/gitserver/.gitignore +0 -1
  118. data/examples/podman-compose/gitserver/Dockerfile +0 -14
  119. data/examples/podman-compose/model-simulation/Dockerfile-model +0 -13
  120. data/examples/podman-compose/model-simulation/asternos.sh +0 -36
  121. data/examples/podman-compose/oxidized-config/.gitignore +0 -10
  122. data/examples/podman-compose/oxidized-config/config +0 -46
  123. data/examples/podman-compose/oxidized-config/config_csv-file +0 -46
  124. data/examples/podman-compose/oxidized-config/config_csv-gitserver +0 -56
  125. data/examples/podman-compose/oxidized-config/router.db +0 -1
  126. data/examples/podman-compose/oxidized-ssh/.gitignore +0 -1
  127. 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$/, '<fan speeds 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$/,
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! /encrypted-password (\S+).*/, 'encrypted-password <secret removed>'
14
- cfg.gsub! /plaintext-password (\S+).*/, 'plaintext-password <secret removed>'
15
- cfg.gsub! /password (\S+).*/, 'password <secret removed>'
16
- cfg.gsub! /pre-shared-secret (\S+).*/, 'pre-shared-secret <secret removed>'
17
- cfg.gsub! /community (\S+) {/, 'community <hidden> {'
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 { |line| line.match(/System Up Time.*/) || line.match(/Current SNTP Synchronized Time.*/) }.join
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
@@ -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(\s+[^\n]+\n)*\s+key) [^\n]+$/m, '\1 <secret hidden>'
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
- comments << "Boot-Monitor Version: #{Regexp.last_match(1)}" if line =~ /^\s+Compressed Boot-Monitor Image size = \d+, Version:(.*)$/
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 /^[#>]\(?.+\)?\s?/
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
- cfg.each_line.to_a[1..-2].join
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:).*/, '\\1 <stripped>'
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+)(.*)/, '\1<stripped>\3'
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
- next if fullcfg.lines[1..3].join =~ /(Parsing error at|command parse error)/ # Don't show for unsupported devices (e.g. FortiAnalyzer, FortiManager, FortiMail)
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
- Oxidized.logger.debug cfg
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
- Oxidized.logger.debug 'Single context tasks'
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
- Oxidized.logger.debug 'Multi context tasks'
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
- Oxidized.logger.debug vs
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
@@ -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
- comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}" if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
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
- comments << "ROM Bootstrap: #{Regexp.last_match(3)}" if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
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
- comments << "Memory: flash #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
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
- comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i
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 { |line| line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/ }.join
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{2}\.\d deg-C/, 'XX.X deg-C'
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 = ''
@@ -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
- Oxidized.logger.send(:debug, "#{self.class.name}: Login Screen")
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
- Oxidized.logger.send(:debug, "#{self.class.name}: Switch menu")
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
- Oxidized.logger.send(:debug, "#{self.class.name}: >")
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 /([\w.@()-\[:\s\]]+[#>]\s)$/
4
+ prompt /^\r?(\e.+\e>\r)?\S* \[\S+: (master|standby)\] [#>] $/
5
5
  comment '## '
6
6
 
7
7
  # Pager Handling
8
- expect /.+lines\s\d+-\d+([\s]|\/\d+\s\(END\)\s).+$/ do |data, re|
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! /\[\?1h=\r/, '' # Pager Handling
15
- cfg.gsub! /\[24;1H/, '' # Pager Handling
16
- cfg.gsub! /\r\[K/, '' # Pager Handling
17
- cfg.gsub! /\[K/, '' # Pager Handling
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
@@ -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
- Oxidized.logger.debug "lib/oxidized/model/model.rb Added #{cmd_arg} to the commands list"
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
- Oxidized.logger.debug "lib/oxidized/model/model.rb Executing #{string}"
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
- Oxidized.logger.debug 'lib/oxidized/model/model.rb Collecting commands\' outputs'
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', { invalid: :replace, undef: :replace, replace: '?' }))["results"]
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']}"] = JSON.parse(firewall_config.encode('UTF-8', { invalid: :replace, undef: :replace, replace: '?' }))
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)
@@ -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
- Oxidized.logger.debug "Exporting uci config - #{filename}"
41
+ logger.debug "Exporting uci config - #{filename}"
42
42
  if vars(:remove_secret) && !(non_sensitive_files.include? filename)
43
- Oxidized.logger.debug "Scrubbing uci config - #{filename}"
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
- Oxidized.logger.debug "Exporting binary file - #{sysupgradefile}"
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
- Oxidized.logger.debug 'Exporting and scrubbing /etc/shadow'
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
- Oxidized.logger.debug "Exporting file - #{sysupgradefile}"
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
- Oxidized.logger.debug "Exporting partition - #{name}(#{partition})"
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\"'")