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
@@ -1,28 +1,17 @@
1
1
  # Configuration
2
2
 
3
- ## Debugging
4
-
5
- In case a model plugin doesn't work correctly (ios, procurve, etc.), you can enable live debugging of SSH/Telnet sessions. Just add a `debug` option containing the value true to the `input` section. The log files will be created depending on the parent directory of the logfile option.
6
-
7
- The following example will log an active ssh/telnet session `/home/oxidized/.config/oxidized/log/<IP-Address>-<PROTOCOL>`. The file will be truncated on each consecutive ssh/telnet session, so you need to put a `tailf` or `tail -f` on that file!
8
-
9
- ```yaml
10
- log: /home/oxidized/.config/oxidized/log
11
-
12
- ...
13
-
14
- input:
15
- default: ssh, telnet
16
- debug: true
17
- ssh:
18
- secure: false
19
- http:
20
- ssl_verify: true
21
- ```
3
+ ## Modules
4
+ The configuration of each module is described in its respective sub-configuration file:
5
+ * [Inputs.md](Inputs.md)
6
+ * [Outputs.md](Outputs.md)
7
+ * [Sources.md](Sources.md)
8
+ * [Hooks.md](Hooks.md)
22
9
 
23
10
  ## Privileged mode
24
11
 
25
- To start privileged mode before pulling the configuration, Oxidized needs to send the enable command. You can globally enable this, by adding the following snippet to the global section of the configuration file.
12
+ To start privileged mode before pulling the configuration, Oxidized needs to
13
+ send the enable command. You can globally enable this, by adding the following
14
+ snippet to the global section of the configuration file.
26
15
 
27
16
  ```yaml
28
17
  vars:
@@ -31,21 +20,24 @@ vars:
31
20
 
32
21
  ## Removing secrets
33
22
 
34
- To strip out secrets from configurations before storing them, Oxidized needs the `remove_secret` flag. You can globally enable this by adding the following snippet to the global section of the configuration file.
23
+ To strip out secrets from configurations before storing them, Oxidized needs the
24
+ `remove_secret` flag. You can globally enable this by adding the following
25
+ snippet to the global section of the configuration file.
35
26
 
36
27
  ```yaml
37
28
  vars:
38
29
  remove_secret: true
39
30
  ```
40
31
 
41
- Device models that contain substitution filters to remove sensitive data will now be run on any fetched configuration.
32
+ Device models that contain substitution filters to remove sensitive data will
33
+ now be run on any fetched configuration.
42
34
 
43
35
  As a partial example from ios.rb:
44
36
 
45
37
  ```ruby
46
38
  cmd :secret do |cfg|
47
39
  cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
48
- (...)
40
+ # ...
49
41
  cfg
50
42
  end
51
43
  ```
@@ -54,135 +46,43 @@ The above strips out snmp community strings from your saved configs.
54
46
 
55
47
  **NOTE:** Removing secrets reduces the usefulness as a full configuration backup, but it may make sharing configs easier.
56
48
 
57
- ## Disabling SSH exec channels
58
-
59
- Oxidized uses exec channels to make information extraction simpler, but there are some situations where this doesn't work well, e.g. configuring devices. This feature can be turned off by setting the `ssh_no_exec`
60
- variable.
61
-
62
- ```yaml
63
- vars:
64
- ssh_no_exec: true
65
- ```
49
+ ## Timeout and Time limit
50
+ You can configure when oxidized will `timeout` while fetching a configuration
51
+ (default: 20 seconds), and how much absolute time (`timelimit`) the fetching
52
+ is allowed to last (default: 300 seconds, or 5 minutes):
66
53
 
67
- ## Disabling SSH keepalives
54
+ * `timeout`: Maximum time to wait for a single operation during config fetching.
55
+ Not every input module has an implemented timeout.
56
+ * `timelimit`: Maximum total time allowed for the entire fetch job. It is
57
+ independent of input modules and will always be enforced.
68
58
 
69
- Oxidized SSH input makes use of SSH keepalives to prevent timeouts from slower devices and to quickly tear down stale sessions in larger deployments. There have been reports of SSH keepalives breaking compatibility with certain OS types. They can be disabled using the `ssh_no_keepalive` variable on a per-node basis (by specifying it in the source) or configured application-wide.
59
+ If `timelimit`is reached, the fetch job will be killed and will produce a
60
+ warning. The job status will be set to `timelimit`.
70
61
 
71
62
  ```yaml
72
- vars:
73
- ssh_no_keepalive: true
74
- ```
75
-
76
- ## SSH Auth Methods
77
-
78
- By default, Oxidized registers the following auth methods: `none`, `publickey` and `password`. However you can configure this globally, by groups, models or nodes.
79
-
80
- ```yaml
81
- vars:
82
- auth_methods: [ "none", "publickey", "password", "keyboard-interactive" ]
83
- ```
84
-
85
- ## Public Key Authentication with SSH
86
-
87
- Instead of password-based login, Oxidized can make use of key-based SSH authentication.
88
-
89
- You can tell Oxidized to use one or more private keys globally, or specify the key to be used on a per-node basis. The latter can be done by mapping the `ssh_keys` variable through the active source.
90
-
91
- Global:
92
-
93
- ```yaml
94
- vars:
95
- ssh_keys: "~/.ssh/id_rsa"
96
- ```
97
-
98
- Per-Node:
99
-
100
- ```yaml
101
- ...
102
- map:
103
- name: 0
104
- model: 1
105
- vars_map:
106
- enable: 2
107
- ssh_keys: 3
108
- ...
109
- ```
110
-
111
- If you are using a non-standard path, especially when copying the private key via a secured channel, make sure that the permissions are set correctly:
112
-
113
- ```bash
114
- foo@bar:~$ ls -la ~/.ssh/
115
- total 20
116
- drwx------ 2 oxidized oxidized 4096 Mar 13 17:03 .
117
- drwx------ 5 oxidized oxidized 4096 Mar 13 21:40 ..
118
- -r-------- 1 oxidized oxidized 103 Mar 13 17:03 authorized_keys
119
- -rw------- 1 oxidized oxidized 399 Mar 13 17:02 id_ed25519
120
- -rw-r--r-- 1 oxidized oxidized 94 Mar 13 17:02 id_ed25519.pub
121
- ```
122
-
123
- Finally, multiple private keys can be specified as an array of file paths, such as `["~/.ssh/id_rsa", "~/.ssh/id_another_rsa"]`.
124
-
125
- ## SSH Proxy Command
126
-
127
- Oxidized can `ssh` through a proxy as well. To do so we just need to set `ssh_proxy` variable with the proxy host information and optionally set the `ssh_proxy_port` with the SSH port if it is not listening on port 22.
128
-
129
- This can be provided on a per-node basis by mapping the proper fields from your source.
130
-
131
- An example for a `csv` input source that maps the 4th field as the `ssh_proxy` value and the 5th field as `ssh_proxy_port`.
132
-
133
- ```yaml
134
- ...
135
- map:
136
- name: 0
137
- model: 1
138
- vars_map:
139
- enable: 2
140
- ssh_proxy: 3
141
- ssh_proxy_port: 4
142
- ...
143
- ```
144
-
145
- ## SSH enabling legacy algorithms
146
-
147
- When connecting to older firmware over SSH, it is sometimes necessary to enable legacy/disabled settings like KexAlgorithms, HostKeyAlgorithms, MAC or the Encryption.
148
-
149
- These settings can be provided on a per-node basis by mapping the ssh_kex, ssh_host_key, ssh_hmac and the ssh_encryption fields from you source.
150
-
151
- ```yaml
152
- ...
153
- map:
154
- name: 0
155
- model: 1
156
- vars_map:
157
- enable: 2
158
- ssh_kex: 3
159
- ssh_host_key: 4
160
- ssh_hmac: 5
161
- ssh_encryption: 6
162
- ...
63
+ timeout: 20
64
+ timelimit: 300
163
65
  ```
164
66
 
165
- ## FTP Passive Mode
67
+ ## Advanced Configuration
166
68
 
167
- Oxidized uses ftp passive mode by default. Some devices require passive mode to be disabled. To do so, we can set `input.ftp.passive` to false - this will make use of FTP active mode.
69
+ Below is an advanced example configuration.
168
70
 
169
- ```yaml
170
- input:
171
- ftp:
172
- passive: false
173
- ```
71
+ You will be able to (optionally) override options per device.
72
+ The router.db format used is `hostname:model:username:password:enable_password`.
73
+ Hostname and model will be the only required options, all others override the
74
+ global configuration sections.
174
75
 
175
- ## Advanced Configuration
76
+ Custom model names can be mapped to an oxidized model name with a string or
77
+ a regular expression.
176
78
 
177
- Below is an advanced example configuration. You will be able to (optionally) override options per device. The router.db format used is `hostname:model:username:password:enable_password`. Hostname and model will be the only required options, all others override the global configuration sections.
178
79
 
179
80
  ```yaml
180
81
  ---
181
82
  username: oxidized
182
83
  password: S3cr3tx
183
84
  model: junos
184
- interval: 3600 #interval in seconds
185
- log: ~/.config/oxidized/log
85
+ interval: 3600 #interval in seconds, when 0 is configured no fetch config is done at initial start and after
186
86
  debug: false
187
87
  threads: 30 # maximum number of threads
188
88
  # use_max_threads:
@@ -190,6 +90,7 @@ threads: 30 # maximum number of threads
190
90
  # true - always use the maximum number of threads
191
91
  use_max_threads: false
192
92
  timeout: 20
93
+ timelimit: 300
193
94
  retries: 3
194
95
  prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
195
96
  crash:
@@ -198,7 +99,21 @@ crash:
198
99
  vars:
199
100
  enable: S3cr3tx
200
101
  groups: {}
201
- rest: 127.0.0.1:8888
102
+ extensions:
103
+ oxidized-web:
104
+ load: true
105
+ # Bind to any IPv4 interface
106
+ listen: 0.0.0.0
107
+ # Bind to port 8888 (default)
108
+ port: 8888
109
+ # Prefix prod to the URL, so http://oxidized.full.domain/prod/
110
+ url_prefix: prod
111
+ # virtual hosts to listen to (others will be denied)
112
+ vhosts:
113
+ - localhost
114
+ - 127.0.0.1
115
+ - oxidized
116
+ - oxidized.full.domain
202
117
  pid: ~/.config/oxidized/oxidized.pid
203
118
  input:
204
119
  default: ssh, telnet
@@ -226,6 +141,17 @@ source:
226
141
  model_map:
227
142
  cisco: ios
228
143
  juniper: junos
144
+ !ruby/regexp /procurve/: procurve
145
+ logger:
146
+ # The default level is :info
147
+ # level: :info
148
+ appenders:
149
+ - type: syslog
150
+ level: :error
151
+ - type: stdout
152
+ level: :warn
153
+ - type: file
154
+ file: ~/.config/oxidized/info.log
229
155
  ```
230
156
 
231
157
  ## Advanced Group Configuration
@@ -242,13 +168,15 @@ groups:
242
168
  password: ubnt
243
169
  ```
244
170
 
245
- Model specific variables within groups
171
+ Model specific variables/credentials within groups
246
172
 
247
173
  ```yaml
248
174
  groups:
249
175
  foo:
250
176
  models:
251
177
  arista:
178
+ username: admin
179
+ password: password
252
180
  vars:
253
181
  ssh_keys: "~/.ssh/id_rsa_foo_arista"
254
182
  vyatta:
@@ -260,11 +188,14 @@ groups:
260
188
  vars:
261
189
  ssh_keys: "~/.ssh/id_rsa_bar_routeros"
262
190
  vyatta:
191
+ username: admin
192
+ password: pass
263
193
  vars:
264
194
  ssh_keys: "~/.ssh/id_rsa_bar_vyatta"
265
195
  ```
266
196
 
267
- For mapping multiple group values to a common name
197
+ For mapping multiple group values to a common name, you can use strings and
198
+ regular expressions:
268
199
 
269
200
  ```yaml
270
201
  group_map:
@@ -272,17 +203,18 @@ group_map:
272
203
  alias2: groupA
273
204
  alias3: groupB
274
205
  alias4: groupB
206
+ !ruby/regexp /specialgroup/: groupS
275
207
  aliasN: groupZ
276
- ...
208
+ # ...
277
209
  ```
278
210
 
279
211
  add group mapping to a source
280
212
 
281
213
  ```yaml
282
214
  source:
283
- ...
215
+ # ...
284
216
  <source>:
285
- ...
217
+ # ...
286
218
  map:
287
219
  model: 0
288
220
  name: 1
@@ -311,25 +243,109 @@ models:
311
243
  password: pass
312
244
  ```
313
245
 
314
- ## RESTful API and Web Interface
246
+ ## Options (credentials, vars, etc.) precedence:
247
+ From least to most important:
248
+ - global options
249
+ - model specific options
250
+ - group specific options
251
+ - model specific options in groups
252
+ - options defined on single nodes
253
+
254
+ More important options overwrite less important ones if they are set.
255
+
256
+ ## oxidized-web: RESTful API and web interface
257
+
258
+ The RESTful API and web interface are enabled by installing the `oxidized-web`
259
+ gem and configuring the `extensions.oxidized-web:` section in the configuration
260
+ file. You can set the following parameter:
261
+ - `load`: `true`/`false`: Enables or disables the `oxidized-web` extension
262
+ (default: `false`)
263
+ - `listen`: Specifies the interface to bind to (default: `127.0.0.1`). Valid
264
+ options:
265
+ - `127.0.0.1`: Allows IPv4 connections from localhost only
266
+ - `'[::1]'`: Allows IPv6 connections from localhost only
267
+ - `<IPv4-Address>` or `'[<IPv6-Address>]'`: Binds to a specific interface
268
+ - `0.0.0.0`: Binds to any IPv4 interface
269
+ - `'[::]'`: Binds to any IPv4 and IPv6 interface
270
+ - `port`: Specifies the TCP port to listen to (default: `8888`)
271
+ - `url_prefix`: Defines a URL prefix (default: no prefix)
272
+ - `vhosts`: A list of virtual hosts to listen to. If not specified, it will
273
+ respond to any virtual host.
274
+
275
+ > [!NOTE]
276
+ > The old syntax `rest: 127.0.0.1:8888/prefix` is still supported but
277
+ > deprecated. It produces a warning and won't be suported in future releases.
278
+ >
279
+ > If the `rest` configuration is used, the extensions.oxidized-web will be
280
+ > ignored.
281
+
282
+ > [!NOTE]
283
+ > You need oxidized-web version 0.16.0 or later to use the
284
+ > extentions.oxidized-web configuration
285
+
315
286
 
316
- The RESTful API and Web Interface is enabled by configuring the `rest:` parameter in the config file. This parameter can optionally contain a relative URI.
287
+ ```yaml
288
+ # Listen on http://[::1]:8888/
289
+ extensions:
290
+ oxidized-web:
291
+ load: true
292
+ listen: '[::1]'
293
+ port: 8888
294
+ ```
317
295
 
318
296
  ```yaml
319
297
  # Listen on http://127.0.0.1:8888/
320
- rest: 127.0.0.1:8888
298
+ extensions:
299
+ oxidized-web:
300
+ load: true
301
+ listen: 127.0.0.1
302
+ port: 8888
303
+ ```
304
+
305
+ ```yaml
306
+ # Listen on http://[2001:db8:0:face:b001:0:dead:beaf]:8888/oxidized/
307
+ extensions:
308
+ oxidized-web:
309
+ load: true
310
+ listen: '[2001:db8:0:face:b001:0:dead:beaf]'
311
+ port: 8888
312
+ url_prefix: oxidized
321
313
  ```
322
314
 
323
315
  ```yaml
324
316
  # Listen on http://10.0.0.1:8000/oxidized/
325
- rest: 10.0.0.1:8000/oxidized
317
+ extensions:
318
+ oxidized-web:
319
+ load: true
320
+ listen: 10.0.0.1
321
+ port: 8000
322
+ url_prefix: oxidized
323
+ ```
324
+
325
+ ```yaml
326
+ # Listen on any interface to http://oxidized.rocks:8888 and
327
+ # http://oxidized:8888
328
+ extensions:
329
+ oxidized-web:
330
+ load: true
331
+ listen: '[::]'
332
+ url_prefix: oxidized
333
+ vhosts:
334
+ - oxidized.rocks
335
+ - oxidized
326
336
  ```
327
337
 
328
338
  ## Triggered backups
329
339
 
330
- A node can be moved to head-of-queue via the REST API `GET/POST /node/next/[NODE]`. This can be useful to immediately schedule a fetch of the configuration after some other event such as a syslog message indicating a configuration update on the device.
340
+ A node can be moved to head-of-queue via the REST API `GET/PUT
341
+ /node/next/[NODE]`. This can be useful to immediately schedule a fetch of the
342
+ configuration after some other event such as a syslog message indicating a
343
+ configuration update on the device.
331
344
 
332
- In the default configuration this node will be processed when the next job worker becomes available, it could take some time if existing backups are in progress. To execute moved jobs immediately a new job can be added automatically:
345
+ In the default configuration this node will be processed when the next job
346
+ worker becomes available, it could take some time if existing backups are in
347
+ progress. To execute moved jobs immediately a new job can be added
348
+ automatically:
333
349
 
334
350
  ```yaml
335
351
  next_adds_job: true
@@ -339,7 +355,10 @@ This will allow for a more timely fetch of the device configuration.
339
355
 
340
356
  ## Disabling DNS resolution
341
357
 
342
- In some instances it might not be desirable to attempt to resolve names of nodes. One such use case is when nodes are accessed through an SSH proxy, where the remote end resolves the names differently than the host on which Oxidized runs would.
358
+ In some instances it might not be desirable to attempt to resolve names of
359
+ nodes. One such use case is when nodes are accessed through an SSH proxy, where
360
+ the remote end resolves the names differently than the host on which Oxidized
361
+ runs would.
343
362
 
344
363
  Names can instead be passed verbatim to the input:
345
364
 
@@ -353,3 +372,217 @@ You can use some environment variables to change default root directories values
353
372
 
354
373
  * `OXIDIZED_HOME` may be used to set oxidized configuration directory, which defaults to `~/.config/oxidized`
355
374
  * `OXIDIZED_LOGS` may be used to set oxidzied logs and crash directories root, which default to `~/.config/oxidized`
375
+
376
+ ## Logging
377
+ Oxidized supports parallel logging to different systems (appenders). The
378
+ following appenders are currently supported:
379
+ - `stderr`: log to standard error (this is the default)
380
+ - `stdout`: log to standard output
381
+ - `file`: log to a file
382
+ - `syslog`: log to syslog
383
+
384
+ > `stderr` and `stdout` are mutually exclusive and will produce a warning if used
385
+ > simultaneously.
386
+
387
+ > You can configure as many file appenders as you wish.
388
+
389
+ You can set a log level globally and/or for each appender.
390
+ - The global log level will limit which log messages are accepted, depending
391
+ on their level.
392
+ - The default global log level is `:info`.
393
+ - If you set `debug: true` in the configuration, the global log level will be
394
+ forced to `:debug`.
395
+ - The appender log level limits which log messages are displayed by the
396
+ appender, depending on their level.
397
+ - The default is `:trace`.
398
+
399
+
400
+ > Available log levels: `:trace`, `:debug`, `:info`, `:warn`,
401
+ > `:error` and `:fatal`
402
+
403
+ Here is a configuration example logging `:error` to syslog, `:warn` to stdout
404
+ and `:info` to `~/.config/oxidized/info.log`:
405
+
406
+ ```yaml
407
+ logger:
408
+ # Default level
409
+ # level: :info
410
+ appenders:
411
+ - type: syslog
412
+ level: :error
413
+ - type: stdout
414
+ level: :warn
415
+ - type: file
416
+ # Default level is :trace, so we get the logs in the default level (:info)
417
+ file: ~/.config/oxidized/info.log
418
+ ```
419
+
420
+ If you want to log :trace to a file and `:info` to stdout, you must set the
421
+ global log level to `:trace`, and limit the stdout appender to `:info`:
422
+
423
+ ```yaml
424
+ logger:
425
+ level: :trace
426
+ appenders:
427
+ - type: stdout
428
+ level: :info
429
+ - type: file
430
+ file: ~/.config/oxidized/trace.log
431
+ ```
432
+
433
+ ### Change log level
434
+ You can change the global log level of oxidized by sending a SIGUSR2 to
435
+ the process:
436
+ ```
437
+ kill -SIGUSR2 424242
438
+ ```
439
+ It will rotate between the log levels and log a warning with the new level
440
+ (you won't see the warning when the log level is `:fatal` or `:error`):
441
+ ```
442
+ 2025-06-30 15:25:27.972881 W [109750:2640] SemanticLogger -- Changed global default log level to :warn
443
+ ```
444
+
445
+ If you specified a log level for an appender, this log level won't be
446
+ changed.
447
+
448
+ > :warning: **Warning** You need oxidized-web 0.17.0 and above for this or
449
+ > it will kill the whole oxidized application.
450
+
451
+ ### Dump running threads
452
+ With the SIGTTIN signal, oxidized will log a backtrace for each of its threads.
453
+ ```
454
+ kill -SIGTTIN 424242
455
+ ```
456
+
457
+ The threads used to fetch the configs are named `Oxidized::Job 'hostname'`:
458
+
459
+ ```
460
+ 2025-06-30 15:32:22.293047 W [110549:2640 core.rb:76] Thread Dump -- Backtrace:
461
+ /home/xxx/oxidized/lib/oxidized/core.rb:76:in `sleep'
462
+ /home/xxx/oxidized/lib/oxidized/core.rb:76:in `block in run'
463
+ (...)
464
+ 2025-06-30 15:32:22.293409 W [110549:Oxidized::Job 'host2' ssh.rb:127] Thread Dump -- Backtrace:
465
+ /home/xxx/oxidized/lib/oxidized/input/ssh.rb:127:in `sleep'
466
+ /home/xxx/oxidized/lib/oxidized/input/ssh.rb:127:in `block (2 levels) in expect'
467
+ ```
468
+
469
+ ## Metadata
470
+ You can include some metadata in your model outputs, for this you have to set
471
+ the variable `metadata` to `true`:
472
+ ```yaml
473
+ vars:
474
+ metadata: true
475
+ ```
476
+
477
+ As every [variable](#options-credentials-vars-etc-precedence), you can set it on
478
+ model, group and even node level.
479
+
480
+ By default this will produce
481
+ `"%{comment}Fetched by Oxidized with model %{model} from host %{name} [%{ip}]\n"`
482
+ at the first line of every model output. Some models with specific needs (XML
483
+ for example) will save the metadata differently (for example, OpnSense and
484
+ PfSense save an XML comment at the end of the model).
485
+
486
+ ### Customize metadata
487
+ You can customize the metadata produced by setting the varibles `metadata_top`
488
+ (top of the file) and `metadata_bottom` (bottom of the file).
489
+
490
+ These variables accept string templates, and you can include newline characters
491
+ (\n) to control formatting.
492
+
493
+ Both `metadata_top` and `metadata_bottom` support interpolation of dynamic values
494
+ using the following substitution templates:
495
+ - `%{model}`: name of the Oxidized model
496
+ - `%{name}`: name of the node
497
+ - `%{ip}`: IP address of the node
498
+ - `%{group}`: group name of the node
499
+ - `%{comment}`: comment string used in the model output (`# `)
500
+ - `%{year}`: current year (`2025`)
501
+ - `%{month}`: current month, zero-padded (`03` for March)
502
+ - `%{day}`: current day, zero-padded (`09`)
503
+ - `%{hour}`: current hour (24-hour format, zero-padded)
504
+ - `%{minute}`: current minute, zero-padded
505
+ - `%{second}`: current second, zero-padded
506
+
507
+ Example:
508
+ ```yaml
509
+ vars:
510
+ metadata: true
511
+ metadata_top: "%{comment}Model: %{model}; Device %{name} [%{ip}] at %{year}-%{month}-%{day} %{hour}:%{minute}:%{second}\n"
512
+ ```
513
+
514
+ ### Customize metadata in models
515
+ When writing a custom metadata for a model, you can default to
516
+ `vars("metadata_*")` or the model default. You need to interpolate the strings
517
+ with interpolate_string. This example is taken from OpnSense, and makes an
518
+ XML comment of the default strings, with precedence for vars("metadata_bottom"),
519
+ as the XML comment is situated at the bottom.
520
+
521
+ ```ruby
522
+ metadata :bottom do
523
+ xmlcomment interpolate_string(
524
+ vars("metadata_bottom") ||
525
+ vars("metadata_top") ||
526
+ Oxidized::Model::METADATA_DEFAULT
527
+ )
528
+ end
529
+ ```
530
+
531
+ You can also change the metadata in the models in your configuration directory with
532
+ [monkey patching](Creating-Models.md#monkey-patching-blocks-in-existing-models).
533
+ This can be done in two ways:
534
+
535
+ 1. Interpolation string:
536
+ ```ruby
537
+ require 'oxidized/model/ios.rb'
538
+
539
+ class IOS
540
+ metadata :top, "%{comment}Model: %{model}\n"
541
+ metadata :bottom, "%{comment}Will be placed at the end of the output\n"
542
+ end
543
+ ```
544
+
545
+ 2. For advanced code, you can use a code block, and access every variable of
546
+ the model:
547
+
548
+ ```ruby
549
+ require 'oxidized/model/opnsense.rb'
550
+ class OpnSense
551
+ metadata :top do
552
+ xmlcomment "Model:#{self.class.name}, hostname: #{@node.name}, ip:#{@node.ip}"
553
+ end
554
+
555
+ metadata :bottom, nil
556
+ end
557
+ ```
558
+
559
+ Remove a previous metadata by setting it to `nil`.
560
+
561
+ ## Store configuration only on significant changes
562
+ Some devices produce configuration changes even though nothing relevant
563
+ changed. For example, Cisco IOS produces a `Last configuration change at` as
564
+ soon as you exit config mode, and FortiOS encrypts its passwords with a
565
+ different salt on every run.
566
+
567
+ By setting the [variable](#options-credentials-vars-etc-precedence)
568
+ `output_store_mode` to `on_significant`, you can tell Oxidized only to
569
+ store the configuration when significant changes occurred. The default is to
570
+ always store the configuration.
571
+ ```yaml
572
+ vars:
573
+ output_store_mode: on_significant
574
+ ```
575
+
576
+ For this to work, the model must implement `cmd :significant_changes`:
577
+ ```ruby
578
+ cmd :significant_changes do |cfg|
579
+ cfg.reject_lines [
580
+ 'Last configuration change at',
581
+ 'NVRAM config last updated at'
582
+ ]
583
+ end
584
+ ```
585
+
586
+ Note that store on significant change only applies to the main configuration,
587
+ and will not affect
588
+ [output types](Creating-Models.md#advanced-feature-output-type)