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,160 @@
1
+ class FortiGate < Oxidized::Model
2
+ using Refinements
3
+
4
+ comment '# '
5
+
6
+ prompt /^(\(\w\) )?([-\w.~]+(\s[(\w\-.)]+)?~?\s?[#>$]\s?)$/
7
+
8
+ # When a post-login-banner is enabled, you have to press "a" to log in
9
+ expect /^\(Press\s'a'\sto\saccept\):/ do |data, re|
10
+ send 'a'
11
+ data.sub re, ''
12
+ end
13
+
14
+ expect /^--More--\s$/ do |data, re|
15
+ send ' '
16
+ data.sub re, ''
17
+ end
18
+
19
+ cmd :all do |cfg|
20
+ # Remove junk after --More-- pager
21
+ cfg = cfg.gsub(/\r +\r/, '')
22
+ # Remove \r\n after command echo
23
+ cfg = cfg.gsub("\r\n", "\n")
24
+ # remove command echo and prompt
25
+ cfg.cut_both
26
+ end
27
+
28
+ cmd :secret do |cfg|
29
+ # Remove private key for encrypted configs
30
+ cfg.gsub! /^(\#private-encryption-key=).+/, '\\1 <configuration removed>'
31
+ # ENC indicates an encrypted password, and secret indicates a secret string
32
+ cfg.gsub! /(set .+ ENC) .+/, '\\1 <configuration removed>'
33
+ cfg.gsub! /(set .*secret) .+/, '\\1 <configuration removed>'
34
+ # A number of other statements also contains sensitive strings
35
+ cfg.gsub! /(set (?:passwd|password|key|group-password|auth-password-l1|auth-password-l2|rsso|history0|history1)) .+/, '\\1 <configuration removed>'
36
+ cfg.gsub! /(set md5-key [0-9]+) .+/, '\\1 <configuration removed>'
37
+ cfg.gsub! /(set private-key ).*?-+END (ENCRYPTED|RSA|OPENSSH) PRIVATE KEY-+\n?"$/m, '\\1<configuration removed>'
38
+ cfg.gsub! /(set privatekey ).*?-+END (ENCRYPTED|RSA|OPENSSH) PRIVATE KEY-+\n?"$/m, '\\1<configuration removed>'
39
+ cfg.gsub! /(set ca )"-+BEGIN.*?-+END CERTIFICATE-+"$/m, '\\1<configuration removed>'
40
+ cfg.gsub! /(set csr ).*?-+END CERTIFICATE REQUEST-+"$/m, '\\1<configuration removed>'
41
+ cfg
42
+ end
43
+
44
+ cmd 'get system status' do |cfg|
45
+ @vdom_enabled = cfg.match(/^Virtual domain configuration: (enable|multiple)/)
46
+ @ha_cluster = cfg.match(/^Current HA mode: a-/) # a-p or a-a
47
+ cfg = cfg.keep_lines [
48
+ "Version: ",
49
+ "Security Level: ",
50
+ "Serial-Number: ",
51
+ "BIOS version: ",
52
+ "System Part-Number: ",
53
+ "Hostname: ",
54
+ "Operation Mode: ",
55
+ "Current virtual domain: ",
56
+ "Max number of virtual domains: ",
57
+ "Virtual domains status:",
58
+ "Virtual domain configuration: ",
59
+ "FIPS-CC mode: ",
60
+ "Current HA mode: ",
61
+ "Private Encryption: ",
62
+ # Lines in FortiGate-VM64
63
+ "License Expiration Date: ",
64
+ "License Status: ",
65
+ "VM Resources: "
66
+ ]
67
+ comment cfg + "\n"
68
+ end
69
+
70
+ cmd 'config global', if: -> { @vdom_enabled } do |_cfg|
71
+ ''
72
+ end
73
+
74
+ cmd 'get system ha status', if: -> { @ha_cluster } do |cfg|
75
+ cfg = cfg.keep_lines [
76
+ "HA Health Status:",
77
+ "Model: ",
78
+ "Mode: ",
79
+ "number of member: ",
80
+ /^(Master|Slave|Primary|Secondary): /
81
+ ]
82
+ comment cfg + "\n"
83
+ end
84
+
85
+ cmd 'get hardware status' do |cfg|
86
+ comment cfg
87
+ end
88
+
89
+ cmd "diagnose hardware deviceinfo psu" do |cfg|
90
+ skip_patterns = [
91
+ /Command fail\./, # The device doesn't support this command
92
+ /Power Supply +Status/ # We only get a status, but no serial numbers
93
+ ]
94
+ if skip_patterns.any? { |p| cfg.match?(p) }
95
+ logger.debug "No PSU serial numbers available"
96
+ ''
97
+ else
98
+ comment cfg
99
+ end
100
+ end
101
+
102
+ cmd "get system interface transceiver" do |cfg|
103
+ cfg = cfg.keep_lines [
104
+ /^Interface \w/,
105
+ "Vendor Name",
106
+ "Part No.",
107
+ "Serial No."
108
+ ]
109
+ cfg = cfg.reject_lines ["Transceiver is not detected"]
110
+ comment cfg + "\n"
111
+ end
112
+
113
+ cmd 'diagnose autoupdate version', if: -> { vars(:fortios_autoupdate) || vars(:fortigate_autoupdate) } do |cfg|
114
+ if vars(:fortios_autoupdate)
115
+ logger.warn("The variable fortios_autoupdate is deprecated. Migrate to fortigate_autoupdate")
116
+ end
117
+
118
+ cfg = cfg.sub(/FDS Address\n---------\n.*\n/, '')
119
+ comment cfg.reject_lines ["Last Update", "Result :"]
120
+ end
121
+
122
+ cmd 'end', if: -> { @vdom_enabled } do |_cfg|
123
+ ''
124
+ end
125
+
126
+ def clean_config(cfg)
127
+ cfg = cfg.reject_lines ['#conf_file_ver=']
128
+ cfg.gsub!(/(set comments "Error \(No order found for account ID \d+\) on).*/,
129
+ '\\1 <stripped>')
130
+ cfg
131
+ end
132
+
133
+ # If vars fullconfig is set to true, we get the full config (including default
134
+ # values)
135
+ cmd "show full-configuration | grep .", if: -> { vars(:fullconfig) } do |cfg|
136
+ clean_config cfg
137
+ end
138
+ # else backup as in Fortigate GUI
139
+ cmd "show | grep .", if: -> { !vars(:fullconfig) } do |cfg|
140
+ clean_config cfg
141
+ end
142
+
143
+ cmd :significant_changes do |cfg|
144
+ cfg = cfg.reject_lines [
145
+ /^ +set \S+ ENC \S+$/
146
+ ]
147
+ cfg.gsub!(/(config firewall internet-service-name\n).*?(\nend\n)/m, '')
148
+ cfg.gsub!(/set private-key .*?-+END \S+ PRIVATE KEY-+\n?"$/m, '')
149
+ cfg
150
+ end
151
+
152
+ cfg :telnet do
153
+ username /^[lL]ogin:/
154
+ password /^Password:/
155
+ end
156
+
157
+ cfg :telnet, :ssh do
158
+ pre_logout "exit"
159
+ end
160
+ end
@@ -3,19 +3,31 @@ class FortiOS < Oxidized::Model
3
3
 
4
4
  comment '# '
5
5
 
6
- prompt /^([-\w.~]+(\s[(\w\-.)]+)?~?\s?[#>$]\s?)$/
6
+ prompt /^(\(\w\) )?([-\w.~]+(\s[(\w\-.)]+)?~?\s?[#>$]\s?)$/
7
+
8
+ # When a post-login-banner is enabled, you have to press "a" to log in
9
+ expect /^\(Press\s'a'\sto\saccept\):/ do |data, re|
10
+ send 'a'
11
+ data.sub re, ''
12
+ end
7
13
 
8
14
  expect /^--More--\s$/ do |data, re|
9
15
  send ' '
10
16
  data.sub re, ''
11
17
  end
12
18
 
13
- cmd :all do |cfg, cmdstring|
14
- new_cfg = comment "COMMAND: #{cmdstring}\n"
15
- new_cfg << cfg.each_line.to_a[1..-2].map { |line| line.gsub(/(conf_file_ver=)(.*)/, '\1<stripped>\3') }.join
19
+ cmd :all do |cfg|
20
+ # Remove junk after --More-- pager
21
+ cfg = cfg.gsub(/\r +\r/, '')
22
+ # Remove \r\n after command echo
23
+ cfg = cfg.gsub("\r\n", "\n")
24
+ # remove command echo and prompt
25
+ cfg.cut_both
16
26
  end
17
27
 
18
28
  cmd :secret do |cfg|
29
+ # Remove private key for encrypted configs
30
+ cfg.gsub! /^(\#private-encryption-key=).+/, '\\1 <configuration removed>'
19
31
  # ENC indicates an encrypted password, and secret indicates a secret string
20
32
  cfg.gsub! /(set .+ ENC) .+/, '\\1 <configuration removed>'
21
33
  cfg.gsub! /(set .*secret) .+/, '\\1 <configuration removed>'
@@ -23,58 +35,36 @@ class FortiOS < Oxidized::Model
23
35
  cfg.gsub! /(set (?:passwd|password|key|group-password|auth-password-l1|auth-password-l2|rsso|history0|history1)) .+/, '\\1 <configuration removed>'
24
36
  cfg.gsub! /(set md5-key [0-9]+) .+/, '\\1 <configuration removed>'
25
37
  cfg.gsub! /(set private-key ).*?-+END (ENCRYPTED|RSA|OPENSSH) PRIVATE KEY-+\n?"$/m, '\\1<configuration removed>'
38
+ cfg.gsub! /(set privatekey ).*?-+END (ENCRYPTED|RSA|OPENSSH) PRIVATE KEY-+\n?"$/m, '\\1<configuration removed>'
26
39
  cfg.gsub! /(set ca )"-+BEGIN.*?-+END CERTIFICATE-+"$/m, '\\1<configuration removed>'
27
40
  cfg.gsub! /(set csr ).*?-+END CERTIFICATE REQUEST-+"$/m, '\\1<configuration removed>'
28
41
  cfg
29
42
  end
30
43
 
31
44
  cmd 'get system status' do |cfg|
32
- @vdom_enabled = cfg.match /Virtual domain configuration: (enable|multiple)/
33
- cfg.gsub! /(System time:).*/, '\\1 <stripped>'
34
- cfg.gsub! /(Cluster (?:uptime|state change time):).*/, '\\1 <stripped>'
35
- cfg.gsub! /(Current Time\s+:\s+)(.*)/, '\1<stripped>'
36
- cfg.gsub! /(Uptime:\s+)(.*)/, '\1<stripped>\3'
37
- cfg.gsub! /(Last reboot:\s+)(.*)/, '\1<stripped>\3'
38
- cfg.gsub! /(Disk Usage\s+:\s+)(.*)/, '\1<stripped>'
39
- cfg.gsub! /(^\S+ (?:disk|DB):\s+)(.*)/, '\1<stripped>\3'
40
- cfg.gsub! /(VM Registration:\s+)(.*)/, '\1<stripped>\3'
41
- 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>'
42
- comment cfg
45
+ cfg = cfg.reject_lines [
46
+ "Current Time",
47
+ "Disk Usage",
48
+ "Release Version Information",
49
+ "Branch Point",
50
+ "Daylight Time Saving",
51
+ "Time Zone",
52
+ "x86-64 Applications",
53
+ "File System",
54
+ "Image Signature"
55
+ ]
56
+ comment cfg + "\n"
43
57
  end
44
58
 
45
- post do
46
- cfg = []
47
- cfg << cmd('config global') if @vdom_enabled
48
-
49
- cfg << cmd('get system ha status') do |cfg_ha|
50
- cfg_ha = cfg_ha.each_line.select { |line| line.match /^(HA Health Status|Mode|Model|Master|Slave|Primary|Secondary|# COMMAND)(\s+)?:/ }.join
51
- comment cfg_ha
52
- end
53
-
54
- cfg << cmd('get hardware status') do |cfg_hw|
55
- comment cfg_hw
56
- end
57
-
58
- # default behaviour: include autoupdate output (backwards compatibility)
59
- # do not include if variable "show_autoupdate" is set to false
60
- if defined?(vars(:fortios_autoupdate)).nil? || vars(:fortios_autoupdate)
61
- cfg << cmd('diagnose autoupdate version') do |cfg_auto|
62
- cfg_auto.gsub! /(FDS Address\n---------\n).*/, '\\1IP Address removed'
63
- comment cfg_auto.each_line.reject { |line| line.match /Last Update|Result/ }.join
64
- end
65
- end
66
-
67
- cfg << cmd('end') if @vdom_enabled
68
-
69
- ['show full-configuration | grep .', 'show full-configuration', 'show'].each do |fullcmd|
70
- fullcfg = cmd(fullcmd)
71
- next if fullcfg.lines[1..3].join =~ /(Parsing error at|command parse error)/ # Don't show for unsupported devices (e.g. FortiAnalyzer, FortiManager, FortiMail)
72
-
73
- cfg << fullcfg
74
- break
75
- end
59
+ cmd "show" do |cfg|
60
+ cfg.reject_lines ['#config-version=']
61
+ end
76
62
 
77
- cfg.join
63
+ cmd :significant_changes do |cfg|
64
+ cfg = cfg.reject_lines [
65
+ /^ +set \S+ ENC \S+$/
66
+ ]
67
+ cfg.gsub(/set private-key .*?-+END \S+ PRIVATE KEY-+\n?"$/m, '')
78
68
  end
79
69
 
80
70
  cfg :telnet do
@@ -83,6 +73,6 @@ class FortiOS < Oxidized::Model
83
73
  end
84
74
 
85
75
  cfg :telnet, :ssh do
86
- pre_logout "exit\n"
76
+ pre_logout "exit"
87
77
  end
88
78
  end
@@ -0,0 +1,46 @@
1
+ class FSOS < Oxidized::Model
2
+ # Fiberstore / fs.com
3
+ using Refinements
4
+ comment '! '
5
+ prompt /^([\w.@()-]+[#>]\s?)$/
6
+
7
+ # Handle paging
8
+ expect /^ --More--.*$/ do |data, re|
9
+ send ' '
10
+ data.sub re, ''
11
+ end
12
+
13
+ cmd :secret do |cfg|
14
+ cfg.gsub! /(secret \w+) (\S+).*/, '\\1 <secret hidden>'
15
+ cfg.gsub! /(password \d+) (\S+).*/, '\\1 <secret hidden>'
16
+ cfg.gsub! /(snmp-server community \d+) (\S+).*/, '\\1 <secret hidden>'
17
+ cfg.gsub! /^(snmp-server host \S+( udp-port \d+)?( permit|deny \d+)?( informs?)?( traps?)?(( version v3 (priv|auth|noauth))|( version (v1|v2c))?)) +\S+( .*)?$*/, '\\1 <secret hidden>'
18
+ cfg.gsub! /^(snmp-server user \S+ \S+ v3( priv (des|aes128|aes256|aes256-c))?( auth (md5|sha|sha256) \d+)) +\S+( .*)?$*/, '\\1 <secret hidden>'
19
+ cfg.gsub! /^(.*key \d+) (\S+).*/, '\\1 <secret hidden>'
20
+ cfg
21
+ end
22
+
23
+ cmd 'show version' do |cfg|
24
+ # Remove uptime so the result doesn't change every time
25
+ comment cfg.reject_lines ['uptime is', 'System uptime']
26
+ end
27
+
28
+ cmd 'show running-config' do |cfg|
29
+ # Remove "Building configuration..." message
30
+ cfg.gsub! /^Building configuration.*\n/, ''
31
+ cfg.cut_head
32
+ end
33
+
34
+ cfg :telnet do
35
+ username /^Username:/
36
+ password /^Password:/
37
+ end
38
+
39
+ cfg :telnet, :ssh do
40
+ post_login 'enable'
41
+ post_login 'terminal length 0'
42
+ post_login 'terminal width 0'
43
+ pre_logout 'exit'
44
+ pre_logout 'exit'
45
+ end
46
+ end
@@ -26,7 +26,7 @@ class GaiaOS < Oxidized::Model
26
26
  # check for vsx / multiple context
27
27
  cmd 'show vsx' do |cfg|
28
28
  @is_vsx = cfg.include? 'VSX Enabled'
29
- Oxidized.logger.debug cfg
29
+ logger.debug cfg
30
30
  end
31
31
 
32
32
  cmd 'show asset all' do |cfg|
@@ -46,7 +46,7 @@ class GaiaOS < Oxidized::Model
46
46
  end
47
47
 
48
48
  def single_context
49
- Oxidized.logger.debug 'Single context tasks'
49
+ logger.debug 'Single context tasks'
50
50
  cmd 'show configuration' do |cfg|
51
51
  cfg.gsub! /^# Exported by \S+ on .*/, '# '
52
52
  cfg
@@ -54,7 +54,7 @@ class GaiaOS < Oxidized::Model
54
54
  end
55
55
 
56
56
  def multiple_context
57
- Oxidized.logger.debug 'Multi context tasks'
57
+ logger.debug 'Multi context tasks'
58
58
  cmd 'show virtual-system all' do |systems|
59
59
  vs_items = systems.scan(/^(?<VSID>\d+)\s+(?<VSNAME>.*[^\s])/)
60
60
  allcfg = ''
@@ -62,7 +62,7 @@ class GaiaOS < Oxidized::Model
62
62
  allcfg += "\n\n\n#--------======== [ VS #{item[0]} - #{item[1]} ] ========--------\n\n"
63
63
  allcfg += "set virtual-system #{item[0]}\n\n"
64
64
  cmd "set virtual-system #{item[0]}" do |vs|
65
- Oxidized.logger.debug vs
65
+ logger.debug vs
66
66
  cmd 'show configuration' do |vscfg|
67
67
  vscfg.gsub! /^# Exported by \S+ on .*/, '# '
68
68
  allcfg += vscfg
@@ -0,0 +1,38 @@
1
+ class Garderos < Oxidized::Model
2
+ using Refinements
3
+ # Garderos GmbH https://www.garderos.com/
4
+ # Routers for harsh environments
5
+ # grs = Garderos Router Software
6
+
7
+ prompt /[\w-]+# /
8
+ clean :escape_codes
9
+ comment '# '
10
+
11
+ cmd :all do |cfg|
12
+ # Remove the echo of the entered command and the prompt after it
13
+ cfg.cut_both
14
+ end
15
+
16
+ cmd 'show system version' do |cfg|
17
+ comment "#{cfg}\n"
18
+ end
19
+
20
+ cmd 'show system serial' do |cfg|
21
+ comment "#{cfg}\n"
22
+ end
23
+
24
+ # If we have a radio modem installed, we'd like to list the SIM Card
25
+ cmd 'show hardware wwan wwan0 sim' do |cfg|
26
+ if cfg.start_with? 'Unknown command'
27
+ String.new('')
28
+ else
29
+ comment "#{cfg}\n"
30
+ end
31
+ end
32
+
33
+ cmd 'show configuration running'
34
+
35
+ cfg :ssh do
36
+ pre_logout 'exit'
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ class GrandstreamHT8xx < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Anchored prompt to avoid matching XML content
5
+ prompt /^(GS|CONFIG)>\s?$/
6
+ comment '# '
7
+
8
+ cfg :ssh do
9
+ # After login go to configuration submenu (looks like enabled in other devices)
10
+ post_login 'config'
11
+ # When logout use double exit - first from configuration submenu, and second to disconnect from device
12
+ pre_logout 'exit'
13
+ pre_logout 'exit'
14
+ end
15
+
16
+ cmd 'export' do |cfg|
17
+ cfg.cut_both
18
+ end
19
+ end
@@ -3,7 +3,7 @@ class H3C < Oxidized::Model
3
3
 
4
4
  # H3C
5
5
 
6
- prompt /^.*(<[\w.-]+>)$/
6
+ prompt /^[<\[][\w.-]+[>\]]$/
7
7
  comment '# '
8
8
 
9
9
  cmd :secret do |cfg|
@@ -22,6 +22,7 @@ class IBOS < Oxidized::Model
22
22
 
23
23
  # radius server 10.1.1.1 secret public
24
24
  cfg.gsub! /^radius server (\S+) secret (\S+)(.*)/, 'radius server \\1 secret <hidden> \\3'
25
+ cfg
25
26
  end
26
27
 
27
28
  cmd 'show version' do |cfg|
@@ -0,0 +1,47 @@
1
+ class Ingate < Oxidized::Model
2
+ using Refinements
3
+
4
+ cfg_cb = lambda do
5
+ cfg = @m.post(
6
+ @main_url,
7
+ {
8
+ 'page' => 'save',
9
+ 'db.webgui.testmode/1/timelimit' => '30',
10
+ 'db.webgui.testmode/__KEEP_ROWS_ALIVE' => '1',
11
+ 'db.webgui.pending_apply/1/verbosity' => 'always',
12
+ 'db.webgui.pending_apply/__KEEP_ROWS_ALIVE' => '1',
13
+ 'action.admin.download_config_cli' => 'Save config to CLI file',
14
+ 'upload.config_file;filename=type' => 'application/octet-stream',
15
+ 'upload.clicmd_file;filename;type' => 'application/octet-stream',
16
+ 'security' => '',
17
+ 'got_complete_form' => 'yes'
18
+ },
19
+ 'Accept' => 'application/x-config-database'
20
+ )
21
+ cfg.body
22
+ end
23
+
24
+ cmd cfg_cb do |cfg|
25
+ cfg.gsub! /^# Timestamp:.*$/, ''
26
+ cfg
27
+ end
28
+
29
+ cfg :http do
30
+ @secure = true
31
+ @main_page = "/"
32
+ define_singleton_method :login do
33
+ @main_url = URI::HTTP.build host: @node.ip, path: @main_page
34
+ @m.post(
35
+ @main_url,
36
+ {
37
+ 'security_user' => @node.auth[:username],
38
+ 'security_password' => @node.auth[:password],
39
+ 'page' => 'login',
40
+ 'goal' => 'save',
41
+ 'got_complete_form' => 'yes',
42
+ 'security' => ''
43
+ }
44
+ )
45
+ end
46
+ end
47
+ end
@@ -27,26 +27,40 @@ class IOS < Oxidized::Model
27
27
 
28
28
  cmd :secret do |cfg|
29
29
  cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
30
- cfg.gsub! /^(snmp-server host \S+( vrf \S+)?( informs?)?( version (1|2c|3 (noauth|auth|priv)))?)\s+\S+((\s+\S*)*)\s*/, '\\1 <secret hidden> \\7'
30
+ cfg.gsub! /^(snmp-server host \S+( vrf \S+)?( informs?)?( version (1|2c))?) +\S+( .*)?$*/, '\\1 <secret hidden>\\6'
31
31
  cfg.gsub! /^(username .+ (password|secret) \d) .+/, '\\1 <secret hidden>'
32
32
  cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>'
33
- cfg.gsub! /^(\s+(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
33
+ cfg.gsub! /^( +(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
34
34
  cfg.gsub! /^(.*wpa-psk ascii \d) (\S+)/, '\\1 <secret hidden>'
35
35
  cfg.gsub! /^(.*key 7) (\d.+)/, '\\1 <secret hidden>'
36
36
  cfg.gsub! /^(tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
37
37
  cfg.gsub! /^(crypto isakmp key) (\S+) (.*)/, '\\1 <secret hidden> \\3'
38
- cfg.gsub! /^(\s+ip ospf message-digest-key \d+ md5) .+/, '\\1 <secret hidden>'
39
- cfg.gsub! /^(\s+ip ospf authentication-key) .+/, '\\1 <secret hidden>'
40
- cfg.gsub! /^(\s+neighbor \S+ password) .+/, '\\1 <secret hidden>'
41
- cfg.gsub! /^(\s+vrrp \d+ authentication text) .+/, '\\1 <secret hidden>'
42
- cfg.gsub! /^(\s+standby \d+ authentication) .{1,8}$/, '\\1 <secret hidden>'
43
- cfg.gsub! /^(\s+standby \d+ authentication md5 key-string) .+?( timeout \d+)?$/, '\\1 <secret hidden> \\2'
44
- cfg.gsub! /^(\s+key-string) .+/, '\\1 <secret hidden>'
45
- cfg.gsub! /^((tacacs|radius) server [^\n]+\n(\s+[^\n]+\n)*\s+key) [^\n]+$/m, '\1 <secret hidden>'
46
- cfg.gsub! /^(\s+ppp (chap|pap) password \d) .+/, '\\1 <secret hidden>'
38
+ cfg.gsub! /^( +ip ospf message-digest-key \d+ md5) .+/, '\\1 <secret hidden>'
39
+ cfg.gsub! /^( +ip ospf authentication-key) .+/, '\\1 <secret hidden>'
40
+ cfg.gsub! /^( +neighbor \S+ password) .+/, '\\1 <secret hidden>'
41
+ cfg.gsub! /^( +vrrp \d+ authentication text) .+/, '\\1 <secret hidden>'
42
+ cfg.gsub! /^( +standby \d+ authentication) .{1,8}$/, '\\1 <secret hidden>'
43
+ cfg.gsub! /^( +standby \d+ authentication md5 key-string) .+?( timeout \d+)?$/, '\\1 <secret hidden> \\2'
44
+ cfg.gsub! /^( +key-string) .+/, '\\1 <secret hidden>'
45
+ cfg.gsub! /^((tacacs|radius) server [^\n]+\n( +[^\n]+\n)* +key) [^\n]+$/m, '\1 <secret hidden>'
46
+ cfg.gsub! /^( +ppp (chap|pap) password \d) .+/, '\\1 <secret hidden>'
47
+ cfg.gsub! /^( +security wpa psk set-key (?:ascii|hex) \d) (.*)$/, '\\1 <secret hidden>'
48
+ cfg.gsub! /^( +dot1x username \S+ password \d) (.*)$/, '\\1 <secret hidden>'
49
+ cfg.gsub! /^( +mgmtuser username \S+ password \d) (.*) (secret \d) (.*)$/, '\\1 <secret hidden> \\3 <secret hidden>'
50
+ cfg.gsub! /^( +client \S+ server-key \d) (.*)$/, '\\1 <secret hidden>'
51
+ cfg.gsub! /^( +domain-password) \S+ ?(.*)/, '\\1 <secret hidden> \\2'
52
+ cfg.gsub! /^( +pre-shared-key).*/, '\\1 <configuration removed>'
53
+ cfg.gsub! /^(.*server-key(?: \d)?) \S+/, '\\1 <secret hidden>'
47
54
  cfg
48
55
  end
49
56
 
57
+ cmd :significant_changes do |cfg|
58
+ cfg.reject_lines [
59
+ /^! (Last|No) configuration change (at|since)/,
60
+ '! NVRAM config last updated at'
61
+ ]
62
+ end
63
+
50
64
  cmd 'show version' do |cfg|
51
65
  comments = []
52
66
  comments << cfg.lines.first
@@ -62,19 +76,27 @@ class IOS < Oxidized::Model
62
76
 
63
77
  comments << "Image:#{slave} Compiled: #{Regexp.last_match(1)}" if line =~ /^Compiled (.*)$/
64
78
 
65
- comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}" if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
79
+ if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
80
+ comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}"
81
+ end
66
82
 
67
- comments << "ROM Bootstrap: #{Regexp.last_match(3)}" if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
83
+ if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
84
+ comments << "ROM Bootstrap: #{Regexp.last_match(3)}"
85
+ end
68
86
 
69
87
  comments << "BOOTFLASH: #{Regexp.last_match(1)}" if line =~ /^BOOTFLASH: .*(Version.*)$/
70
88
 
71
89
  comments << "Memory: nvram #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/
72
90
 
73
- comments << "Memory: flash #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
91
+ if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
92
+ comments << "Memory: flash #{Regexp.last_match(1)}"
93
+ end
74
94
 
75
- comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i
95
+ if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i
96
+ comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}"
97
+ end
76
98
 
77
- if line =~ /(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
99
+ if line =~ /(\S+(?:\sseries)?)\s+(?:\(([\S ]+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
78
100
  sproc = Regexp.last_match(1)
79
101
  cpu = Regexp.last_match(2)
80
102
  mem = Regexp.last_match(3)
@@ -85,11 +107,13 @@ class IOS < Oxidized::Model
85
107
  comments << "Processor ID: #{Regexp.last_match(1)}" if cfg.lines[i + 1] =~ /processor board id (\S+)/i
86
108
  if cfg.lines[i + 2] =~ /(cpu at |processor: |#{cpu} processor,)/i
87
109
  # change implementation to impl and prepend comma
88
- cpuxtra = cfg.lines[i + 2].gsub(/implementation/, 'impl').gsub(/^/, ', ').chomp
110
+ cpuxtra = cfg.lines[i + 2].gsub("implementation", 'impl').gsub(/^/, ', ').chomp
89
111
  end
90
112
  comments << "CPU:#{slave} #{cpu}#{cpuxtra}#{slaveslot}"
91
113
  end
92
114
 
115
+ comments << line.chomp if line.start_with?('Motherboard')
116
+
93
117
  comments << "Image: #{Regexp.last_match(1)}" if line =~ /^System image file is "([^"]*)"$/
94
118
  end
95
119
  comments << "\n"
@@ -111,13 +135,22 @@ class IOS < Oxidized::Model
111
135
  cmd_line = 'show running-config'
112
136
  cmd_line += ' view full' if vars(:ios_rbac)
113
137
  cmd cmd_line do |cfg|
114
- cfg = cfg.each_line.to_a[3..-1]
115
- cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
116
- cfg = cfg.each_line.reject { |line| line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/ }.join
117
- cfg.gsub! /^Current configuration : [^\n]*\n/, ''
138
+ cfg = cfg.cut_head(3)
139
+ cfg = cfg.reject_lines [
140
+ /^ntp clock-period /,
141
+ /^Current configuration : \S+/
142
+ ]
143
+ unless vars("output_store_mode") == "on_significant"
144
+ cfg = cfg.reject_lines [
145
+ # Only store the line "configuration change" when a user is specified
146
+ /^! (Last|No) configuration change (at|since)(?!.*\d+ by \S+$)/
147
+ ]
148
+ end
118
149
  cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
119
150
  (?: [^\n]*\n*)*
120
151
  tunnel mpls traffic-eng auto-bw)/mx, '\1'
152
+ # get rid of values of custom SNMP OID's
153
+ cfg.gsub! /^(\s+expression) \d+$/, '\\1 <value removed>'
121
154
  cfg
122
155
  end
123
156
  end
@@ -128,17 +161,11 @@ class IOS < Oxidized::Model
128
161
  end
129
162
 
130
163
  cfg :telnet, :ssh do
131
- # preferred way to handle additional passwords
132
- post_login do
133
- if vars(:enable) == true
134
- cmd "enable"
135
- elsif vars(:enable)
136
- cmd "enable", /^[pP]assword:/
137
- cmd vars(:enable)
138
- end
139
- end
140
164
  post_login 'terminal length 0'
141
165
  post_login 'terminal width 0'
142
166
  pre_logout 'exit'
143
167
  end
168
+
169
+ # preferred way to handle additional passwords (enable)
170
+ macro :enable
144
171
  end
@@ -16,7 +16,7 @@ class IOSXR < Oxidized::Model
16
16
  cfg
17
17
  end
18
18
 
19
- cmd 'show inventory' do |cfg|
19
+ cmd 'show inventory all' do |cfg|
20
20
  comment cfg
21
21
  end
22
22
 
@@ -25,7 +25,7 @@ class IOSXR < Oxidized::Model
25
25
  end
26
26
 
27
27
  cmd 'show running-config' do |cfg|
28
- cfg = cfg.each_line.to_a[3..-1].join
28
+ cfg = cfg.each_line.to_a[1..-1].join
29
29
  cfg
30
30
  end
31
31