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,93 @@
1
+ class ArubaInstant < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Aruba IAP, Instant Controller
5
+
6
+ comment '# '
7
+ prompt(/^ ?[\w:.@-]+[#>] $/)
8
+
9
+ cmd :all do |cfg|
10
+ # Remove command echo and prompt
11
+ cfg.cut_both
12
+ end
13
+
14
+ cmd :secret do |cfg|
15
+ cfg.gsub!(/ipsec (\S+)$/, 'ipsec <secret removed>')
16
+ cfg.gsub!(/community (\S+)$/, 'community <secret removed>')
17
+ cfg.gsub!(/^(snmp-server host [\d.]+ version 2c) \S+ (.*)$/, '\1 <secret removed> \2')
18
+ # MAS format: mgmt-user <username> <accesslevel> <password hash>
19
+ # IAP format (root user): mgmt-user <username> <password hash>
20
+ # IAP format: mgmt-user <username> <password hash> <access level>
21
+ cfg.gsub!(/mgmt-user (\S+) (root|guest-provisioning|network-operations|read-only|location-api-mgmt) (\S+)$/, 'mgmt-user \1 \2 <secret removed>') # MAS & Wireless Controler
22
+ cfg.gsub!(/mgmt-user (\S+) (\S+)( (read-only|guest-mgmt))?$/, 'mgmt-user \1 <secret removed> \3') # IAP
23
+ cfg.gsub!(/key (\S+)$/, 'key <secret removed>')
24
+ cfg.gsub!(/wpa-passphrase (\S+)$/, 'wpa-passphrase <secret removed>')
25
+ cfg.gsub!(/bkup-passwords (\S+)$/, 'bkup-passwords <secret removed>')
26
+ cfg.gsub!(/user (\S+) (\S+) (\S+)$/, 'user \1 <secret removed> \3')
27
+ cfg.gsub!(/virtual-controller-key (\S+)$/, 'virtual-controller-key <secret removed>')
28
+ cfg.gsub!(/^(hash-mgmt-user .* password \S+) \S+( usertype .*)?$/, '\1 <secret removed>\2')
29
+ cfg
30
+ end
31
+
32
+ # get software version
33
+ cmd 'show version' do |cfg|
34
+ cfg = cfg.reject_lines [
35
+ /^(Switch|AP) uptime is /,
36
+ /^Reboot Time and Cause/
37
+ ]
38
+ comment cfg
39
+ end
40
+
41
+ # Get serial number
42
+ cmd 'show activate status' do |cfg|
43
+ cfg = cfg.reject_lines [
44
+ /^Activate /,
45
+ /^Provision interval/,
46
+ /^Cloud Activation Key/
47
+ ]
48
+ comment cfg + "\n"
49
+ end
50
+
51
+ # Get controlled WLAN-AP
52
+ cmd 'show aps' do |cfg|
53
+ out = ''
54
+ cfg.each_line do |line|
55
+ out += line.sub(
56
+ /^(?'Name'(?:.+?|-{2,})\s{2,}) # \s{2,} = separator between columns
57
+ (?'IPv4'(?:
58
+ IP\ Address|-{2,}| # Header
59
+ (?:\d+\.){3}\S+ # Match an IPv4 to catch AP-Names with two spaces
60
+ )\s{2,})
61
+ (?:(?:.+?|-{2,})\s{2,}){3} # Ignore Mode, Spectrum, Clients
62
+ (?'Type'(?:.+?|-{2,})\s{2,})
63
+ (?'IPv6'(?:.+?|-{2,})\s{2,})
64
+ (?:(?:.+?|-{2,})\s{2,}) # Ignore Mesh Role
65
+ (?'Zone'(?:.+?|-{2,})\s{2,})
66
+ (?'Serial'(?:.+?|-{2,}))
67
+ \s{2,} # Last separator
68
+ .*$ # Ignore the rest
69
+ /x,
70
+ '\k<Name>\k<IPv4>\k<Type>\k<IPv6>\k<Zone>\k<Serial>'
71
+ )
72
+ end
73
+ comment out + "\n"
74
+ end
75
+
76
+ cmd 'show running-config no-encrypt'
77
+
78
+ cfg :telnet do
79
+ username(/^User:\s*/)
80
+ password(/^Password:\s*/)
81
+ end
82
+
83
+ cfg :telnet, :ssh do
84
+ if vars :enable
85
+ post_login do
86
+ cmd "enable", /^[pP]assword:/
87
+ cmd vars(:enable)
88
+ end
89
+ end
90
+ pre_logout 'exit' if vars :enable
91
+ pre_logout 'exit'
92
+ end
93
+ end
@@ -15,9 +15,8 @@ class ASA < Oxidized::Model
15
15
  cfg.gsub! /enable password (\S+) (.*)/, 'enable password <secret hidden> \2'
16
16
  cfg.gsub! /^passwd (\S+) (.*)/, 'passwd <secret hidden> \2'
17
17
  cfg.gsub! /username (\S+) password (\S+) (.*)/, 'username \1 password <secret hidden> \3'
18
- cfg.gsub! /(ikev[12] ((remote|local)-authentication )?pre-shared-key) (\S+)/, '\1 <secret hidden>'
19
- cfg.gsub! /^(aaa-server TACACS\+? \(\S+\) host[^\n]*\n(\s+[^\n]+\n)*\skey) \S+$/mi, '\1 <secret hidden>'
20
- cfg.gsub! /^(aaa-server \S+ \(\S+\) host[^\n]*\n(\s+[^\n]+\n)*\s+key) \S+$/mi, '\1 <secret hidden>'
18
+ cfg.gsub! /(ikev[12] ((remote|local)-authentication )?pre-shared-key( hex)?) (\S+)/, '\1 <secret hidden>'
19
+ cfg.gsub! /^(aaa-server \S+(?: \(\S+\))? host \S+\n(?: [^\n]+\n)* +key) \S+$/mi, '\1 <secret hidden>'
21
20
  cfg.gsub! /ldap-login-password (\S+)/, 'ldap-login-password <secret hidden>'
22
21
  cfg.gsub! /^snmp-server host (.*) community (\S+)/, 'snmp-server host \1 community <secret hidden>'
23
22
  cfg.gsub! /^(failover key) .+/, '\1 <secret hidden>'
@@ -33,12 +32,13 @@ class ASA < Oxidized::Model
33
32
  end
34
33
 
35
34
  cmd 'show version' do |cfg|
36
- # avoid commits due to uptime / ixo-router01 up 2 mins 28 secs / ixo-router01 up 1 days 2 hours
37
- cfg = cfg.each_line.reject { |line| line.match /(\s+up\s+\d+\s+)|(.*days.*)/ }
38
- cfg = cfg.join
39
- cfg.gsub! /^Configuration has not been modified since last system restart.*\n/, ''
40
- cfg.gsub! /^Configuration last modified by.*\n/, ''
41
- comment cfg
35
+ comment cfg.reject_lines [
36
+ # avoid commits due to uptime / ixo-router01 up 2 mins 28 secs / ixo-router01 up 1 days 2 hours
37
+ /(\s+up\s+\d+\s+)|(.*days.*)/,
38
+ /^Configuration has not been modified since last system restart.*/,
39
+ /^Configuration last modified by.*/,
40
+ /^Start-up time.*/
41
+ ]
42
42
  end
43
43
 
44
44
  cmd 'show inventory' do |cfg|
@@ -96,7 +96,8 @@ class ASA < Oxidized::Model
96
96
  contexts = systemcfg.scan(/^context (\S+)$/)
97
97
  files = systemcfg.scan(/config-url (\S+)$/)
98
98
  contexts.each_with_index do |cont, i|
99
- allcfg = allcfg + "\n\n----------========== [ CONTEXT " + cont.join(" ") + " FILE " + files[i].join(" ") + " ] ==========----------\n\n"
99
+ allcfg = allcfg + "\n\n----------========== [ CONTEXT " + cont.join(" ") +
100
+ " FILE " + files[i].join(" ") + " ] ==========----------\n\n"
100
101
  cmd "more " + files[i].join(" ") do |cfgcontext|
101
102
  allcfg = allcfg + "\n\n" + cfgcontext
102
103
  end
@@ -0,0 +1,22 @@
1
+ class AsterNOS < Oxidized::Model
2
+ using Refinements
3
+
4
+ prompt /^[^$]+\$/
5
+ comment '# '
6
+
7
+ cmd :all do |cfg|
8
+ cfg.each_line.to_a[1..-2].join
9
+ end
10
+
11
+ cmd 'show version' do |cfg|
12
+ # @model = Regexp.last_match(1) if cfg =~ /^Model: (\S+)/
13
+ comment cfg
14
+ end
15
+
16
+ cmd "show runningconfiguration all"
17
+
18
+ cfg :ssh do
19
+ # exec true
20
+ pre_logout 'exit'
21
+ end
22
+ end
@@ -2,7 +2,7 @@ class AsyncOS < Oxidized::Model
2
2
  using Refinements
3
3
 
4
4
  # ESA prompt "(mail.example.com)> " or "mail.example.com> "
5
- prompt /^\r*([(]?[\w. ]+[)]?[#>]\s+)$/
5
+ prompt /^\r*\(?[\w.\- ]+\)?[#>]\s+$/
6
6
  comment '! '
7
7
 
8
8
  # Select passphrase display option
@@ -25,9 +25,9 @@ class AsyncOS < Oxidized::Model
25
25
  # Delete hour and date which change each run
26
26
  # cfg.gsub! /\sCurrent Time: \S+\s\S+\s+\S+\s\S+\s\S+/, ' Current Time:'
27
27
  # Delete select passphrase display option
28
- cfg.gsub! /Choose the passphrase option:/, ''
28
+ cfg.gsub! "Choose the passphrase option:", ''
29
29
  cfg.gsub! /1. Mask passphrases \(Files with masked passphrases cannot be loaded using/, ''
30
- cfg.gsub! /loadconfig command\)/, ''
30
+ cfg.gsub! "loadconfig command)", ''
31
31
  cfg.gsub! /2. Encrypt passphrases/, ''
32
32
  cfg.gsub! /3. Plain passphrases/, ''
33
33
  cfg.gsub! /^3$/, ''
@@ -12,14 +12,14 @@ class AudioCodes < Oxidized::Model
12
12
  data.sub re, ''
13
13
  end
14
14
 
15
- cmd 'show running-config' do |cfg|
15
+ cmd "show running-config\r\n" do |cfg|
16
16
  cfg
17
17
  end
18
18
 
19
19
  cfg :ssh do
20
20
  username /^login as:\s$/
21
21
  password /^.+password:\s$/
22
- pre_logout 'exit'
22
+ pre_logout "exit\r\n"
23
23
  end
24
24
 
25
25
  cfg :telnet do
@@ -15,8 +15,8 @@ class AWPlus < Oxidized::Model
15
15
 
16
16
  # Removes gibberish pager output e.g. VT100 escape codes
17
17
  cmd :all do |cfg|
18
- cfg.gsub! /\e\[K/, '' # example how to handle pager - cleareol EL0
19
- cfg.gsub! /\e\[7m\e\[m/, '' # example how to handle pager - Reverse SGR7
18
+ cfg.gsub! "\e[K", '' # example how to handle pager - cleareol EL0
19
+ cfg.gsub! "\e[7m\e[m", '' # example how to handle pager - Reverse SGR7
20
20
  cfg.delete! "\r" # Filters rogue ^M - see issue #415
21
21
  cfg.cut_both
22
22
  end
@@ -61,25 +61,28 @@ class AWPlus < Oxidized::Model
61
61
  cfg
62
62
  end
63
63
 
64
- # Config required for telnet to detect username prompt
64
+ # Config required for telnet to detect username & password prompt.
65
65
  cfg :telnet do
66
66
  username /login:\s/
67
+ password /^Password:\s/
67
68
  end
68
69
 
69
- # Main login config
70
+ # Config required for ssh to specify newline characters.
70
71
  cfg :telnet, :ssh do
72
+ newline "\r\n"
73
+
71
74
  post_login do
72
- if vars :enable
73
- send "enable\n"
74
- expect /^Password:\s/
75
- cmd vars(:enable) + "\r\n"
76
- else
77
- cmd 'enable' # Required for Priv-Exec users without enable PW to be put into "enable mode".
75
+ if vars(:enable) == true
76
+ cmd "enable"
77
+ elsif vars(:enable)
78
+ cmd "enable", /^[pP]assword:/
79
+ cmd vars(:enable)
78
80
  end
79
- # cmd 'terminal length 0' #set so the entire config is output without intervention.
81
+ # cmd 'terminal length 0' # set so the entire config is output without intervention.
80
82
  end
83
+
81
84
  pre_logout do
82
- # cmd 'terminal no length' #Sets term length back to default on exit.
85
+ # cmd 'terminal no length' # sets term length back to default on exit.
83
86
  send "exit\r\n"
84
87
  end
85
88
  end
@@ -1,7 +1,7 @@
1
1
  class AxOS < Oxidized::Model
2
2
  using Refinements
3
3
 
4
- prompt /(\x1b\[\?7h)?([\w.@()-]+[#]\s?)$/
4
+ prompt /(\x1b\[\?7h)?([\w.@()-]+\#\s?)$/
5
5
  comment '! '
6
6
 
7
7
  cmd 'show running-config | nomore' do |cfg|
@@ -47,5 +47,6 @@ class BDCOM < Oxidized::Model
47
47
 
48
48
  post_login 'terminal length 0'
49
49
  pre_logout 'exit'
50
+ pre_logout 'exit'
50
51
  end
51
52
  end
@@ -18,8 +18,7 @@ class C4CMTS < Oxidized::Model
18
18
  cfg
19
19
  end
20
20
 
21
- cmd 'show environment' do |cfg|
22
- cfg.gsub! /\s+[\-\d]+\s+C\s+[(\s\d]+\s+F\)/, '' # remove temperature readings
21
+ cmd 'show factory-eeprom' do |cfg|
23
22
  comment cfg.cut_both
24
23
  end
25
24
 
@@ -25,7 +25,7 @@ class CiscoSMA < Oxidized::Model
25
25
  # Delete hour and date which change each run
26
26
  # cfg.gsub! /\sCurrent Time: \S+\s\S+\s+\S+\s\S+\s\S+/, ' Current Time:'
27
27
  # Delete select passphrase display option
28
- cfg.gsub! /Do you want to mask the password\? Files with masked passwords cannot be loaded/, ''
28
+ cfg.gsub! "Do you want to mask the password? Files with masked passwords cannot be loaded", ''
29
29
  cfg.gsub! /^\s+y/, ''
30
30
  # Delete space
31
31
  cfg.gsub! /\n\s{25}/, ''
@@ -5,7 +5,12 @@ class CiscoSMB < Oxidized::Model
5
5
  # http://www.cisco.com/c/en/us/support/switches/small-business-300-series-managed-switches/products-release-notes-list.html
6
6
 
7
7
  prompt /^\r?([\w.@()-]+[#>]\s?)$/
8
- comment '! '
8
+ comment '! '
9
+
10
+ expect '^.*Your password has exceeded the maximum lifetime.*$' do
11
+ send 'N'
12
+ ""
13
+ end
9
14
 
10
15
  cmd :all do |cfg|
11
16
  lines = cfg.each_line.to_a[1..-2]
@@ -4,18 +4,20 @@ class CNOS < Oxidized::Model
4
4
 
5
5
  comment '! '
6
6
 
7
- cmd :all do |cfg|
8
- cfg.each_line.to_a[0..-2].join
7
+ cmd :secret do |cfg|
8
+ cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
9
+ cfg.gsub! /^(username .+ (password|secret) \d) .+/, '\\1 <secret hidden>'
10
+ cfg.gsub! /^(enable (password|secret)( level \d+)?( \d)?) .+/, '\\1 <secret hidden>'
11
+ cfg
9
12
  end
10
13
 
11
- cmd 'show running-config' do |cfg|
12
- cfg.gsub!(/(snmp-server community )(\S+)/, '\1<hidden>')
13
- cfg.gsub!(/key type private.+key string end/m, '<private key hidden>')
14
- cfg
14
+ cmd :all do |cfg|
15
+ cfg = cfg.delete("\r")
16
+ cfg.cut_both
15
17
  end
16
18
 
17
19
  cmd 'show version' do |cfg|
18
- cfg.gsub! /^(.* uptime is ).*\n/, '\1'
20
+ cfg = cfg.each_line.reject { |line| line.match /\ uptime\ is\ / }.join
19
21
  comment cfg
20
22
  end
21
23
 
@@ -23,9 +25,10 @@ class CNOS < Oxidized::Model
23
25
  comment cfg
24
26
  end
25
27
 
26
- cfg :telnet do
27
- username /^Username:/
28
- password /^Password:/
28
+ cmd 'show running-config' do |cfg|
29
+ # remove empty lines
30
+ cfg = cfg.each_line.reject { |line| line.match /^[\r\n\s\u0000#]+$/ }.join
31
+ cfg
29
32
  end
30
33
 
31
34
  cfg :telnet, :ssh do
@@ -35,7 +35,7 @@ class Comtrol < Oxidized::Model
35
35
  expect /[pP]assword:\s?$/
36
36
  send vars(:enable) + "\n"
37
37
  end
38
- expect /^.+[#]\s?$/
38
+ expect /^.+\#\s?$/
39
39
  end
40
40
  end
41
41
  pre_logout 'exit'
@@ -21,13 +21,15 @@ class Comware < Oxidized::Model
21
21
 
22
22
  cmd :secret do |cfg|
23
23
  cfg.gsub! /^( snmp-agent community).*/, '\\1 <configuration removed>'
24
- cfg.gsub! /^( password hash).*/, '\\1 <configuration removed>'
24
+ cfg.gsub! /(password hash).*/, '\\1 <configuration removed>'
25
25
  cfg.gsub! /^( password cipher).*/, '\\1 <configuration removed>'
26
+ cfg.gsub! /(key (authentication )?cipher) \S+/, '\\1 <configuration removed>'
27
+ cfg.gsub! /(cipher authentication-mode (md5|sha)).\S+ (privacy-mode (des56|3des|aes\d{0,3})) .\S+/, '\\1 <auth-pass> \\3 <priv-pass>'
26
28
  cfg
27
29
  end
28
30
 
29
31
  cfg :telnet do
30
- username /^(Username|login):/
32
+ username /^(Username|[Ll]ogin):/
31
33
  password /^Password:/
32
34
  end
33
35
 
@@ -37,7 +39,7 @@ class Comware < Oxidized::Model
37
39
  if vars(:enable) == true
38
40
  cmd "super"
39
41
  elsif vars(:enable)
40
- cmd "super", /^ [pP]assword:/
42
+ cmd "super", /^\s?[pP]assword:/
41
43
  cmd vars(:enable)
42
44
  end
43
45
  end
@@ -1,7 +1,14 @@
1
1
  class Cumulus < Oxidized::Model
2
2
  using Refinements
3
3
 
4
- prompt /^((\w*)@(.*)):/
4
+ # Regular expression explanation:
5
+ # ^ : match begin of line, to have the most specific prompt
6
+ # [\w.-]+@[\w.-]+ : user@hostname
7
+ # (:mgmt)? : optional when logged in out of band
8
+ # :?~[#$] ?$ : end of prompt, containing the linux path,
9
+ # which is always "~" in our context.
10
+ prompt /^[\w.-]+@[\w.-]+(:mgmt)?:?~[#$] ?$/
11
+ clean :escape_codes
5
12
  comment '# '
6
13
 
7
14
  # add a comment in the final conf
@@ -21,9 +28,12 @@ class Cumulus < Oxidized::Model
21
28
  # show the persistent configuration
22
29
  pre do
23
30
  use_nclu = vars(:cumulus_use_nclu) || false
31
+ use_nvue = vars(:cumulus_use_nvue) || false
24
32
 
25
33
  if use_nclu
26
34
  cfg = cmd 'net show configuration commands'
35
+ elsif use_nvue
36
+ cfg = cmd 'nv config show --color off'
27
37
  else
28
38
  # Set FRR or Quagga in config
29
39
  routing_daemon = vars(:cumulus_routing_daemon) ? vars(:cumulus_routing_daemon).downcase : 'quagga'
@@ -76,7 +86,9 @@ class Cumulus < Oxidized::Model
76
86
  cfg += cmd 'cat /etc/cumulus/switchd.conf'
77
87
 
78
88
  cfg += add_comment 'PORTS'
79
- cfg += cmd 'cat /etc/cumulus/ports.conf'
89
+ # in some configurations, ports.conf has no trailing Line Feed,
90
+ # which breaks the prompt, so we add one
91
+ cfg += cmd "cat /etc/cumulus/ports.conf; echo"
80
92
 
81
93
  cfg += add_comment 'TRAFFIC'
82
94
  cfg += cmd 'cat /etc/cumulus/datapath/traffic.conf'
@@ -0,0 +1,26 @@
1
+ class Defacto < Oxidized::Model
2
+ prompt /^(\r*[\w.:@()\/_-]+[#>]\s?)$/
3
+ comment '! '
4
+
5
+ clean :cut
6
+
7
+ post do
8
+ cmd "show running-config" do |cfg|
9
+ process_config cfg
10
+ end
11
+ end
12
+
13
+ cfg :telnet do
14
+ username /^(user ?name|login|user)/i
15
+ password /^password/i
16
+ end
17
+
18
+ cfg :telnet, :ssh do
19
+ post_login 'terminal length 0'
20
+ post_login 'terminal width 0'
21
+ pre_logout 'exit'
22
+ pre_logout 'logout'
23
+ end
24
+
25
+ def process_config(cfg) = cfg
26
+ end
@@ -7,7 +7,7 @@ class DellX < Oxidized::Model
7
7
 
8
8
  comment '! '
9
9
 
10
- expect /(^.*)?+[mM]ore\:+.*$/ do |data, re|
10
+ expect /(^.*)?+[mM]ore:+.*$/ do |data, re|
11
11
  send ' '
12
12
  data.sub re, ''
13
13
  end
@@ -2,9 +2,8 @@ class Dlink < Oxidized::Model
2
2
  using Refinements
3
3
 
4
4
  # D-LINK Switches
5
- # Add support dgs 1100 series (tested only with dgs-1100-10/me)
6
5
 
7
- prompt /^(\r*[\w\s.@()\/:-]+[#>]\s?)$/
6
+ prompt /[\w.@()\/:-]+[#>]\s?$/
8
7
  comment '# '
9
8
 
10
9
  cmd :secret do |cfg|
@@ -19,6 +18,9 @@ class Dlink < Oxidized::Model
19
18
 
20
19
  cmd 'show switch' do |cfg|
21
20
  cfg.gsub! /^System Uptime\s.+/, '' # Omit constantly changing uptime info
21
+ cfg.gsub! /^System up time\s.+/, '' # Omit constantly changing uptime info
22
+ cfg.gsub! /^System Time\s.+/, '' # Omit constantly changing uptime info
23
+ cfg.gsub! /^RTC Time\s.+/, '' # Omit constantly changing uptime info
22
24
  comment cfg
23
25
  end
24
26
 
@@ -35,6 +37,7 @@ class Dlink < Oxidized::Model
35
37
 
36
38
  cfg :telnet, :ssh do
37
39
  post_login 'disable clipaging'
40
+ post_login 'enable admin' if vars(:enable) == true
38
41
  pre_logout 'logout'
39
42
  end
40
43
  end
@@ -0,0 +1,55 @@
1
+ class DlinkNextGen < Oxidized::Model
2
+ using Refinements
3
+
4
+ # D-LINK next generation cli Switches
5
+ # Add support DXS-1210-12SC
6
+
7
+ prompt /[\w.@()\/-]+[#>]\s?$/
8
+ comment '# '
9
+
10
+ cmd :all do |cfg|
11
+ cfg.gsub!("\0", "") # Remove NULL bytes that cause Git to detect the file as binary
12
+ cfg.each_line.to_a[2..-2].map { |line| line.delete("\r").rstrip }.join("\n") + "\n"
13
+ end
14
+
15
+ cmd :secret do |cfg|
16
+ cfg.gsub! /(password) (\S+).*/, '\\1 <secret hidden>'
17
+ cfg.gsub! /(snmp-server group) (\S+) (v.*)/, '\\1 <secret hidden> \\3'
18
+ cfg.gsub! /(snmp-server community) (\S+) (v.*)/, '\\1 <secret hidden> \\3'
19
+ cfg
20
+ end
21
+
22
+ # "show switch" doesn't exist on DXS-1210-28T rev A1 Firmware: Build 1.00.024; not figured out how to run "show version" so running both
23
+ cmd 'show switch' do |cfg|
24
+ cfg.gsub! /^\s+System Time\s.+/, '' # Omit constantly changing uptime info
25
+ comment cfg
26
+ end
27
+
28
+ cmd 'show version' do |cfg|
29
+ comment cfg
30
+ end
31
+
32
+ cmd 'show vlan' do |cfg|
33
+ comment cfg
34
+ end
35
+
36
+ cmd 'show running-config' do |cfg|
37
+ cfg.gsub! /^(snmp-server community ["\w]+) \S+/, '\\1 <removed>'
38
+ cfg.gsub! /^(username [\w.@-]+ privilege \d{1,2} password \d{1,2}) \S+/, '\\1 <removed>'
39
+ cfg.gsub! /^(!System Up Time).*/, '\\1 <removed>'
40
+ cfg.gsub! /^(!Current SNTP Synchronized Time:).*/, '\\1 <removed>'
41
+ cfg.gsub! /^(\s+ppp (chap|pap) password \d) .+/, '\\1 <secret hidden>'
42
+ cfg
43
+ end
44
+
45
+ cfg :telnet do
46
+ username /\r*([\w\s.@()\/:-]+)?([Uu]ser[Nn]ame|[Ll]ogin):/
47
+ password /\r*[Pp]ass[Ww]ord:/
48
+ end
49
+
50
+ cfg :telnet, :ssh do
51
+ post_login 'terminal length 0'
52
+ post_login 'terminal width 255'
53
+ pre_logout 'logout'
54
+ end
55
+ end
@@ -16,6 +16,9 @@ class DNOS < Oxidized::Model
16
16
  cfg.gsub! /secret (\d+) (\S+).*/, '<secret hidden>'
17
17
  cfg.gsub! /password (\d+) (\S+).*/, '<secret hidden>'
18
18
  cfg.gsub! /^(tacacs-server key \d+) (\S+).*/, '\\1 <secret hidden>'
19
+ cfg.gsub! /(ip ospf message-digest-key \d \S+ \d).*/, '\\1 <secret hidden>'
20
+ cfg.gsub! /(authentication-type).*/, '\\1 <secret hidden>'
21
+ cfg.gsub! /^(bsd-username \S+ secret).*/, '\\1 <secret hidden>'
19
22
  cfg
20
23
  end
21
24
 
@@ -0,0 +1,93 @@
1
+ module Oxidized
2
+ class Model
3
+ # Domain Specific Language for model commands
4
+ module DSLCommands
5
+ # Store a command to be run against the device
6
+ # cmd_arg can be:
7
+ # - a string (the command to be run)
8
+ # - a symbol:
9
+ # - :all - run the block against each command output
10
+ # - :secret - run the block against each command output when
11
+ # vars :remove_secret is true
12
+ # - :significant_changes - use the block to remove unsignificant
13
+ # changes
14
+ # Optional arguments (**args):
15
+ # - clear: true
16
+ # replace all the stored blocks for this command (monkey patching)
17
+ # - prepend: true
18
+ # prepend the block to the stored blocks for this command (monkey
19
+ # patching)
20
+ # - if: lambda
21
+ # run the command only if the lambda evaluates to true
22
+ # - input: symbol or array of symbols
23
+ # for the inputs this command is to run against (default - run
24
+ # every command)
25
+ def cmd(cmd_arg = nil, **args, &block)
26
+ if cmd_arg.instance_of?(Symbol)
27
+ process_args_block(@cmd[cmd_arg], args, block)
28
+ else
29
+ return unless valid_cmd_args?(cmd_arg, args)
30
+
31
+ # Always use an array for :input
32
+ args[:input] = Array(args[:input]) if args.include?(:input)
33
+ process_args_block(@cmd[:cmd], args,
34
+ { cmd: cmd_arg, args: args, block: block })
35
+ end
36
+ logger.debug "Added #{cmd_arg} to the commands list"
37
+ end
38
+
39
+ def cmds
40
+ @cmd
41
+ end
42
+
43
+ # calls the block at the end of the model, prepending the output of the
44
+ # block to the output string
45
+ def pre(**args, &block)
46
+ process_args_block(@procs[:pre], args, block)
47
+ end
48
+
49
+ # calls the block at the end of the model, adding the output of the block
50
+ # to the output string
51
+ def post(**args, &block)
52
+ process_args_block(@procs[:post], args, block)
53
+ end
54
+
55
+ # @procs is a hash of procs (:pre+:post) to be prepended/postfixed to
56
+ # output
57
+ attr_reader :procs
58
+
59
+ private
60
+
61
+ def process_args_block(target, args, block)
62
+ if args[:clear]
63
+ if block.instance_of?(Array)
64
+ target.reject! { |k, _| k == block[0] }
65
+ target.push(block)
66
+ elsif block.instance_of?(Hash)
67
+ target.reject! { |item| item[:cmd] == block[:cmd] }
68
+ target.push(block)
69
+ else
70
+ target.replace([block])
71
+ end
72
+ else
73
+ method = args[:prepend] ? :unshift : :push
74
+ target.send(method, block)
75
+ end
76
+ end
77
+
78
+ def valid_cmd_args?(cmd_arg, args)
79
+ if args.include?(:if) && !(args[:if].is_a?(Proc) && args[:if].lambda?)
80
+ logger.error "cmd #{cmd_arg.dump}: if must be a lambda"
81
+ return false
82
+ end
83
+
84
+ if args.include?(:input) && ![Symbol, Array].include?(args[:input].class)
85
+ logger.error "cmd #{cmd_arg.dump}: input must be a symbol or an array of symbols"
86
+ return false
87
+ end
88
+
89
+ true
90
+ end
91
+ end
92
+ end
93
+ end