oxidized 0.29.1 → 0.37.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 (236) hide show
  1. checksums.yaml +4 -4
  2. data/.coderabbit.yaml +21 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +45 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  5. data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
  6. data/.github/workflows/codeql.yml +4 -4
  7. data/.github/workflows/publishdocker.yml +108 -13
  8. data/.github/workflows/ruby.yml +3 -12
  9. data/.github/workflows/stale.yml +6 -1
  10. data/.gitignore +2 -0
  11. data/.rubocop.yml +69 -13
  12. data/.rubocop_todo.yml +13 -143
  13. data/CHANGELOG.md +431 -4
  14. data/CONTRIBUTING.md +189 -0
  15. data/Dockerfile +89 -34
  16. data/README.md +59 -188
  17. data/Rakefile +58 -12
  18. data/bin/oxidized +2 -5
  19. data/docs/Configuration.md +382 -149
  20. data/docs/Creating-Models.md +262 -10
  21. data/docs/DeviceSimulation.md +196 -0
  22. data/docs/Docker.md +246 -0
  23. data/docs/Hooks.md +146 -51
  24. data/docs/Inputs.md +237 -0
  25. data/docs/Issues.md +123 -0
  26. data/docs/Model-Notes/APC.md +72 -0
  27. data/docs/Model-Notes/Cumulus.md +5 -0
  28. data/docs/Model-Notes/EatonNetwork.md +18 -0
  29. data/docs/Model-Notes/ExaLink.md +43 -0
  30. data/docs/Model-Notes/FSOS.md +17 -0
  31. data/docs/Model-Notes/Fortinet.md +75 -0
  32. data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
  33. data/docs/Model-Notes/HPEAruba.md +32 -0
  34. data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
  35. data/docs/Model-Notes/OS6.md +10 -0
  36. data/docs/Model-Notes/README.md +1 -20
  37. data/docs/Model-Notes/RouterOS.md +28 -0
  38. data/docs/Model-Notes/SikluMHTG.md +7 -0
  39. data/docs/Model-Notes/TrueNAS.md +23 -0
  40. data/docs/Model-Notes/XGS4600-Zyxel.md +5 -0
  41. data/docs/ModelUnitTests.md +219 -0
  42. data/docs/Outputs.md +102 -5
  43. data/docs/Release.md +102 -0
  44. data/docs/Ruby-API.md +135 -2
  45. data/docs/Sources.md +34 -0
  46. data/docs/Supported-OS-Types.md +207 -270
  47. data/docs/Troubleshooting.md +43 -1
  48. data/extra/device2yaml.rb +259 -0
  49. data/extra/gitdiff-msteams.sh +32 -5
  50. data/extra/hooks/modelrules.rb +55 -0
  51. data/extra/hooks/modelrulesadvanced.rb +167 -0
  52. data/extra/hooks/srcipmap.rb +54 -0
  53. data/extra/nagios_check_failing_nodes.rb +1 -1
  54. data/extra/oxidized.runit +1 -1
  55. data/extra/rest_client.rb +5 -4
  56. data/extra/syslog.rb +11 -6
  57. data/lib/oxidized/cli/support.rb +152 -0
  58. data/lib/oxidized/cli.rb +21 -6
  59. data/lib/oxidized/config/vars.rb +33 -14
  60. data/lib/oxidized/config.rb +28 -17
  61. data/lib/oxidized/core.rb +50 -8
  62. data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
  63. data/lib/oxidized/hook/exec.rb +5 -4
  64. data/lib/oxidized/hook/githubrepo.rb +55 -18
  65. data/lib/oxidized/hook/noophook.rb +2 -2
  66. data/lib/oxidized/hook/slackdiff.rb +50 -14
  67. data/lib/oxidized/hook/xmppdiff.rb +9 -9
  68. data/lib/oxidized/hook.rb +68 -16
  69. data/lib/oxidized/input/cli.rb +8 -3
  70. data/lib/oxidized/input/debugtext.rb +40 -0
  71. data/lib/oxidized/input/debugyaml.rb +82 -0
  72. data/lib/oxidized/input/exec.rb +2 -11
  73. data/lib/oxidized/input/ftp.rb +2 -19
  74. data/lib/oxidized/input/http.rb +67 -17
  75. data/lib/oxidized/input/input.rb +35 -14
  76. data/lib/oxidized/input/scp.rb +27 -0
  77. data/lib/oxidized/input/ssh.rb +59 -83
  78. data/lib/oxidized/input/sshbase.rb +102 -0
  79. data/lib/oxidized/input/telnet.rb +20 -19
  80. data/lib/oxidized/input/tftp.rb +8 -8
  81. data/lib/oxidized/job.rb +18 -7
  82. data/lib/oxidized/jobs.rb +11 -1
  83. data/lib/oxidized/logger.rb +51 -0
  84. data/lib/oxidized/manager.rb +18 -17
  85. data/lib/oxidized/model/acos.rb +2 -1
  86. data/lib/oxidized/model/addpack.rb +26 -0
  87. data/lib/oxidized/model/adtran.rb +5 -1
  88. data/lib/oxidized/model/adva.rb +3 -3
  89. data/lib/oxidized/model/airfiber.rb +1 -1
  90. data/lib/oxidized/model/aos7.rb +11 -0
  91. data/lib/oxidized/model/aoscx.rb +37 -29
  92. data/lib/oxidized/model/aosw.rb +39 -29
  93. data/lib/oxidized/model/apc_aos.rb +7 -2
  94. data/lib/oxidized/model/apcaos.rb +39 -0
  95. data/lib/oxidized/model/aricentiss.rb +9 -2
  96. data/lib/oxidized/model/arubainstant.rb +93 -0
  97. data/lib/oxidized/model/asa.rb +11 -10
  98. data/lib/oxidized/model/asternos.rb +22 -0
  99. data/lib/oxidized/model/asyncos.rb +3 -3
  100. data/lib/oxidized/model/audiocodes.rb +2 -2
  101. data/lib/oxidized/model/awplus.rb +15 -12
  102. data/lib/oxidized/model/axos.rb +1 -1
  103. data/lib/oxidized/model/bdcom.rb +1 -0
  104. data/lib/oxidized/model/c4cmts.rb +1 -2
  105. data/lib/oxidized/model/ciscosma.rb +1 -1
  106. data/lib/oxidized/model/ciscosmb.rb +6 -1
  107. data/lib/oxidized/model/cnos.rb +13 -10
  108. data/lib/oxidized/model/comtrol.rb +1 -1
  109. data/lib/oxidized/model/comware.rb +5 -3
  110. data/lib/oxidized/model/cumulus.rb +14 -2
  111. data/lib/oxidized/model/defacto.rb +26 -0
  112. data/lib/oxidized/model/dellx.rb +1 -1
  113. data/lib/oxidized/model/dlink.rb +5 -2
  114. data/lib/oxidized/model/dlinknextgen.rb +55 -0
  115. data/lib/oxidized/model/dnos.rb +3 -0
  116. data/lib/oxidized/model/dslcommands.rb +93 -0
  117. data/lib/oxidized/model/dslsetup.rb +102 -0
  118. data/lib/oxidized/model/eatonnetwork.rb +70 -0
  119. data/lib/oxidized/model/edgecos.rb +3 -1
  120. data/lib/oxidized/model/edgeos.rb +7 -6
  121. data/lib/oxidized/model/edgeswitch.rb +3 -1
  122. data/lib/oxidized/model/efos.rb +41 -0
  123. data/lib/oxidized/model/eltex.rb +4 -2
  124. data/lib/oxidized/model/enterasys800.rb +2 -2
  125. data/lib/oxidized/model/enterprise_sonic.rb +46 -0
  126. data/lib/oxidized/model/eos.rb +3 -1
  127. data/lib/oxidized/model/exalink.rb +36 -0
  128. data/lib/oxidized/model/f5os.rb +17 -0
  129. data/lib/oxidized/model/fabricos.rb +2 -2
  130. data/lib/oxidized/model/fastiron.rb +5 -3
  131. data/lib/oxidized/model/firebrick.rb +2 -2
  132. data/lib/oxidized/model/firelinuxos.rb +13 -6
  133. data/lib/oxidized/model/firewareos.rb +10 -1
  134. data/lib/oxidized/model/fortigate.rb +160 -0
  135. data/lib/oxidized/model/fortios.rb +38 -48
  136. data/lib/oxidized/model/fsos.rb +46 -0
  137. data/lib/oxidized/model/gaiaos.rb +4 -4
  138. data/lib/oxidized/model/garderos.rb +38 -0
  139. data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
  140. data/lib/oxidized/model/h3c.rb +1 -1
  141. data/lib/oxidized/model/ibos.rb +1 -0
  142. data/lib/oxidized/model/ingate.rb +47 -0
  143. data/lib/oxidized/model/ios.rb +57 -30
  144. data/lib/oxidized/model/iosxr.rb +2 -2
  145. data/lib/oxidized/model/ironware.rb +7 -5
  146. data/lib/oxidized/model/ivanti.rb +54 -0
  147. data/lib/oxidized/model/junos.rb +12 -5
  148. data/lib/oxidized/model/kornfeldos.rb +33 -0
  149. data/lib/oxidized/model/lenovonos.rb +2 -0
  150. data/lib/oxidized/model/linksyssrw.rb +3 -3
  151. data/lib/oxidized/model/linuxgeneric.rb +4 -2
  152. data/lib/oxidized/model/macros.rb +60 -0
  153. data/lib/oxidized/model/mimosab11.rb +34 -0
  154. data/lib/oxidized/model/ml66.rb +33 -0
  155. data/lib/oxidized/model/mlnxos.rb +18 -14
  156. data/lib/oxidized/model/model.rb +98 -103
  157. data/lib/oxidized/model/mtrlrfs.rb +1 -0
  158. data/lib/oxidized/model/ndms.rb +6 -0
  159. data/lib/oxidized/model/netgear.rb +14 -3
  160. data/lib/oxidized/model/netonix.rb +1 -1
  161. data/lib/oxidized/model/netscaler.rb +1 -1
  162. data/lib/oxidized/model/nodegrid.rb +1 -1
  163. data/lib/oxidized/model/nsxdfw.rb +31 -0
  164. data/lib/oxidized/model/nsxfirewall.rb +2 -1
  165. data/lib/oxidized/model/nxos.rb +20 -15
  166. data/lib/oxidized/model/ocnos.rb +42 -0
  167. data/lib/oxidized/model/onefinity.rb +18 -0
  168. data/lib/oxidized/model/openbsd.rb +1 -1
  169. data/lib/oxidized/model/opengear.rb +36 -1
  170. data/lib/oxidized/model/openwrt.rb +6 -6
  171. data/lib/oxidized/model/opnsense.rb +9 -1
  172. data/lib/oxidized/model/os6.rb +48 -0
  173. data/lib/oxidized/model/outputs.rb +5 -0
  174. data/lib/oxidized/model/panos.rb +2 -0
  175. data/lib/oxidized/model/perle.rb +41 -0
  176. data/lib/oxidized/model/pfsense.rb +9 -0
  177. data/lib/oxidized/model/powerconnect.rb +32 -11
  178. data/lib/oxidized/model/procurve.rb +6 -2
  179. data/lib/oxidized/model/qtech.rb +3 -1
  180. data/lib/oxidized/model/quantaos.rb +8 -6
  181. data/lib/oxidized/model/rgos.rb +33 -0
  182. data/lib/oxidized/model/riverbed.rb +104 -0
  183. data/lib/oxidized/model/routeros.rb +18 -11
  184. data/lib/oxidized/model/saos.rb +18 -1
  185. data/lib/oxidized/model/saos10.rb +38 -0
  186. data/lib/oxidized/model/siklu.rb +1 -1
  187. data/lib/oxidized/model/siklumhtg.rb +22 -0
  188. data/lib/oxidized/model/sixwind.rb +28 -0
  189. data/lib/oxidized/model/slxos.rb +3 -3
  190. data/lib/oxidized/model/smartbyte.rb +48 -0
  191. data/lib/oxidized/model/sonicos.rb +27 -20
  192. data/lib/oxidized/model/speedtouch.rb +1 -1
  193. data/lib/oxidized/model/sros.rb +3 -3
  194. data/lib/oxidized/model/srosmd.rb +1 -1
  195. data/lib/oxidized/model/supermicro.rb +1 -1
  196. data/lib/oxidized/model/telco.rb +1 -1
  197. data/lib/oxidized/model/tmos.rb +1 -0
  198. data/lib/oxidized/model/tnsr.rb +57 -0
  199. data/lib/oxidized/model/tplink.rb +5 -5
  200. data/lib/oxidized/model/trango.rb +4 -2
  201. data/lib/oxidized/model/truenas.rb +64 -3
  202. data/lib/oxidized/model/ucs.rb +1 -1
  203. data/lib/oxidized/model/unifiap.rb +144 -0
  204. data/lib/oxidized/model/uplinkolt.rb +46 -0
  205. data/lib/oxidized/model/voltaire.rb +1 -1
  206. data/lib/oxidized/model/voss.rb +3 -0
  207. data/lib/oxidized/model/vrp.rb +5 -1
  208. data/lib/oxidized/model/vyatta.rb +9 -3
  209. data/lib/oxidized/model/vyos.rb +37 -0
  210. data/lib/oxidized/model/xos.rb +10 -1
  211. data/lib/oxidized/model/zhoneolt.rb +4 -2
  212. data/lib/oxidized/model/zynos.rb +67 -3
  213. data/lib/oxidized/model/zynosadsl.rb +14 -0
  214. data/lib/oxidized/model/zynoscli.rb +1 -1
  215. data/lib/oxidized/model/zynosgs.rb +2 -0
  216. data/lib/oxidized/model/zynosmgs.rb +32 -0
  217. data/lib/oxidized/node.rb +99 -64
  218. data/lib/oxidized/nodes.rb +40 -19
  219. data/lib/oxidized/output/file.rb +80 -43
  220. data/lib/oxidized/output/git.rb +295 -151
  221. data/lib/oxidized/output/gitcrypt.rb +193 -185
  222. data/lib/oxidized/output/http.rb +63 -51
  223. data/lib/oxidized/output/output.rb +20 -4
  224. data/lib/oxidized/signals.rb +44 -0
  225. data/lib/oxidized/source/csv.rb +49 -49
  226. data/lib/oxidized/source/http.rb +76 -63
  227. data/lib/oxidized/source/jsonfile.rb +68 -0
  228. data/lib/oxidized/source/source.rb +73 -18
  229. data/lib/oxidized/source/sql.rb +71 -59
  230. data/lib/oxidized/version.rb +6 -4
  231. data/lib/oxidized/worker.rb +57 -29
  232. data/lib/oxidized.rb +4 -24
  233. data/lib/refinements.rb +21 -1
  234. data/oxidized.gemspec +45 -21
  235. metadata +248 -41
  236. data/lib/oxidized/model/timos.rb +0 -10
@@ -0,0 +1,48 @@
1
+ class SmartByte < Oxidized::Model
2
+ using Refinements
3
+
4
+ comment '! '
5
+
6
+ cmd :secret do |cfg|
7
+ cfg.gsub!(/group (\S+) v2c/, 'group <hidden> v2c')
8
+ cfg.gsub!(/community (\S+)/, 'community <hidden>')
9
+ cfg
10
+ end
11
+
12
+ cmd :all do |cfg|
13
+ cfg = cfg.delete("\r")
14
+ cfg.cut_tail
15
+ end
16
+
17
+ cmd 'show running-config'
18
+
19
+ cmd 'show version' do |cfg|
20
+ comment cfg
21
+ end
22
+
23
+ cmd 'show interface optical-transceiver info' do |cfg|
24
+ cfg.gsub! /^\|Transceiver current alarm information: \|\s+\+-------------------------------------------------\+.*?\s+\+-------------------------------------------------\+\s+/m, ''
25
+ comment cfg
26
+ end
27
+
28
+ cmd 'show power' do |cfg|
29
+ comment cfg
30
+ end
31
+
32
+ cfg :telnet do
33
+ username /^.*? login:/
34
+ password /^Password:/
35
+ end
36
+
37
+ cfg :telnet, :ssh do
38
+ post_login do
39
+ if vars(:enable)
40
+ cmd "enable", /^[pP]assword:/
41
+ cmd vars(:enable)
42
+ end
43
+ end
44
+
45
+ post_login 'terminal length 0'
46
+ pre_logout 'exit'
47
+ end
48
+ end
@@ -3,28 +3,35 @@ class SonicOS < Oxidized::Model
3
3
 
4
4
  # Applies to Sonicwall NSA series firewalls
5
5
 
6
- prompt /^\w+@\w+[>]\(?.+\)?\s?/
7
- comment '! '
6
+ prompt /^\w+@[\w-]+>\(?.+\)?\s?/
7
+ comment '! '
8
+
9
+ # Accept policiy message (see Issue #3339). Tested on 6.5 and 7.1
10
+ expect /Accept The Policy Banner \(yes\)\?\r\nyes: $/ do |data, re|
11
+ send "yes\n"
12
+ data.sub re, ''
13
+ end
8
14
 
9
15
  cmd :all do |cfg|
10
16
  cfg.each_line.to_a[1..-2].join
11
17
  end
12
18
 
13
19
  cmd :secret do |cfg|
14
- cfg.gsub! /cli ftp password default \d\,(\S+)/, 'cli ftp password default <secret hidden> \2'
15
- cfg.gsub! /secret \d\,(\S+)/, 'secret <secret hidden> \2'
16
- cfg.gsub! /shared-secret \d\,(\S+)/, 'shared-secret <secret hidden> \2'
17
- cfg.gsub! /password \d\,(\S+)/, 'password <secret hidden> \2'
18
- cfg.gsub! /passphrase password \d\,(\S+)/, 'passphrase password <secret hidden> \2'
19
- cfg.gsub! /bind-password \d\,(\S+)/, 'bind-password <secret hidden> \2'
20
- cfg.gsub! /authentication sha1 \d\,(\S+)/, 'authentication sha1 <secret hidden> \2'
21
- cfg.gsub! /encryption aes \d\,(\S+)/, 'encryption aes <secret hidden> \2'
22
- cfg.gsub! /smtp-pass \d\,(\S+)/, 'smtp-pass <secret hidden> \2'
23
- cfg.gsub! /pop-pass \d\,(\S+)/, 'pop-pass <secret hidden> \2'
24
- cfg.gsub! /sslvpn password \d\,(\S+)/, 'sslvpn password <secret hidden> \2'
25
- cfg.gsub! /administrator password \d\,(\S+)/, 'administrator password <secret hidden> \2'
26
- cfg.gsub! /ftp password \d\,(\S+)/, 'ftp password <secret hidden> \2'
27
- cfg.gsub! /shared-key \d\,(\S+)/, 'shared-key <secret hidden> \2'
20
+ cfg.gsub! /cli ftp password default \d,(\S+)/, 'cli ftp password default <secret hidden> \2'
21
+ cfg.gsub! /secret \d,(\S+)/, 'secret <secret hidden> \2'
22
+ cfg.gsub! /shared-secret \d,(\S+)/, 'shared-secret <secret hidden> \2'
23
+ cfg.gsub! /password \d,(\S+)/, 'password <secret hidden> \2'
24
+ cfg.gsub! /passphrase password \d,(\S+)/, 'passphrase password <secret hidden> \2'
25
+ cfg.gsub! /bind-password \d,(\S+)/, 'bind-password <secret hidden> \2'
26
+ cfg.gsub! /authentication sha1 \d,(\S+)/, 'authentication sha1 <secret hidden> \2'
27
+ cfg.gsub! /encryption aes \d,(\S+)/, 'encryption aes <secret hidden> \2'
28
+ cfg.gsub! /smtp-pass \d,(\S+)/, 'smtp-pass <secret hidden> \2'
29
+ cfg.gsub! /pop-pass \d,(\S+)/, 'pop-pass <secret hidden> \2'
30
+ cfg.gsub! /sslvpn password \d,(\S+)/, 'sslvpn password <secret hidden> \2'
31
+ cfg.gsub! /administrator password \d,(\S+)/, 'administrator password <secret hidden> \2'
32
+ cfg.gsub! /ftp password \d,(\S+)/, 'ftp password <secret hidden> \2'
33
+ cfg.gsub! /shared-key \d,(\S+)/, 'shared-key <secret hidden> \2'
34
+ cfg.gsub! /wpa passphrase \d,(\S+)/, 'wpa passphrase <secret hidden> \2'
28
35
  cfg
29
36
  end
30
37
 
@@ -46,10 +53,10 @@ class SonicOS < Oxidized::Model
46
53
  def clean(cfg)
47
54
  out = []
48
55
  cfg.each_line do |line|
49
- next if line =~ /date \d{4}\:\d{2}\:\d{2}/
50
- next if line =~ /time \d{2}\:\d{2}:\d{2}/
51
- next if line =~ /system-time \"\d{2}\/\d{2}\/\d{4} \d{2}\:\d{2}:\d{2}.\d+\"/
52
- next if line =~ /system-uptime "((\s+up\s+\d+\s+)|(\d+\s\w+(,\s)?)*)"/
56
+ next if line =~ /date \d{4}:\d{2}:\d{2}/
57
+ next if line =~ /time \d{2}:\d{2}:\d{2}/
58
+ next if line =~ /system-time "\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}.\d+"/
59
+ next if line =~ /system-uptime "(?:\s+up\s+\d+\s+|\d+ \w+(?:, \d+ \w+)*)"/
53
60
  next if line =~ /checksum \d+/
54
61
 
55
62
  line = line[1..-1] if line[0] == "\r"
@@ -1,7 +1,7 @@
1
1
  class SpeedTouch < Oxidized::Model
2
2
  using Refinements
3
3
 
4
- prompt /([\w{}=]+[>])$/
4
+ prompt /([\w{}=]+>)$/
5
5
  comment '! '
6
6
 
7
7
  expect /login$/ do
@@ -32,7 +32,7 @@ class SROS < Oxidized::Model
32
32
  #
33
33
  # Strip uptime.
34
34
  #
35
- cfg.sub! /^System Up Time.*\n/, ''
35
+ cfg.gsub! /^System Up Time.*$/, ''
36
36
  comment cfg
37
37
  end
38
38
 
@@ -75,14 +75,14 @@ class SROS < Oxidized::Model
75
75
  #
76
76
  # Show the running persistent indices.
77
77
  #
78
- cmd 'admin display-config index' do |cfg|
78
+ cmd "admin display-config index\n" do |cfg|
79
79
  comment cfg
80
80
  end
81
81
 
82
82
  #
83
83
  # Show the running configuration.
84
84
  #
85
- cmd 'admin display-config' do |cfg|
85
+ cmd "admin display-config\n" do |cfg|
86
86
  cfg
87
87
  end
88
88
 
@@ -26,7 +26,7 @@ class SROSMD < Oxidized::Model
26
26
  #
27
27
  # Strip uptime.
28
28
  #
29
- cfg.sub! /^System Up Time.*\n/, ''
29
+ cfg.gsub! /^System Up Time.*\n/, ''
30
30
  comment cfg
31
31
  end
32
32
 
@@ -5,6 +5,6 @@ require_relative 'edgecos'
5
5
 
6
6
  Supermicro = EdgeCOS
7
7
 
8
- Oxidized.logger.warn "Using deprecated model supermicro, use edgecos instead."
8
+ logger.warn "Using deprecated model supermicro, use edgecos instead."
9
9
 
10
10
  # Deprecated
@@ -3,7 +3,7 @@ class TELCO < Oxidized::Model
3
3
 
4
4
  # Telco Systems T-Marc 3306
5
5
 
6
- prompt /^(\r?[\w.@_()-]+[#]\s?)$/
6
+ prompt /^(\r?[\w.@_()-]+\#\s?)$/
7
7
  comment '! '
8
8
 
9
9
  cmd :all do |cfg|
@@ -32,6 +32,7 @@ class TMOS < Oxidized::Model
32
32
  cfg.gsub!(/^\s+bandwidth-bps (\d+)/, '')
33
33
  cfg.gsub!(/^\s+bandwidth-cps (\d+)/, '')
34
34
  cfg.gsub!(/^\s+bandwidth-pps (\d+)\n/, '')
35
+ cfg.gsub!(/^\s*\S*encrypted \S+\n/, '')
35
36
  cfg
36
37
  end
37
38
 
@@ -0,0 +1,57 @@
1
+ class TNSR < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Netgate TNSR #
5
+
6
+ # prompt examples
7
+ # https://docs.netgate.com/tnsr/en/latest/basics/working-cli.html#command-prompt
8
+ # "<hostname> tnsr<(mode)># " <-- with trailing whitespace
9
+ # tnsr-dev-25-02 tnsr#
10
+ # tnsr-dev-25-02 tnsr(config)# <-- after "configure terminal", but this is not important for oxidized
11
+ # prompt from debug log
12
+ # received "Welcome to Netgate TNSR Version: 25.02-2\r\n\r\n\t* Documentation: https://docs.netgate.com/tnsr/en/latest/\r\n\t* Support: https://www.netgate.com/support\r\n\r\n _ __________\r\n _| |_ _ __ | ___ _ __ |\r\n|_ __| '_ \\ |/ __| '__||\r\n | |_| | | ||\\__ \\ | |\r\n \\__|_| |_|||___/_| |\r\n |__________|\r\n\r\n\r\n"
13
+ # received "\r\nVersion: 25.02-2\r\n\r\nFor information see 'show documentation'\r\n\r\n"
14
+ # received "\rbgp01 tnsr# "
15
+ # when the --More-- pager is the last line of paged output, the prompt contains \x08\x20\x08 orphans on the begin
16
+ # on older version (23.06) --More-- pager is sometimes misplaced
17
+ # you can look for context into spec simulation:
18
+ # spec/model/data/tnsr#TNSR_24.10-3_short-config#simulation.yaml
19
+ # spec/model/data/tnsr#TNSR_25.02-2_long-config-and-pager-at-last-line#simulation.yaml
20
+ # spec/model/data/tnsr#TNSR_23.06-3_with-misplaced-pager#simulation.yaml
21
+ prompt /^((\x08{8}\x20{8}\x08{8})?\r?[\w-]+\stnsr#\s?)$/
22
+
23
+ comment '! '
24
+
25
+ expect /^--More--|--More--$/ do |data, re|
26
+ send ' '
27
+ data.sub re, ''
28
+ end
29
+
30
+ cmd :all do |cfg|
31
+ # remove orphans \r
32
+ cfg.gsub! /^\r+(.+)/, '\1'
33
+ # handle pager orphans ^H^H^H^H^H^H^H^H ^H^H^H^H^H^H^H^H
34
+ cfg.gsub! /\x08{8}\x20{8}\x08{8}/, ''
35
+ cfg.cut_both
36
+ end
37
+
38
+ cmd :secret do |cfg|
39
+ cfg.gsub! /(password( \d+)?) (\S+).*/, '\\1 <secret hidden>'
40
+ cfg.gsub! /^(snmp community community-name )\S+ (.*)?/, '\\1 <configuration removed> \\2'
41
+ cfg
42
+ end
43
+
44
+ cmd 'show version all' do |cfg|
45
+ # for older tnsr versions
46
+ cfg = cmd('show version') if cfg.to_s =~ /^CLI syntax error:.+Unknown command$/
47
+ comment cfg
48
+ end
49
+
50
+ cmd 'show configuration running cli' do |cfg|
51
+ cfg
52
+ end
53
+
54
+ cfg :telnet, :ssh do
55
+ pre_logout 'exit'
56
+ end
57
+ end
@@ -48,17 +48,17 @@ class TPLink < Oxidized::Model
48
48
  lines[0..lines.index("end\n")].join
49
49
  end
50
50
 
51
+ macro :enable, regex: /^[pP]assword:/
52
+
51
53
  cfg :telnet, :ssh do
52
54
  username /^User ?[nN]ame:/
53
55
  password /^\r?Password:/
56
+ newline "\r\n"
54
57
  end
55
58
 
56
59
  cfg :telnet, :ssh do
57
- if vars :enable
58
- post_login do
59
- send "enable\r"
60
- cmd vars(:enable)
61
- end
60
+ post_login do
61
+ cmd 'terminal length 0'
62
62
  end
63
63
 
64
64
  pre_logout do
@@ -14,11 +14,13 @@ class Trango < Oxidized::Model
14
14
  out << ("opmode " + Regexp.last_match[1])
15
15
  out << ("defaultopmode " + Regexp.last_match[2])
16
16
  end
17
- out << ("power " + Regexp.last_match[1]) if line =~ /\[Tx Power\] ([\-\d]+) dBm/
17
+ out << ("power " + Regexp.last_match[1]) if line =~ /\[Tx Power\] ([-\d]+) dBm/
18
18
  out << ("freq " + Regexp.last_match[1] + ' ' + Regexp.last_match[2]) if line =~ /\[Active Channel\] (\d+) (v|h)/
19
19
  out << ("peerid " + Regexp.last_match[1]) if line =~ /\[Peer ID\] ([A-F0-9]+)/
20
20
  out << ("utype " + Regexp.last_match[1]) if line =~ /\[Unit Type\] (\S+)/
21
- comments << ('# ' + Regexp.last_match[1] + ': ' + Regexp.last_match[2]) if line =~ /\[(Hardware Version|Firmware Version|Model|S\/N)\] (\S+)/
21
+ if line =~ /\[(Hardware Version|Firmware Version|Model|S\/N)\] (\S+)/
22
+ comments << ('# ' + Regexp.last_match[1] + ': ' + Regexp.last_match[2])
23
+ end
22
24
  out << ("remarks " + Regexp.last_match[1]) if line =~ /\[Remarks\] (\S+)/
23
25
  out << ("rssiled " + Regexp.last_match[1]) if line =~ /\[RSSI LED\] (on|off)/
24
26
  speed = Regexp.last_match[1] if line =~ /\[Speed\] (\d+) Mbps/
@@ -5,13 +5,74 @@ class TrueNAS < Oxidized::Model
5
5
 
6
6
  cmd('uname -a') { |cfg| comment cfg }
7
7
  cmd('cat /etc/version') { |cfg| comment cfg }
8
- cmd('sqlite3 "file:///data/freenas-v1.db?mode=ro&immutable=1" .dump') do |cfg|
8
+
9
+ # for TrueNAS SCALE machines, make sure the user you use to connect can run
10
+ # this command, or if needed, with passwordless sudo. Try putting this in
11
+ # /etc/sudoers
12
+ # oxidized ALL=(ALL) NOPASSWD: /usr/bin/find /mnt/.ix-apps/app_configs *, /usr/bin/sqlite3 -readonly file\:/data/freenas-v1.db *
13
+
14
+ cmd("sqlite3 -readonly 'file:/data/freenas-v1.db' .dump") do |cfg|
15
+ if cfg.include? "Error: unable to open database"
16
+ # retry with sudo
17
+ cfg = cmd("sudo sqlite3 -readonly 'file:/data/freenas-v1.db' .dump")
18
+ end
9
19
  cfg.lines.reject do |line|
10
- line.match(/^INSERT INTO storage_replication /) ||
11
- line.match(/^INSERT INTO system_alert /)
20
+ line.match(/^INSERT INTO storage_replication /) || # ignore storage_replication because repl_status field changes on every run
21
+ line.match(/^INSERT INTO system_alert /) || # ignore system alerts in db
22
+ line.match(/^INSERT INTO sqlite_sequence VALUES\('system_alert',/) || # ignore system alerts in db
23
+ line.match(/^INSERT INTO tasks_cloudsync /) # ignore cloudsync tasks because job field changes on every run
12
24
  end.join
13
25
  end
14
26
 
27
+ post do
28
+ filter_column("storage_replication", "repl_state")
29
+ end
30
+
31
+ post do
32
+ filter_column("tasks_cloudsync", "job")
33
+ end
34
+
35
+ post do
36
+ collect_ixapps_configurations
37
+ end
38
+
39
+ def filter_column(table_name, column_name)
40
+ sqlite_cmd = "sqlite3 -readonly 'file:/data/freenas-v1.db'"
41
+
42
+ # This SQL command will create a SELECT query with all columns except the one we want to skip.
43
+ generate_select_cmd = "select 'select ' || group_concat(name,', ') || ' FROM #{table_name};' FROM pragma_table_info('#{table_name}') WHERE name != '#{column_name}';"
44
+
45
+ select_stmt = cmd("#{sqlite_cmd} \"#{generate_select_cmd}\"")
46
+ if select_stmt.include? "Error: unable to open database"
47
+ # retry with sudo
48
+ sqlite_cmd = "sudo #{sqlite_cmd}"
49
+ select_stmt = cmd("#{sqlite_cmd} \"#{generate_select_cmd}\"")
50
+ end
51
+
52
+ insert_cmds = "-header '.mode insert #{table_name}' '#{select_stmt}'"
53
+ cmd("#{sqlite_cmd} #{insert_cmds}") do |cfg|
54
+ if cfg.include? "INSERT"
55
+ # Don't add a COMMIT; if the query came up with no rows
56
+ cfg + "COMMIT;\n"
57
+ end
58
+ end
59
+ end
60
+
61
+ def collect_ixapps_configurations
62
+ config_command = <<~'CMDEND'
63
+ if [ -d /mnt/.ix-apps ];
64
+ then
65
+ sudo find /mnt/.ix-apps/app_configs
66
+ \( -name "app.yaml" -or -name "user_config.yaml" -or -name "metadata.yaml" \)
67
+ -printf "\n\n#######################\n# %p\n#######################\n"
68
+ -exec cat {} \; ;
69
+ else
70
+ echo "# No Apps configuration found in /mnt/.ix-apps";
71
+ fi
72
+ CMDEND
73
+ cmd(config_command.gsub("\n", ""))
74
+ end
75
+
15
76
  cfg :ssh do
16
77
  exec true # don't run shell, run each command in exec channel
17
78
  end
@@ -1,7 +1,7 @@
1
1
  class UCS < Oxidized::Model
2
2
  using Refinements
3
3
 
4
- prompt /^(\r?[\w.@_()-]+[#]\s?)$/
4
+ prompt /^(\r?[\w.@_()-]+\#\s?)$/
5
5
  comment '! '
6
6
 
7
7
  cmd 'show version brief' do |cfg|
@@ -0,0 +1,144 @@
1
+ class Unifiap < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Ubiquiti Unifi AP circa 6.x
5
+ # Should also work for unfi switches, and airOS, maybe they could be combined.
6
+ # Since it relies on exec channels, because the interactive session wouldn't
7
+ # capture all of the system.cfg output, you can't use telnet with this model.
8
+
9
+ # Sometimes there's a handy info command that summarizes some device attributes,
10
+ # but it doesn't seem to be available in exec mode. So we try to build up a similar
11
+ # list by extracting tidbits from various places. AirOS doesn't have some of these
12
+ # files, so we # may have to fall back on other commands, or locations.
13
+
14
+ # First get the board model
15
+ cmd 'head -4 /etc/board.info' do |cfg|
16
+ @model = Regexp.last_match(1) if cfg =~ /board\.name=(\S+)/i
17
+ ""
18
+ end
19
+
20
+ # and version
21
+ cmd 'cat /etc/version' do |cfg|
22
+ @version = Regexp.last_match(1) if cfg =~ /(\S+)$/i
23
+ ""
24
+ end
25
+
26
+ # Now the Mac address
27
+ cmd 'ifconfig eth0' do |cfg|
28
+ @mac = Regexp.last_match(1) if cfg =~ /eth0\s+Link encap:Ethernet\s+HWaddr\s+(\w+:\w+:\w+:\w+:\w+:\w+)/i
29
+ ""
30
+ end
31
+
32
+ # Next see if we can get our IP and host name out of /etc/hosts
33
+ cmd 'cat /etc/hosts' do |cfg|
34
+ cfg = cfg.split("\n").reject do |line|
35
+ line[/^\s*(127|0000:0000:0000:0000:0000:0000:0000:0001|0:0:0:0:0:0:0:1|::1)/]
36
+ end
37
+ cfg.select do |line|
38
+ if (match = line.match(/(\d+\.\d+\.\d+\.\d+)\s+(\S+)/))
39
+ @ip, @hostname = match.captures
40
+ end
41
+ end
42
+ ""
43
+ end
44
+
45
+ # We check here to see if we succeeded with /etc/hosts. If not, then we try again with ifconfig, and /tmp/system.cfg
46
+ cmd 'echo' do
47
+ unless @ip
48
+ cmd 'ifconfig br0' do |cfg|
49
+ @ip = Regexp.last_match(1) if cfg =~ /inet addr:\s*(\d+\.\d+\.\d+\.\d+)/i
50
+ end
51
+
52
+ unless @ip
53
+ cmd 'ifconfig eth0' do |cfg|
54
+ @ip = Regexp.last_match(1) if cfg =~ /inet addr:\s*(\d+\.\d+\.\d+\.\d+)/i
55
+ end
56
+ end
57
+ end
58
+
59
+ unless @hostname
60
+ cmd 'cat /tmp/system.cfg' do |cfg|
61
+ @hostname = Regexp.last_match(1) if cfg =~ /resolv.host.1.name=(\S+)/i
62
+ end
63
+ end
64
+ ""
65
+ end
66
+
67
+ # Check if ntpclient is running
68
+ cmd 'ps wwww' do |cfg|
69
+ @ntpserver = Regexp.last_match(1) if cfg =~ /bin\/ntpclient.+-h\s*(\S+)/i
70
+ ""
71
+ end
72
+
73
+ # If it's a Unifi device it may have NTP health indication
74
+ # If there are other places that Ubiquiti puts these status files, add them here.
75
+ cmd '[ -e /tmp/run/ntp.ready ] || [ -e /var/run/ntp.ready ] && echo "File(s) exist(s)" || echo "No such file"' do |cfg|
76
+ if cfg =~ /No such file/i
77
+ if @ntpserver
78
+ # Ok, now lets try getting the skew from the output of ntpclient
79
+ cmd "ntpclient -d -n -c 2 -i0 -h #{@ntpserver}" do |ntp_out|
80
+ @skew = ntpskew(ntp_out)
81
+ end
82
+ @sync = !@skew.nil? && @skew.to_f.abs < 1e6 ? "Synchronized" : "FAIL"
83
+ end
84
+ else
85
+ @ntpserver = true
86
+ @sync = "Synchronized"
87
+ end
88
+ ""
89
+ end
90
+
91
+ # Now we can display it all as a banner
92
+ cmd 'echo' do
93
+ out = []
94
+ out << "*************************"
95
+ out << "Model: #{@model}"
96
+ out << "Version: #{@version}"
97
+ out << "MAC Address: #{@mac}"
98
+ out << "IP Address: #{@ip}"
99
+ out << "Hostname: #{@hostname}"
100
+ out << "NTP: #{@sync}" if @ntpserver
101
+ out << "*************************"
102
+ comment out.join("\n") + "\n"
103
+ end
104
+
105
+ # Followed by the board info
106
+ cmd 'cat /etc/board.info' do |cfg|
107
+ cfg = "#\n# Board Info:\n#\n" + cfg
108
+ comment cfg
109
+ end
110
+
111
+ # Lastly the system config
112
+ cmd 'cat /tmp/system.cfg' do |cfg|
113
+ cfg = "#\n# System Config:\n#\n" + cfg
114
+ cfg + "\n"
115
+ end
116
+
117
+ cmd :secret do |cfg|
118
+ cfg.gsub! /^((?:users|snmp\.(?:user|community))\.\d+\.password)=.+/, "# \\1=<hidden>"
119
+ cfg
120
+ end
121
+
122
+ cfg :ssh do
123
+ exec true # Don't run shell, run each command in exec channel
124
+ end
125
+
126
+ # NTPskew: Return the skew in micro seconds from the ntpclient output
127
+ def ntpskew(cfg)
128
+ index = skew = nil
129
+
130
+ cfg.each_line do |line|
131
+ # Look for the header just before the stats line, and find which number is skew
132
+ if line.match(/^\s*[a-z]+\s+[a-z]+\s+[a-z]+\s+[a-z]+/i)
133
+ words = line.split
134
+ index = words.map(&:downcase).index("skew")
135
+ end
136
+ # Now look for the single stats line and grab the skew
137
+ if !index.nil? && line.match(/^\s*[\d.]+\s+[\d.]+\s+[\d.]+\s+[\d.]+/)
138
+ numbers = line.split
139
+ skew = numbers[index]
140
+ end
141
+ end
142
+ skew
143
+ end
144
+ end
@@ -0,0 +1,46 @@
1
+ class UPLINKOLT < Oxidized::Model
2
+ prompt /^([\w.@()-]+[#>]\s?)$/
3
+ comment '! '
4
+
5
+ cmd :all do |cfg|
6
+ cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
7
+ cfg.gsub!(/^show running-config$/, '')
8
+ cfg.gsub!(/^.*\s*#\s*$/, '')
9
+ # Remove leading and trailing whitespace
10
+ cfg.strip!
11
+ # Remove empty lines
12
+ cfg.gsub!(/^\s*$/, '')
13
+ cfg
14
+ end
15
+
16
+ cmd 'configure terminal' do
17
+ # Enter configure terminal mode
18
+ cmd 'show version' do |cfg|
19
+ cfg.gsub! /^show version/, ''
20
+ comment cfg
21
+ end
22
+ end
23
+
24
+ cmd 'show running-config' do |cfg|
25
+ cfg.gsub! /^Current configuration:/, ''
26
+ cfg
27
+ end
28
+
29
+ cfg :telnet, :ssh do
30
+ username /^Login:/i
31
+ password /^Password:/i
32
+ # preferred way to handle additional passwords
33
+ post_login do
34
+ if vars(:enable) == true
35
+ cmd "enable"
36
+ elsif vars(:enable)
37
+ cmd "enable", /^[pP]assword:/
38
+ cmd vars(:enable)
39
+ end
40
+ end
41
+ post_login 'terminal length 0'
42
+ pre_logout 'exit'
43
+ pre_logout 'disable'
44
+ pre_logout 'exit'
45
+ end
46
+ end
@@ -5,7 +5,7 @@ class VOLTAIRE < Oxidized::Model
5
5
  comment '## '
6
6
 
7
7
  # Pager Handling
8
- expect /.+lines\s\d+-\d+([\s]|\/\d+\s\(END\)\s).+$/ do |data, re|
8
+ expect /.+lines\s\d+-\d+(\s|\/\d+\s\(END\)\s).+$/ do |data, re|
9
9
  send ' '
10
10
  data.sub re, ''
11
11
  end
@@ -23,6 +23,9 @@ class Voss < Oxidized::Model
23
23
  cfg.gsub! /(^((.*)Last Vlan Change(.*):(.*))$)/, 'removed Last Vlan Change'
24
24
  cfg.gsub! /(^((.*)Temperature(.*):(.*))$)/, 'removed Temperature'
25
25
  cfg.gsub! /(^((.*)Total Power Usage(.*):(.*))$)/, 'removed Total Power Usage'
26
+ cfg.gsub! /(^((.*)(Tray \d+ Fan \d+)\s+(\w+)\s+(\w+)\s+(.*))$)/, '\3\4 \5 [removed RPM values]'
27
+ cfg.gsub! /(^((.*)Command Execution Time: (.*))$)/, 'Command Execution Time [removed]'
28
+ cfg.gsub! /(^((.*)(Ambient\s+\d+|CPU|INTERNAL\s+MAC|SODIMM)\s+\d+\s+\d+(.*))$)/, '\3\4 [removed temperature readings]'
26
29
  comment "#{cfg}\n"
27
30
  end
28
31
 
@@ -27,15 +27,19 @@ class VRP < Oxidized::Model
27
27
  end
28
28
 
29
29
  cmd 'display version' do |cfg|
30
- cfg = cfg.each_line.reject { |l| l.match /uptime/ }.join
30
+ cfg = cfg.each_line.reject do |l|
31
+ l.match /uptime|^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d(\.\d\d\d)? ?(\+\d\d:\d\d)?$/
32
+ end.join
31
33
  comment cfg
32
34
  end
33
35
 
34
36
  cmd 'display device' do |cfg|
37
+ cfg = cfg.each_line.reject { |l| l.match /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d(\.\d\d\d)? ?(\+\d\d:\d\d)?$/ }.join
35
38
  comment cfg
36
39
  end
37
40
 
38
41
  cmd 'display current-configuration all' do |cfg|
42
+ cfg = cfg.each_line.reject { |l| l.match /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d(\.\d\d\d)? ?(\+\d\d:\d\d)?$/ }.join
39
43
  cfg
40
44
  end
41
45
  end
@@ -1,9 +1,9 @@
1
1
  class Vyatta < Oxidized::Model
2
2
  using Refinements
3
3
 
4
- # Brocade Vyatta / VyOS model #
4
+ # Brocade Vyatta model #
5
5
 
6
- prompt /@.*?:~\$\s/
6
+ prompt /@.*(:~\$|>)\s/
7
7
 
8
8
  cmd :all do |cfg|
9
9
  cfg.lines.to_a[1..-2].join
@@ -14,10 +14,16 @@ class Vyatta < Oxidized::Model
14
14
  cfg.gsub! /plaintext-password (\S+).*/, 'plaintext-password <secret removed>'
15
15
  cfg.gsub! /password (\S+).*/, 'password <secret removed>'
16
16
  cfg.gsub! /pre-shared-secret (\S+).*/, 'pre-shared-secret <secret removed>'
17
- cfg.gsub! /community (\S+) {/, 'community <hidden> {'
17
+ cfg.gsub! /community (\S+)/, 'community <hidden>'
18
+ cfg.gsub! /private-key (\S+).*/, 'private-key <secret removed>'
19
+ cfg.gsub! /preshared-key (\S+).*/, 'preshared-key <secret removed>'
18
20
  cfg
19
21
  end
20
22
 
23
+ cmd 'show version' do |cfg|
24
+ comment cfg
25
+ end
26
+
21
27
  cmd 'show configuration commands | no-more'
22
28
 
23
29
  cfg :telnet do