oxidized 0.28.0 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publishdocker.yml +8 -1
  3. data/.github/workflows/ruby.yml +42 -0
  4. data/.rubocop.yml +30 -10
  5. data/.rubocop_todo.yml +95 -41
  6. data/CHANGELOG.md +139 -2
  7. data/Dockerfile +13 -9
  8. data/README.md +66 -32
  9. data/Rakefile +2 -0
  10. data/docs/Configuration.md +49 -7
  11. data/docs/Creating-Models.md +10 -4
  12. data/docs/Hooks.md +35 -6
  13. data/docs/Model-Notes/ADVA.md +12 -0
  14. data/docs/Model-Notes/Cumulus.md +7 -1
  15. data/docs/Model-Notes/IOS.md +36 -0
  16. data/docs/Model-Notes/JunOS.md +3 -3
  17. data/docs/Model-Notes/LenovoNOS.md +29 -0
  18. data/docs/Model-Notes/LinksysSRW.md +15 -0
  19. data/docs/Model-Notes/Nokia.md +3 -0
  20. data/docs/Model-Notes/OS10.md +33 -0
  21. data/docs/Model-Notes/PanOS_API.md +28 -0
  22. data/docs/Model-Notes/README.md +2 -0
  23. data/docs/Sources.md +18 -0
  24. data/docs/Supported-OS-Types.md +51 -6
  25. data/docs/Troubleshooting.md +1 -1
  26. data/extra/gitdiff-msteams.sh +91 -0
  27. data/extra/nagios_check_failing_nodes.rb +6 -9
  28. data/extra/oxidized-report-git-commits +71 -14
  29. data/extra/oxidized.init +2 -5
  30. data/extra/oxidized.logrotate +1 -0
  31. data/extra/oxidized.runit +4 -1
  32. data/extra/oxidized.service +5 -8
  33. data/extra/rest_client.rb +1 -1
  34. data/extra/syslog.rb +2 -2
  35. data/lib/oxidized/cli.rb +1 -1
  36. data/lib/oxidized/config/vars.rb +5 -2
  37. data/lib/oxidized/config.rb +6 -3
  38. data/lib/oxidized/core.rb +1 -1
  39. data/lib/oxidized/hook/exec.rb +6 -6
  40. data/lib/oxidized/hook/githubrepo.rb +42 -11
  41. data/lib/oxidized/hook/slackdiff.rb +2 -2
  42. data/lib/oxidized/hook/xmppdiff.rb +45 -25
  43. data/lib/oxidized/hook.rb +4 -8
  44. data/lib/oxidized/input/exec.rb +1 -1
  45. data/lib/oxidized/input/input.rb +1 -0
  46. data/lib/oxidized/input/ssh.rb +23 -20
  47. data/lib/oxidized/input/telnet.rb +52 -44
  48. data/lib/oxidized/job.rb +1 -0
  49. data/lib/oxidized/jobs.rb +11 -6
  50. data/lib/oxidized/manager.rb +1 -0
  51. data/lib/oxidized/model/acmepacket.rb +38 -0
  52. data/lib/oxidized/model/adtran.rb +5 -3
  53. data/lib/oxidized/model/adva.rb +66 -0
  54. data/lib/oxidized/model/airfiber.rb +1 -1
  55. data/lib/oxidized/model/aoscx.rb +96 -0
  56. data/lib/oxidized/model/aosw.rb +1 -1
  57. data/lib/oxidized/model/asa.rb +2 -0
  58. data/lib/oxidized/model/awplus.rb +1 -1
  59. data/lib/oxidized/model/bdcom.rb +49 -0
  60. data/lib/oxidized/model/cambiumepmp.rb +17 -0
  61. data/lib/oxidized/model/casa.rb +4 -1
  62. data/lib/oxidized/model/ciscoce.rb +12 -0
  63. data/lib/oxidized/model/ciscosmb.rb +2 -0
  64. data/lib/oxidized/model/comware.rb +16 -1
  65. data/lib/oxidized/model/cumulus.rb +58 -44
  66. data/lib/oxidized/model/dellx.rb +1 -3
  67. data/lib/oxidized/model/dlink.rb +2 -1
  68. data/lib/oxidized/model/edgecos.rb +22 -2
  69. data/lib/oxidized/model/edgeswitch.rb +4 -4
  70. data/lib/oxidized/model/eltex.rb +48 -0
  71. data/lib/oxidized/model/enterasys.rb +18 -3
  72. data/lib/oxidized/model/enterasys800.rb +29 -0
  73. data/lib/oxidized/model/eos.rb +2 -1
  74. data/lib/oxidized/model/fabricos.rb +1 -1
  75. data/lib/oxidized/model/fastiron.rb +3 -2
  76. data/lib/oxidized/model/fortios.rb +24 -11
  77. data/lib/oxidized/model/fortiwlc.rb +24 -0
  78. data/lib/oxidized/model/gaiaos.rb +40 -3
  79. data/lib/oxidized/model/h3c.rb +40 -0
  80. data/lib/oxidized/model/hatteras.rb +2 -2
  81. data/lib/oxidized/model/hios.rb +38 -0
  82. data/lib/oxidized/model/hpebladesystem.rb +1 -1
  83. data/lib/oxidized/model/ios.rb +13 -10
  84. data/lib/oxidized/model/iosxe.rb +1 -1
  85. data/lib/oxidized/model/ironware.rb +8 -4
  86. data/lib/oxidized/model/junos.rb +5 -1
  87. data/lib/oxidized/model/lancom.rb +23 -0
  88. data/lib/oxidized/model/lenovonos.rb +82 -0
  89. data/lib/oxidized/model/linksyssrw.rb +71 -0
  90. data/lib/oxidized/model/mlnxos.rb +2 -0
  91. data/lib/oxidized/model/model.rb +29 -3
  92. data/lib/oxidized/model/necix.rb +30 -0
  93. data/lib/oxidized/model/netgear.rb +5 -2
  94. data/lib/oxidized/model/netscaler.rb +38 -1
  95. data/lib/oxidized/model/nodegrid.rb +23 -0
  96. data/lib/oxidized/model/nxos.rb +3 -2
  97. data/lib/oxidized/model/openbsd.rb +9 -0
  98. data/lib/oxidized/model/opengear.rb +1 -1
  99. data/lib/oxidized/model/opnsense.rb +12 -4
  100. data/lib/oxidized/model/panos_api.rb +71 -0
  101. data/lib/oxidized/model/pfsense.rb +12 -7
  102. data/lib/oxidized/model/powerconnect.rb +1 -3
  103. data/lib/oxidized/model/procurve.rb +2 -2
  104. data/lib/oxidized/model/purityos.rb +8 -1
  105. data/lib/oxidized/model/quantaos.rb +1 -5
  106. data/lib/oxidized/model/routeros.rb +15 -2
  107. data/lib/oxidized/model/slxos.rb +1 -0
  108. data/lib/oxidized/model/smartcs.rb +40 -0
  109. data/lib/oxidized/model/sonicos.rb +9 -1
  110. data/lib/oxidized/model/srosmd.rb +97 -0
  111. data/lib/oxidized/model/stoneos.rb +6 -2
  112. data/lib/oxidized/model/supermicro.rb +1 -1
  113. data/lib/oxidized/model/swos.rb +9 -0
  114. data/lib/oxidized/model/timos.rb +1 -1
  115. data/lib/oxidized/model/tmos.rb +2 -1
  116. data/lib/oxidized/model/tplink.rb +2 -0
  117. data/lib/oxidized/model/trango.rb +11 -11
  118. data/lib/oxidized/model/truenas.rb +20 -0
  119. data/lib/oxidized/model/vrp.rb +1 -1
  120. data/lib/oxidized/model/xos.rb +4 -3
  121. data/lib/oxidized/model/yamaha.rb +57 -0
  122. data/lib/oxidized/model/zteolt.rb +52 -0
  123. data/lib/oxidized/model/zy1308.rb +11 -0
  124. data/lib/oxidized/node/stats.rb +1 -0
  125. data/lib/oxidized/node.rb +16 -11
  126. data/lib/oxidized/nodes.rb +7 -6
  127. data/lib/oxidized/output/file.rb +2 -1
  128. data/lib/oxidized/output/git.rb +4 -3
  129. data/lib/oxidized/output/gitcrypt.rb +5 -8
  130. data/lib/oxidized/output/http.rb +2 -0
  131. data/lib/oxidized/source/csv.rb +1 -0
  132. data/lib/oxidized/source/http.rb +4 -0
  133. data/lib/oxidized/source/source.rb +7 -2
  134. data/lib/oxidized/source/sql.rb +15 -5
  135. data/lib/oxidized/string.rb +9 -3
  136. data/lib/oxidized/version.rb +2 -2
  137. data/lib/oxidized/worker.rb +5 -5
  138. data/oxidized.gemspec +22 -16
  139. metadata +116 -29
  140. data/.travis.yml +0 -10
@@ -46,7 +46,7 @@ class FastIron < Oxidized::Model
46
46
  cmd 'show running-config'
47
47
 
48
48
  cfg :telnet do
49
- username /^.* login: /
49
+ username /^(.* login|Username): /
50
50
  password /^Password:/
51
51
  end
52
52
 
@@ -56,11 +56,12 @@ class FastIron < Oxidized::Model
56
56
  if vars(:enable) == true
57
57
  cmd "enable"
58
58
  elsif vars(:enable)
59
- cmd "enable", /^[pP]assword:/
59
+ cmd "enable", /[pP]assword:/
60
60
  cmd vars(:enable)
61
61
  end
62
62
  end
63
63
  post_login 'skip-page-display'
64
64
  pre_logout 'exit'
65
+ pre_logout 'exit'
65
66
  end
66
67
  end
@@ -21,7 +21,7 @@ class FortiOS < Oxidized::Model
21
21
  cfg.gsub! /(set (?:passwd|password|key|group-password|auth-password-l1|auth-password-l2|rsso|history0|history1)) .+/, '\\1 <configuration removed>'
22
22
  cfg.gsub! /(set md5-key [0-9]+) .+/, '\\1 <configuration removed>'
23
23
  cfg.gsub! /(set private-key ).*?-+END (ENCRYPTED|RSA|OPENSSH) PRIVATE KEY-+\n?"$/m, '\\1<configuration removed>'
24
- cfg.gsub! /(set ca ).*?-+END CERTIFICATE-+"$/m, '\\1<configuration removed>'
24
+ cfg.gsub! /(set ca )"-+BEGIN.*?-+END CERTIFICATE-+"$/m, '\\1<configuration removed>'
25
25
  cfg.gsub! /(set csr ).*?-+END CERTIFICATE REQUEST-+"$/m, '\\1<configuration removed>'
26
26
  cfg
27
27
  end
@@ -29,13 +29,14 @@ class FortiOS < Oxidized::Model
29
29
  cmd 'get system status' do |cfg|
30
30
  @vdom_enabled = cfg.match /Virtual domain configuration: (enable|multiple)/
31
31
  cfg.gsub! /(System time:).*/, '\\1 <stripped>'
32
- cfg.gsub! /(Cluster uptime:).*/, '\\1 <stripped>'
33
- cfg.gsub! /(Virus-DB|Extended DB|IPS-DB|IPS-ETDB|APP-DB|INDUSTRIAL-DB|Botnet DB|IPS Malicious URL Database).*/, '\\1 <db version stripped>'
34
- comment cfg
35
- end
36
-
37
- cmd 'get system ha status' do |cfg|
38
- cfg = cfg.each_line.select { |line| line.match /^(HA Health Status|Mode|Model|Master|Slave\s+):/ }.join
32
+ cfg.gsub! /(Cluster (?:uptime|state change time):).*/, '\\1 <stripped>'
33
+ cfg.gsub! /(Current Time\s+:\s+)(.*)/, '\1<stripped>'
34
+ cfg.gsub! /(Uptime:\s+)(.*)/, '\1<stripped>\3'
35
+ cfg.gsub! /(Last reboot:\s+)(.*)/, '\1<stripped>\3'
36
+ cfg.gsub! /(Disk Usage\s+:\s+)(.*)/, '\1<stripped>'
37
+ cfg.gsub! /(^\S+ (?:disk|DB):\s+)(.*)/, '\1<stripped>\3'
38
+ cfg.gsub! /(VM Registration:\s+)(.*)/, '\1<stripped>\3'
39
+ cfg.gsub! /(Virus-DB|Extended DB|IPS-DB|IPS-ETDB|APP-DB|INDUSTRIAL-DB|Botnet DB|IPS Malicious URL Database|AV AI\/ML Model|IoT-Detect).*/, '\\1 <db version stripped>'
39
40
  comment cfg
40
41
  end
41
42
 
@@ -43,6 +44,11 @@ class FortiOS < Oxidized::Model
43
44
  cfg = []
44
45
  cfg << cmd('config global') if @vdom_enabled
45
46
 
47
+ cfg << cmd('get system ha status') do |cfg_ha|
48
+ cfg_ha = cfg_ha.each_line.select { |line| line.match /^(HA Health Status|Mode|Model|Master|Slave|Primary|Secondary|# COMMAND)(\s+)?:/ }.join
49
+ comment cfg_ha
50
+ end
51
+
46
52
  cfg << cmd('get hardware status') do |cfg_hw|
47
53
  comment cfg_hw
48
54
  end
@@ -58,12 +64,19 @@ class FortiOS < Oxidized::Model
58
64
 
59
65
  cfg << cmd('end') if @vdom_enabled
60
66
 
61
- cfg << cmd('show full-configuration | grep .')
62
- cfg.join "\n"
67
+ ['show full-configuration | grep .', 'show full-configuration', 'show'].each do |fullcmd|
68
+ fullcfg = cmd(fullcmd)
69
+ next if fullcfg.lines[1..3].join =~ /(Parsing error at|command parse error)/ # Don't show for unsupported devices (e.g. FortiAnalyzer, FortiManager, FortiMail)
70
+
71
+ cfg << fullcfg
72
+ break
73
+ end
74
+
75
+ cfg.join
63
76
  end
64
77
 
65
78
  cfg :telnet do
66
- username /login:/
79
+ username /^[lL]ogin:/
67
80
  password /^Password:/
68
81
  end
69
82
 
@@ -0,0 +1,24 @@
1
+ class FortiWLC < Oxidized::Model
2
+ comment '# '
3
+
4
+ cmd :all do |cfg, cmdstring|
5
+ new_cfg = comment "COMMAND: #{cmdstring}\n"
6
+ new_cfg << cfg.each_line.to_a[1..-2].map { |line| line.gsub(/(conf_file_ver=)(.*)/, '\1<stripped>\3') }.join
7
+ end
8
+
9
+ prompt /^([-\w.\/:?\[\]()]+[#>]\s?)$/
10
+
11
+ cmd 'show controller' do |cfg|
12
+ comment cfg
13
+ end
14
+ cmd 'show ap' do |cfg|
15
+ comment cfg
16
+ end
17
+ cmd 'show running-config' do |cfg|
18
+ comment cfg
19
+ end
20
+
21
+ cfg :telnet, :ssh do
22
+ pre_logout "exit\n"
23
+ end
24
+ end
@@ -21,6 +21,12 @@ class GaiaOS < Oxidized::Model
21
21
  cfg
22
22
  end
23
23
 
24
+ # check for vsx / multiple context
25
+ cmd 'show vsx' do |cfg|
26
+ @is_vsx = cfg.include? 'VSX Enabled'
27
+ Oxidized.logger.debug cfg
28
+ end
29
+
24
30
  cmd 'show asset all' do |cfg|
25
31
  comment cfg
26
32
  end
@@ -29,9 +35,40 @@ class GaiaOS < Oxidized::Model
29
35
  comment cfg
30
36
  end
31
37
 
32
- cmd 'show configuration' do |cfg|
33
- cfg.gsub! /^# Exported by \S+ on .*/, '# '
34
- cfg
38
+ post do
39
+ if @is_vsx
40
+ multiple_context
41
+ else
42
+ single_context
43
+ end
44
+ end
45
+
46
+ def single_context
47
+ Oxidized.logger.debug 'Single context tasks'
48
+ cmd 'show configuration' do |cfg|
49
+ cfg.gsub! /^# Exported by \S+ on .*/, '# '
50
+ cfg
51
+ end
52
+ end
53
+
54
+ def multiple_context
55
+ Oxidized.logger.debug 'Multi context tasks'
56
+ cmd 'show virtual-system all' do |systems|
57
+ vs_items = systems.scan(/^(?<VSID>\d+)\s+(?<VSNAME>.*[^\s])/)
58
+ allcfg = ''
59
+ vs_items.each do |item|
60
+ allcfg += "\n\n\n#--------======== [ VS #{item[0]} - #{item[1]} ] ========--------\n\n"
61
+ allcfg += "set virtual-system #{item[0]}\n\n"
62
+ cmd "set virtual-system #{item[0]}" do |vs|
63
+ Oxidized.logger.debug vs
64
+ cmd 'show configuration' do |vscfg|
65
+ vscfg.gsub! /^# Exported by \S+ on .*/, '# '
66
+ allcfg += vscfg
67
+ end
68
+ end
69
+ end
70
+ allcfg
71
+ end
35
72
  end
36
73
 
37
74
  cfg :ssh do
@@ -0,0 +1,40 @@
1
+ class H3C < Oxidized::Model
2
+ # H3C
3
+
4
+ prompt /^.*(<[\w.-]+>)$/
5
+ comment '# '
6
+
7
+ cmd :secret do |cfg|
8
+ cfg.gsub! /(pin verify (?:auto|)).*/, '\\1 <PIN hidden>'
9
+ cfg.gsub! /(%\^%#.*%\^%#)/, '<secret hidden>'
10
+ cfg
11
+ end
12
+
13
+ cmd :all do |cfg|
14
+ cfg.cut_both
15
+ end
16
+
17
+ cfg :telnet do
18
+ username /^Username:$/
19
+ password /^Password:$/
20
+ end
21
+
22
+ cfg :telnet, :ssh do
23
+ post_login 'screen-length disable'
24
+ pre_logout 'quit'
25
+ end
26
+
27
+ cmd 'display version' do |cfg|
28
+ cfg = cfg.each_line.reject { |l| l.match /uptime/ }.join
29
+ cfg = cfg.each_line.reject { |l| l.match /Uptime is/ }.join
30
+ comment cfg
31
+ end
32
+
33
+ cmd 'display device' do |cfg|
34
+ comment cfg
35
+ end
36
+
37
+ cmd 'display current-configuration' do |cfg|
38
+ cfg
39
+ end
40
+ end
@@ -24,7 +24,7 @@ class Hatteras < Oxidized::Model
24
24
  cfg = cfg.each_line.reject do |line|
25
25
  line.match(/Switch uptime|Switch temperature|Last reset reason/) ||
26
26
  line.match(/TermCpuUtil|^\s+\^$|ERROR: Bad command/)
27
- end .join
27
+ end.join
28
28
  comment cfg
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ class Hatteras < Oxidized::Model
32
32
  cfg = cfg.each_line.reject do |line|
33
33
  line.match(/Card uptime|Card temperature|Last reset reason/) ||
34
34
  line.match(/TermCpuUtil|^\s+\^$|ERROR: Bad command/)
35
- end .join
35
+ end.join
36
36
  comment cfg
37
37
  end
38
38
 
@@ -0,0 +1,38 @@
1
+ class Hios < Oxidized::Model
2
+ ## Docker location: /var/lib/gems/2.7.0/gems/oxidized-0.28.0/lib/oxidized/model/hios.rb
3
+ prompt /^\[[\w\s\W]+\][>|#]+?$/
4
+
5
+ comment '## '
6
+
7
+ # Handle pager
8
+ expect /^--More--.*$/ do |data, re|
9
+ send 'n'
10
+ data.sub re, ''
11
+ end
12
+
13
+ cmd :all do |cfg|
14
+ cfg.cut_both
15
+ end
16
+
17
+ cmd 'show system info' do |cfg|
18
+ cfg.gsub! /^System uptime.*\n/, ""
19
+ cfg.gsub! /^Operating hours.*\n/, ""
20
+ cfg.gsub! /^System date.*\n/, ""
21
+ cfg.gsub! /^Current temperature.*\n/, ""
22
+ comment cfg
23
+ end
24
+
25
+ cmd 'show running-config script' do |cfg|
26
+ cfg
27
+ end
28
+
29
+ cfg :telnet do
30
+ username /^User:/
31
+ password /^Password:/
32
+ end
33
+
34
+ cfg :telnet, :ssh do
35
+ post_login 'enable'
36
+ pre_logout "logout\nY\r\n"
37
+ end
38
+ end
@@ -69,7 +69,7 @@ class HPEBladeSystem < Oxidized::Model
69
69
  end
70
70
 
71
71
  cmd 'show config' do |cfg|
72
- cfg.gsub! /^#(Generated on:) .*$/, '\\1 <removed>'
72
+ cfg.gsub! /^(#Generated on:) .*$/, '\\1 <removed>'
73
73
  cfg.gsub /^\s+/, ''
74
74
  end
75
75
 
@@ -105,16 +105,19 @@ class IOS < Oxidized::Model
105
105
  comment cfg
106
106
  end
107
107
 
108
- cmd 'show running-config' do |cfg|
109
- cfg = cfg.each_line.to_a[3..-1]
110
- cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
111
- cfg.gsub! /^Current configuration : [^\n]*\n/, ''
112
- cfg.gsub! /^! (Last|No) configuration change (at|since).*\n/, ''
113
- cfg.gsub! /^! NVRAM config last updated.*\n/, ''
114
- cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
115
- (?: [^\n]*\n*)*
116
- tunnel mpls traffic-eng auto-bw)/mx, '\1'
117
- cfg
108
+ post do
109
+ cmd_line = 'show running-config'
110
+ cmd_line += ' view full' if vars(:ios_rbac)
111
+ cmd cmd_line do |cfg|
112
+ cfg = cfg.each_line.to_a[3..-1]
113
+ cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
114
+ cfg = cfg.each_line.reject { |line| line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/ }.join
115
+ cfg.gsub! /^Current configuration : [^\n]*\n/, ''
116
+ cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
117
+ (?: [^\n]*\n*)*
118
+ tunnel mpls traffic-eng auto-bw)/mx, '\1'
119
+ cfg
120
+ end
118
121
  end
119
122
 
120
123
  cfg :telnet do
@@ -1,5 +1,5 @@
1
1
  # IOS parser should work here
2
2
 
3
- require_relative 'ios.rb'
3
+ require_relative 'ios'
4
4
 
5
5
  IOSXE = IOS
@@ -31,7 +31,7 @@ class IronWare < Oxidized::Model
31
31
  cfg.encode!("UTF-8", invalid: :replace, undef: :replace) # sometimes ironware returns broken encoding
32
32
  cfg.gsub! /(^((.*)Current temp(.*))$)/, '' # remove unwanted lines current temperature
33
33
  cfg.gsub! /Speed = [A-Z-]{2,6} \(\d{2,3}%\)/, '' # remove unwanted lines Speed Fans
34
- cfg.gsub! /current speed is [A-Z]{2,6} \(\d{2,3}%\)/, ''
34
+ cfg.gsub! /current speed is [A-Z-]{2,6} \(\d{2,3}%\)/, ''
35
35
  cfg.gsub! /Fan \d* - STATUS: OK \D*\d*./, '' # Fix for ADX Fan speed reporting
36
36
  cfg.gsub! /\d* deg C/, '' # Fix for ADX temperature reporting
37
37
  cfg.gsub! /([\[]*)1([\]]*)<->([\[]*)2([\]]*)(<->([\[]*)3([\]]*))*/, ''
@@ -75,9 +75,13 @@ class IronWare < Oxidized::Model
75
75
  # handle pager with enable
76
76
  cfg :telnet, :ssh do
77
77
  if vars :enable
78
- post_login do
79
- send "enable\r\n"
80
- cmd vars(:enable)
78
+ if vars(:enable).is_a? TrueClass
79
+ post_login 'enable'
80
+ else
81
+ post_login do
82
+ send "enable\r\n"
83
+ cmd vars(:enable)
84
+ end
81
85
  end
82
86
  end
83
87
  post_login ''
@@ -34,7 +34,11 @@ class JunOS < Oxidized::Model
34
34
  end
35
35
 
36
36
  cmd('show chassis hardware') { |cfg| comment cfg }
37
- cmd('show system license') { |cfg| comment cfg }
37
+ cmd('show system license') do |cfg|
38
+ cfg.gsub!(/ fib-scale\s+(\d+)/, ' fib-scale <count>')
39
+ cfg.gsub!(/ rib-scale\s+(\d+)/, ' rib-scale <count>')
40
+ comment cfg
41
+ end
38
42
  cmd('show system license keys') { |cfg| comment cfg }
39
43
 
40
44
  cmd 'show configuration | display omit'
@@ -0,0 +1,23 @@
1
+ class LANCOM < Oxidized::Model
2
+ # LANCOM Systems GmbH
3
+ # tested on LANCOM 1781EF+ router using Lancom OS 10.32.0176RU9 / 21.04.2020
4
+ comment '# '
5
+
6
+ prompt />\s?$/
7
+
8
+ cmd "sysinfo\r" do |cfg|
9
+ cfg.gsub! /^TIME:.*\n/, ''
10
+ comment cfg
11
+ end
12
+
13
+ cmd "readscript\r"
14
+
15
+ cfg :telnet do
16
+ username /login:\s/
17
+ password /^Password:\s/
18
+ end
19
+
20
+ cfg :telnet, :ssh do
21
+ pre_logout "exit\r"
22
+ end
23
+ end
@@ -0,0 +1,82 @@
1
+ class LenovoNOS < Oxidized::Model
2
+ prompt /^([\w.@()-]+[#>]\s?)$/
3
+ comment '! '
4
+
5
+ def comment_ext(header, output)
6
+ data = ''
7
+ data << header
8
+ data << "\n"
9
+ data << output
10
+ data << "\n"
11
+ comment data
12
+ end
13
+
14
+ cmd :all do |cfg|
15
+ cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
16
+ cfg.cut_both
17
+ end
18
+
19
+ cmd :secret do |cfg|
20
+ cfg.gsub! /^(enable password) \S+(.*)/, '\\1 <secret hidden>\\2'
21
+ cfg.gsub! /^(access user \S+ password) \S+(.*)/, '\\1 <secret hidden>\\2'
22
+ cfg.gsub! /^(snmp-server \S+-community) \S+(.*)/, '\\1 <secret hidden>\\2'
23
+ cfg.gsub! /^(tacacs-server \S+ \S+ ekey) \S+(.*)/, '\\1 <secret hidden>\\2'
24
+ cfg.gsub! /^(ntp message-digest-key \S+ md5-ekey) \S+(.*)/, '\\1 <secret hidden>\\2'
25
+ cfg.gsub! /(.* password )"[0-9a-f]+"(.*)/, '\\1<secret hidden>\\2'
26
+ cfg.gsub! /(.*ekey )"[0-9a-f]+"(.*)/, '\\1<secret hidden>\\2'
27
+ cfg
28
+ end
29
+
30
+ expect /^Select Command Line Interface mode.*iscli.*:/ do |data, re|
31
+ send "iscli\n"
32
+ data.sub re, ''
33
+ end
34
+
35
+ cmd 'show version' do |cfg|
36
+ cfg = cfg.each_line.to_a
37
+
38
+ cfg = cfg.reject { |line| line.match /^System Information at/ }
39
+ cfg = cfg.reject { |line| line.match /^Switch has been up for/ }
40
+ cfg = cfg.reject { |line| line.match /^Last boot:/ }
41
+ cfg = cfg.reject { |line| line.match /^Temperature / }
42
+ cfg = cfg.reject { |line| line.match /^Power Consumption/ }
43
+
44
+ cfg = cfg.join
45
+ comment_ext("=== show version ===", cfg)
46
+ end
47
+
48
+ cmd 'show boot' do |cfg|
49
+ comment_ext("=== show boot ===", cfg)
50
+ end
51
+
52
+ cmd 'show transceiver' do |cfg|
53
+ comment_ext("=== show transceiver ===", cfg)
54
+ end
55
+
56
+ cmd 'show software-key' do |cfg|
57
+ comment_ext("=== show software-key ===", cfg)
58
+ end
59
+
60
+ cmd 'show running-config' do |cfg|
61
+ cfg.gsub! /^Current configuration:[^\n]*\n/, ''
62
+ if vars(:remove_unstable_lines) == true
63
+ cfg.gsub! /(.* password )"[0-9a-f]+"(.*)/, '\\1<unstable line hidden>\\2'
64
+ cfg.gsub! /(.*ekey )"[0-9a-f]+"(.*)/, '\\1<unstable line hidden>\\2'
65
+ end
66
+ cfg
67
+ end
68
+
69
+ cfg :ssh do
70
+ # preferred way to handle additional passwords
71
+ post_login do
72
+ if vars(:enable) == true
73
+ cmd "enable"
74
+ elsif vars(:enable)
75
+ cmd "enable", /^[pP]assword:/
76
+ cmd vars(:enable)
77
+ end
78
+ end
79
+ post_login 'terminal-length 0'
80
+ pre_logout 'exit'
81
+ end
82
+ end
@@ -0,0 +1,71 @@
1
+ class LinksysSRW < Oxidized::Model
2
+ comment '! '
3
+
4
+ prompt /^([\r\w.@-]+[#>]\s?)$/
5
+
6
+ # Graphical login screen
7
+ # Just login to get to Main Menu
8
+ expect /Login Screen/ do
9
+ Oxidized.logger.send(:debug, "#{self.class.name}: Login Screen")
10
+ # This is to ensure the whole thing have rendered before we send stuff
11
+ sleep 0.2
12
+ send 0x18.chr # CAN Cancel
13
+ send @node.auth[:username]
14
+ send "\t"
15
+ send @node.auth[:password]
16
+ send "\r"
17
+ ''
18
+ end
19
+
20
+ # Main menu, escape into Pre-cli-shell
21
+ expect /Switch Main Menu/ do
22
+ Oxidized.logger.send(:debug, "#{self.class.name}: Switch menu")
23
+ send 0x1a.chr # SUB Substitite ^z
24
+ ''
25
+ end
26
+
27
+ # Pre-cli-shell, start lcli which is ios-ish
28
+ expect />/ do
29
+ Oxidized.logger.send(:debug, "#{self.class.name}: >")
30
+ send "lcli\r"
31
+ ''
32
+ end
33
+
34
+ cmd :all do |cfg|
35
+ # Remove \r from first response row
36
+ cfg.gsub! /^\r/, ''
37
+ cfg.cut_tail + "\n"
38
+ end
39
+
40
+ cmd :secret do |cfg|
41
+ cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
42
+ cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>'
43
+ end
44
+
45
+ cmd 'show startup-config' do |cfg|
46
+ # Repair some linewraps which terminal datadump doesn't take care of
47
+ # and there's no terminal width either.
48
+ cfg.gsub! /(lldpPortConfigT)\n(LVsTxEnable)/, '\\1\\2'
49
+ cfg.gsub! /(lldpPortConfigTL)\n(VsTxEnable)/, '\\1\\2'
50
+ # And comment out the echo of the command
51
+ "#{comment cfg.lines.first}#{cfg.cut_head}"
52
+ end
53
+
54
+ cmd 'show version' do |cfg|
55
+ comment cfg
56
+ end
57
+
58
+ cmd 'show system' do |cfg|
59
+ cfg.gsub! /(System Up Time \(days,hour:min:sec\):\s+).*/, '\\1 <uptime removed>'
60
+ comment cfg
61
+ end
62
+
63
+ cfg :telnet, :ssh do
64
+ # Some pre-cli-shell just expects a username, who its going to log in.
65
+ username /^User Name:/
66
+ password /Password:/
67
+ post_login 'terminal datadump'
68
+ pre_logout 'exit'
69
+ pre_logout 'logout'
70
+ end
71
+ end
@@ -10,7 +10,9 @@ class MLNXOS < Oxidized::Model
10
10
 
11
11
  cmd :all do |cfg|
12
12
  cfg.gsub! /\[\?1h=\r/, '' # Pager Handling
13
+ cfg.gsub! /\[24;1H/, '' # Pager Handling
13
14
  cfg.gsub! /\r\[K/, '' # Pager Handling
15
+ cfg.gsub! /\[K/, '' # Pager Handling
14
16
  cfg.gsub! /\s/, '' # Linebreak Handling
15
17
  cfg.gsub! /^CPU load averages:\s.+/, '' # Omit constantly changing CPU info
16
18
  cfg.gsub! /^System memory:\s.+/, '' # Omit constantly changing memory info
@@ -7,6 +7,7 @@ module Oxidized
7
7
 
8
8
  class << self
9
9
  def inherited(klass)
10
+ super
10
11
  if klass.superclass == Oxidized::Model
11
12
  klass.instance_variable_set '@cmd', (Hash.new { |h, k| h[k] = [] })
12
13
  klass.instance_variable_set '@cfg', (Hash.new { |h, k| h[k] = [] })
@@ -16,7 +17,9 @@ module Oxidized
16
17
  klass.instance_variable_set '@prompt', nil
17
18
  else # we're subclassing some existing model, take its variables
18
19
  instance_variables.each do |var|
19
- klass.instance_variable_set var, instance_variable_get(var)
20
+ iv = instance_variable_get(var)
21
+ klass.instance_variable_set var, iv.dup
22
+ @cmd[:cmd] = iv[:cmd].dup if var.to_s == "@cmd"
20
23
  end
21
24
  end
22
25
  end
@@ -46,7 +49,7 @@ module Oxidized
46
49
  end
47
50
 
48
51
  def cmd(cmd_arg = nil, **args, &block)
49
- if cmd_arg.class == Symbol
52
+ if cmd_arg.instance_of?(Symbol)
50
53
  process_args_block(@cmd[cmd_arg], args, block)
51
54
  else
52
55
  process_args_block(@cmd[:cmd], args, [cmd_arg, block])
@@ -97,7 +100,12 @@ module Oxidized
97
100
 
98
101
  def process_args_block(target, args, block)
99
102
  if args[:clear]
100
- target.replace([block])
103
+ if block.instance_of?(Array)
104
+ target.reject! { |k, _| k == block[0] }
105
+ target.push(block)
106
+ else
107
+ target.replace([block])
108
+ end
101
109
  else
102
110
  method = args[:prepend] ? :unshift : :push
103
111
  target.send(method, block)
@@ -181,6 +189,24 @@ module Oxidized
181
189
  data
182
190
  end
183
191
 
192
+ def xmlcomment(str)
193
+ # XML Comments start with <!-- and end with -->
194
+ #
195
+ # Because it's illegal for the first or last characters of a comment
196
+ # to be a -, i.e. <!--- or ---> are illegal, and also to improve
197
+ # readability, we add extra spaces after and before the beginning
198
+ # and end of comment markers.
199
+ #
200
+ # Also, XML Comments must not contain --. So we put a space between
201
+ # any double hyphens, by replacing any - that is followed by another -
202
+ # with '- '
203
+ data = ''
204
+ str.each_line do |_line|
205
+ data << '<!-- ' << str.gsub(/-(?=-)/, '- ').chomp << " -->\n"
206
+ end
207
+ data
208
+ end
209
+
184
210
  def screenscrape
185
211
  @input.class.to_s.match(/Telnet/) || vars(:ssh_no_exec)
186
212
  end
@@ -0,0 +1,30 @@
1
+ class NecIX < Oxidized::Model
2
+ prompt /^(\([\w.-]*\)\s[#$]|^\S+[$#]\s?)$/
3
+ comment '! '
4
+ expect /^--More--$/ do |data, re|
5
+ send ' '
6
+ data.sub re, ''
7
+ end
8
+
9
+ cmd 'show running-config' do |cfg|
10
+ cfg = cfg.each_line.to_a[3..-2].join
11
+ cfg.gsub! /^.*Current time.*$/, ''
12
+ cfg
13
+ end
14
+
15
+ cfg :telnet do
16
+ username /^Username:/
17
+ password /^Password:/
18
+ end
19
+
20
+ cfg :telnet, :ssh do
21
+ post_login do
22
+ send "configure\n"
23
+ end
24
+
25
+ pre_logout do
26
+ send "\cZ"
27
+ send "exit\n"
28
+ end
29
+ end
30
+ end
@@ -5,7 +5,8 @@ class Netgear < Oxidized::Model
5
5
  cmd :secret do |cfg|
6
6
  cfg.gsub!(/password (\S+)/, 'password <hidden>')
7
7
  cfg.gsub!(/encrypted (\S+)/, 'encrypted <hidden>')
8
- cfg.gsub!(/snmp-server community (\S+)/, 'snmp-server community <hidden>') # snmp
8
+ cfg.gsub!(/snmp-server community (\S+)$/, 'snmp-server community <hidden>')
9
+ cfg.gsub!(/snmp-server community (\S+) (\S+) (\S+)/, 'snmp-server community \\1 \\2 <hidden>')
9
10
  cfg
10
11
  end
11
12
 
@@ -29,7 +30,9 @@ class Netgear < Oxidized::Model
29
30
  # The system has unsaved changes.
30
31
  # Would you like to save them now? (y/n)
31
32
  #
32
- # So it is safer simply to disconnect and not issue a pre_logout command
33
+ # As no changes will be made over this simple SSH session, we can safely choose "n" here.
34
+ pre_logout 'quit'
35
+ pre_logout 'n'
33
36
  end
34
37
 
35
38
  cmd :all do |cfg, cmdstring|