oxidized 0.35.0 → 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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/.coderabbit.yaml +21 -0
  3. data/.github/workflows/publishdocker.yml +11 -9
  4. data/.github/workflows/ruby.yml +1 -3
  5. data/.rubocop.yml +16 -2
  6. data/.rubocop_todo.yml +21 -2
  7. data/CHANGELOG.md +76 -3
  8. data/README.md +2 -3
  9. data/Rakefile +1 -1
  10. data/docs/Configuration.md +40 -2
  11. data/docs/Creating-Models.md +129 -14
  12. data/docs/Docker.md +2 -1
  13. data/docs/Hooks.md +92 -67
  14. data/docs/Inputs.md +44 -12
  15. data/docs/Model-Notes/APC.md +72 -0
  16. data/docs/Model-Notes/ExaLink.md +43 -0
  17. data/docs/Model-Notes/Fortinet.md +75 -0
  18. data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
  19. data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
  20. data/docs/Model-Notes/RouterOS.md +13 -0
  21. data/docs/Model-Notes/TrueNAS.md +23 -0
  22. data/docs/ModelUnitTests.md +23 -0
  23. data/docs/Outputs.md +18 -4
  24. data/docs/Release.md +7 -2
  25. data/docs/Ruby-API.md +86 -5
  26. data/docs/Supported-OS-Types.md +21 -9
  27. data/docs/Troubleshooting.md +1 -1
  28. data/extra/device2yaml.rb +2 -3
  29. data/extra/hooks/modelrules.rb +55 -0
  30. data/extra/hooks/modelrulesadvanced.rb +167 -0
  31. data/extra/hooks/srcipmap.rb +54 -0
  32. data/lib/oxidized/cli/support.rb +152 -0
  33. data/lib/oxidized/cli.rb +9 -0
  34. data/lib/oxidized/hook/githubrepo.rb +2 -1
  35. data/lib/oxidized/hook.rb +58 -8
  36. data/lib/oxidized/input/debugtext.rb +40 -0
  37. data/lib/oxidized/input/debugyaml.rb +82 -0
  38. data/lib/oxidized/input/exec.rb +1 -10
  39. data/lib/oxidized/input/ftp.rb +0 -17
  40. data/lib/oxidized/input/http.rb +39 -21
  41. data/lib/oxidized/input/input.rb +33 -13
  42. data/lib/oxidized/input/scp.rb +10 -64
  43. data/lib/oxidized/input/ssh.rb +36 -79
  44. data/lib/oxidized/input/sshbase.rb +102 -0
  45. data/lib/oxidized/input/telnet.rb +12 -13
  46. data/lib/oxidized/input/tftp.rb +7 -7
  47. data/lib/oxidized/model/aoscx.rb +18 -12
  48. data/lib/oxidized/model/aosw.rb +10 -11
  49. data/lib/oxidized/model/apc_aos.rb +4 -0
  50. data/lib/oxidized/model/apcaos.rb +39 -0
  51. data/lib/oxidized/model/arubainstant.rb +11 -20
  52. data/lib/oxidized/model/asa.rb +7 -7
  53. data/lib/oxidized/model/comware.rb +3 -1
  54. data/lib/oxidized/model/cumulus.rb +3 -3
  55. data/lib/oxidized/model/defacto.rb +26 -0
  56. data/lib/oxidized/model/dlinknextgen.rb +1 -0
  57. data/lib/oxidized/model/dslcommands.rb +93 -0
  58. data/lib/oxidized/model/dslsetup.rb +102 -0
  59. data/lib/oxidized/model/efos.rb +5 -5
  60. data/lib/oxidized/model/exalink.rb +36 -0
  61. data/lib/oxidized/model/fastiron.rb +2 -2
  62. data/lib/oxidized/model/firelinuxos.rb +1 -3
  63. data/lib/oxidized/model/fortigate.rb +160 -0
  64. data/lib/oxidized/model/fortios.rb +28 -69
  65. data/lib/oxidized/model/fsos.rb +1 -3
  66. data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
  67. data/lib/oxidized/model/h3c.rb +1 -1
  68. data/lib/oxidized/model/ios.rb +23 -15
  69. data/lib/oxidized/model/ironware.rb +5 -3
  70. data/lib/oxidized/model/ivanti.rb +54 -0
  71. data/lib/oxidized/model/junos.rb +2 -2
  72. data/lib/oxidized/model/linuxgeneric.rb +4 -2
  73. data/lib/oxidized/model/macros.rb +60 -0
  74. data/lib/oxidized/model/mlnxos.rb +11 -7
  75. data/lib/oxidized/model/model.rb +28 -126
  76. data/lib/oxidized/model/ndms.rb +6 -0
  77. data/lib/oxidized/model/netgear.rb +5 -3
  78. data/lib/oxidized/model/nxos.rb +6 -3
  79. data/lib/oxidized/model/outputs.rb +5 -0
  80. data/lib/oxidized/model/perle.rb +14 -8
  81. data/lib/oxidized/model/routeros.rb +4 -0
  82. data/lib/oxidized/model/smartbyte.rb +48 -0
  83. data/lib/oxidized/model/tplink.rb +4 -6
  84. data/lib/oxidized/model/truenas.rb +63 -3
  85. data/lib/oxidized/model/voss.rb +3 -0
  86. data/lib/oxidized/model/vyos.rb +4 -1
  87. data/lib/oxidized/node.rb +25 -23
  88. data/lib/oxidized/nodes.rb +2 -0
  89. data/lib/oxidized/output/file.rb +7 -1
  90. data/lib/oxidized/output/git.rb +11 -1
  91. data/lib/oxidized/output/gitcrypt.rb +1 -1
  92. data/lib/oxidized/output/http.rb +12 -3
  93. data/lib/oxidized/source/csv.rb +5 -0
  94. data/lib/oxidized/source/jsonfile.rb +5 -0
  95. data/lib/oxidized/source/sql.rb +5 -0
  96. data/lib/oxidized/version.rb +2 -2
  97. data/lib/oxidized/worker.rb +36 -15
  98. data/lib/refinements.rb +18 -0
  99. data/oxidized.gemspec +28 -24
  100. metadata +103 -55
  101. data/docs/Model-Notes/APC_AOS.md +0 -65
  102. data/docs/Model-Notes/FortiOS.md +0 -44
data/docs/Hooks.md CHANGED
@@ -109,50 +109,102 @@ hooks:
109
109
 
110
110
  ## Hook type: githubrepo
111
111
 
112
- Note: You must not use the same name as any local repo configured under output. Make sure your 'git' output has a unique name that does not match your remote_repo.
112
+ The `githubrepo` hook executes a `git push` to a configured `remote_repo` when
113
+ the specified event is triggered.
113
114
 
114
- The `githubrepo` hook executes a `git push` to a configured `remote_repo` when the specified event is triggered.
115
+ ### Configuration keys
115
116
 
116
- Several authentication methods are supported:
117
+ | Key | Description |
118
+ |---------------|-------------|
119
+ | `remote_repo` | The remote repository to push to. Use a URL string (no groups) or a group dictionary (see [Using groups](#using-groups)). |
120
+ | `username` | Username for authentication. Defaults to the user part of the `remote_repo` URI, falling back to `git`. |
121
+ | `password` | Password for username/password authentication. |
122
+ | `privatekey` | Path to the private key file. Must be in legacy PEM format (see note below). |
123
+ | `publickey` | Path to the public key file (optional — inferred from `privatekey` + `.pub` if omitted). |
117
124
 
118
- * Provide a `password` for username + password authentication
119
- * Provide both a `publickey` and a `privatekey` for ssh key-based authentication
120
- * Provide only a `privatekey` (public key filename is assumed to be `privatekey` + "`.pub`"
121
- * Don't provide any credentials for ssh-agent authentication
125
+ Notes:
126
+ - `remote_repo` must not match the name of any local `git` output repo configured under `output`. Use unique names for each.
127
+ - If using SSH key authentication with a passphrase-protected private key, provide the passphrase with the `OXIDIZED_SSH_PASSPHRASE` environment variable.
128
+ - The `privatekey` must be in the legacy PEM format (`BEGIN RSA PRIVATE KEY`), not the newer OpenSSH format (`BEGIN OPENSSH PRIVATE KEY`). See [#1877](https://github.com/ytti/oxidized/issues/1877) and [#2324](https://github.com/ytti/oxidized/issues/2324).
129
+ - To convert an existing key to PEM format, run:
130
+ ```shell
131
+ ssh-keygen -p -m PEM -f $MY_KEY_HERE
132
+ ```
122
133
 
123
- The username will be set to the relevant part of the `remote_repo` URI, with a fallback to `git`. It is also possible to provide one by setting the `username` configuration key.
134
+ ### Authentication methods
124
135
 
125
- For ssh key-based authentication, it is possible to set the environment variable `OXIDIZED_SSH_PASSPHRASE` to a passphrase if the private key requires it.
136
+ Choose one of the following methods:
126
137
 
127
- `githubrepo` hook recognizes the following configuration keys:
138
+ | Method | Required keys |
139
+ |-------------------------------|---------------|
140
+ | Username + password | `username` (optional), `password` |
141
+ | SSH key pair | `privatekey`, `publickey` (optional - assumed to be at `privatekey` + `.pub`) |
142
+ | SSH agent | no credentials needed |
128
143
 
129
- * `remote_repo`: the remote repository to be pushed to.
130
- * `username`: username for repository auth.
131
- * `password`: password for repository auth.
132
- * `publickey`: public key file path for repository auth. (optional)
133
- * `privatekey`: private key file path for repository auth.
134
- * NOTE: this key needs to be in the legacy PEM format, not the newer OpenSSL format [#1877](https://github.com/ytti/oxidized/issues/1877), [#2324](https://github.com/ytti/oxidized/issues/2324)
135
- * To convert a key beginning with `BEGIN OPENSSH PRIVATE KEY` to the legacy PEM format, run this command:
136
- `ssh-keygen -p -m PEM -f $MY_KEY_HERE`
144
+ ### Configuration examples
137
145
 
138
- When using groups, `remote_repo` must be a dictionary of groups that the hook should apply to. If a group is missing from the dictionary, no action will be taken.
146
+ **Username and password:**
139
147
 
140
- The dictionary entry can either be a url alone:
148
+ ```yaml
149
+ hooks:
150
+ push_to_remote:
151
+ type: githubrepo
152
+ events: [post_store]
153
+ remote_repo: git@git.intranet:oxidized/test.git
154
+ username: user
155
+ password: pass
156
+ ```
157
+
158
+ **SSH key pair:**
141
159
 
142
160
  ```yaml
143
161
  hooks:
144
162
  push_to_remote:
163
+ type: githubrepo
164
+ events: [post_store]
165
+ remote_repo: git@git.intranet:oxidized/test.git
166
+ publickey: /root/.ssh/id_rsa.pub
167
+ privatekey: /root/.ssh/id_rsa
168
+ ```
169
+
170
+
171
+ **SSH agent:**
172
+
173
+ ```yaml
174
+ hooks:
175
+ push_to_remote:
176
+ type: githubrepo
177
+ events: [post_store]
178
+ remote_repo: git@git.intranet:oxidized/test.git
179
+ ```
180
+
181
+ ### Using groups
182
+
183
+ When using groups and `single_repo` is set to `true` (default) in the
184
+ configuration section output/git, `remote_repo` must be a dictionary mapping
185
+ group names to remote repositories. Groups not listed in the dictionary are
186
+ silently skipped.
187
+
188
+ Each entry can be either a plain URL string:
189
+
190
+ ```yaml
191
+ hooks:
192
+ push_to_remote:
193
+ type: githubrepo
194
+ events: [post_store]
145
195
  remote_repo:
146
196
  routers: git@git.intranet:oxidized/routers.git
147
197
  switches: git@git.intranet:oxidized/switches.git
148
198
  firewalls: git@git.intranet:oxidized/firewalls.git
149
199
  ```
150
200
 
151
- ... or it can be a dictionary with `url` and `privatekey` specified:
201
+ ...or a dictionary with `url` and `privatekey` to use a per-group SSH key:
152
202
 
153
203
  ```yaml
154
204
  hooks:
155
205
  push_to_remote:
206
+ type: githubrepo
207
+ events: [post_store]
156
208
  remote_repo:
157
209
  routers:
158
210
  url: git@git.intranet:oxidized/routers.git
@@ -165,58 +217,31 @@ hooks:
165
217
  privatekey: /root/.ssh/id_rsa_firewalls
166
218
  ```
167
219
 
168
- Both forms can be mixed and matched.
220
+ Both forms can be mixed within the same configuration.
169
221
 
170
- ### githubrepo hook configuration example
222
+ ### Custom branch name
171
223
 
172
- Authenticate with a username and a password without groups in use:
224
+ The `githubrepo` hook uses the branch name from the
225
+ [git output](Outputs.md#output-git) as the remote branch name. When the
226
+ repository is first created, Oxidized uses the default branch name from
227
+ `git config --global init.defaultBranch`. The default is `master`.
173
228
 
174
- ```yaml
175
- hooks:
176
- push_to_remote:
177
- type: githubrepo
178
- events: [post_store]
179
- remote_repo: git@git.intranet:oxidized/test.git
180
- username: user
181
- password: pass
182
- ```
229
+ You can manually rename the branch after Oxidized has already created the
230
+ repository. Be aware that you may break things, so make backups.
183
231
 
184
- Authenticate with the username `git` and an ssh key:
232
+ To rename the branch after Oxidized has already created the repository:
185
233
 
186
- ```yaml
187
- hooks:
188
- push_to_remote:
189
- type: githubrepo
190
- events: [post_store]
191
- remote_repo: git@git.intranet:oxidized/test.git
192
- publickey: /root/.ssh/id_rsa.pub
193
- privatekey: /root/.ssh/id_rsa
194
- ```
234
+ 1. Stop oxidized.
235
+ 2. Back up your oxidized git repository.
236
+ 3. Change to your oxidized git repository directory.
237
+ 4. Inspect the current branches: `git branch -avv`
238
+ 5. Rename the local branch: `git branch -m <NewName>`
239
+ 6. Remove the stale remote-tracking reference: `git branch -r -d origin/<OldName>`
240
+ 7. Verify the result: `git branch -avv`
241
+ 8. Restart oxidized.
195
242
 
196
- ### Custom branch name
197
- Githubrepo will use the branch name used in the
198
- [git output](Outputs.md#output-git) as a remote branch name. When creating the
199
- git repository for the first time, Oxidized uses the default branch name
200
- configured in git with `git config --global init.defaultBranch <Name>`. The
201
- default is `master`.
202
-
203
- If you need to rename the branch name after Oxidized has created it, you may do
204
- it manually. Be aware that you may break things. Make backups and do not
205
- complain if something goes wrong!
206
-
207
- 1. Stop oxidized (no one should access the git repository while doing the
208
- following steps)
209
- 2. Make a backup of your oxidized data, especially the git repository
210
- 3. Change directory to your oxidized git repository (as configured in oxidized
211
- configuration file)
212
- 4. Inspect the current branches with `git branch -avv`
213
- 5. Rename the default branch with `git branch -m <NewName>`
214
- 6. Remove the reference to the old remote branch with
215
- `git branch -r -d origin/<OldName>`
216
- 6. Inspect the change with `git branch -avv`
217
- 7. Restart oxidized - you're done!
218
-
219
- Note that you will also have to clean your remote git repository.
243
+ Oxidized will push to a new remote branch. When everything is fine, you can
244
+ remove the old branch from the remote repository.
220
245
 
221
246
  ## Hook type: awssns
222
247
 
data/docs/Inputs.md CHANGED
@@ -177,27 +177,59 @@ input:
177
177
  passive: false
178
178
  ```
179
179
 
180
+ ## HTTP
181
+ ### Supported HTTP Methods
180
182
 
181
- ## Debugging
183
+ The HTTP input supports the following HTTP methods:
184
+ - `:get` - for GET requests
185
+ - `:post` - for POST requests
182
186
 
183
- In case a model plugin doesn't work correctly (ios, procurve, etc.), you can
184
- enable live debugging of SSH/Telnet sessions. Just add a `debug` option
185
- containing the value true to the `input` section. The log files will be created
186
- depending on the parent directory of the logfile option.
187
+ These methods are used internally by models that require HTTP-based
188
+ configuration retrieval. Models can use `get_http()` and `post_http()` methods
189
+ provided by the HTTP input.
190
+
191
+ Example usage in a model:
192
+
193
+ ```ruby
194
+ cfg :http do
195
+ post_response = post_http('/some/path', payload, 'Some-Extra-Header' => 'value')
196
+ get_response = get_http('/some/path')
197
+ end
198
+ ```
187
199
 
188
- The following example will log an active ssh/telnet session
189
- `/home/oxidized/.config/oxidized/log/<IP-Address>-<PROTOCOL>`. The file will be
190
- truncated on each consecutive ssh/telnet session, so you need to put a `tailf`
191
- or `tail -f` on that file!
200
+ HTTP input can be enabled by adding this block to the configuration file:
192
201
 
193
202
  ```yaml
194
- log: /home/oxidized/.config/oxidized/log
203
+ input:
204
+ http:
205
+ scheme: https
206
+ ssl_verify: true
207
+ timeout: 30
208
+ ```
195
209
 
196
- # ...
210
+ ## Debugging
211
+ In case a model plugin doesn't work correctly (ios, procurve, etc.), you can
212
+ enable live debugging of SSH and Telnet sessions with the `debug` option of
213
+ the `input` section.
197
214
 
215
+ Starting with version 0.37.0, `debug` can take different values:
216
+ - `text`: log input and output to a text file (ssh, telnet)
217
+ - `yaml`: produce a yaml simulation file (ssh, scp)
218
+ - `library`: activate debug logging of the underlying library
219
+ - a combination of the options above (`text, yaml`)
220
+ - `true`; activate all debugging options (Only option for versions prior 0.37.0)
221
+
222
+ The log files will be created in `~/.config/oxidized/logs/` (or `$OXIDIZED_LOGS/logs/`).
223
+
224
+ The following example will log an active ssh/telnet session to
225
+ `~/.config/oxidized/logs/<IP-Address>-<PROTOCOL>-<timestamp>.txt` and for ssh
226
+ `~/.config/oxidized/logs/<IP-Address>-<PROTOCOL>-<timestamp>.yaml`. A new file
227
+ is created for each session.
228
+
229
+ ```yaml
198
230
  input:
199
231
  default: ssh, telnet
200
- debug: true
232
+ debug: yaml, text
201
233
  ssh:
202
234
  secure: false
203
235
  http:
@@ -0,0 +1,72 @@
1
+ # APC Configuration
2
+ The configuration of APC Network Management Cards can be downloaded using FTP
3
+ and SCP. You can retrieve serial numbers and OS version information through
4
+ an SSH connection.
5
+
6
+ APC OS does not have the ability to display the config.ini within an SSH shell.
7
+ A ticket was opened with APC support to enable "cat config.ini"
8
+ within an SSH shell, but APC declined to implement this feature.
9
+
10
+ To overcome this limitation, a capability to run against multiple inputs (SSH + SCP)
11
+ has been implemented in Oxidized and in the [model ApcAos](/lib/oxidized/model/apcaos.rb).
12
+
13
+ The old model apc_aos (SCP/FTP only) is deprecated and will be removed in a
14
+ future release. Migrate to ApcAos.
15
+
16
+ ## How do I activate FTP/SCP input?
17
+ To download the configuration with FTP or SCP, you must activate it
18
+ as an input in the Oxidized configuration. If you don't activate the input,
19
+ Oxidized will fail for the node with an error.
20
+
21
+ You probably also need to increase the default timeout to something about 60
22
+ seconds, as the APC are really slow, and need about 30 seconds to complete.
23
+
24
+ The configuration can be done either globally or only for the ApcAos model.
25
+
26
+ ### Global Configuration
27
+ The global configuration would look like this. Note that Oxidized will try every
28
+ input type in the given order until it succeeds, or it will report a failure.
29
+ ```yaml
30
+ timeout: 60
31
+ input:
32
+ default: ssh, ftp, scp
33
+ ```
34
+ The order in the configuration is relevant. With this configuration, the ApcAos
35
+ model will run SSH first, then it will try FTP, and if FTP fails SCP.
36
+
37
+ ### Model-Specific Configuration
38
+
39
+ Configuration for activating only the SCP input for ApcAos only:
40
+ ```yaml
41
+ input:
42
+ default: ssh
43
+ models:
44
+ apcaos:
45
+ input: ssh, scp
46
+ timeout: 60
47
+ ```
48
+
49
+ ### Setting Specific Credentials
50
+ You can also set a specific username and password for ApcAos only:
51
+ ```yaml
52
+ username: default-user
53
+ password: default-password
54
+ input:
55
+ default: ssh
56
+ models:
57
+ ApcAos:
58
+ username: apc-user
59
+ password: apc-password
60
+ input: ssh, scp
61
+ timeout: 60
62
+ ```
63
+
64
+ ## Why do I partially get CR + LF?
65
+ The config.ini file has a DOS-Format (CR + LF), and is saved without
66
+ modifications, so that it can be uploaded to the device.
67
+
68
+ Outputs from ssh are stored without CR, so the first part of the file is
69
+ without CR and config.ini with CR + LF.
70
+
71
+ This is expected behavior and should not affect the functionality of the backup
72
+ or restore process.
@@ -0,0 +1,43 @@
1
+ # Cisco Nexus 3550-F (ExaLink Fusion)
2
+
3
+ The Cisco Nexus 3550-F (formerly Exablaze ExaLink Fusion) is an ultra-low-latency
4
+ Layer 1/2 switch platform based on FPGA technology, primarily used in high-frequency
5
+ trading and HPC environments. It runs a custom Linux-based OS with a proprietary CLI
6
+ and JSON RPC API.
7
+
8
+ ## Device Configuration
9
+
10
+ Create a read-only user for Oxidized on the device:
11
+
12
+ ```
13
+ admin@N3550-F> configure user oxidized password <password>
14
+ admin@N3550-F> configure user oxidized privilege read-only
15
+ ```
16
+
17
+ ## Oxidized Configuration
18
+
19
+ ```yaml
20
+ source:
21
+ default: csv
22
+ csv:
23
+ file: "/home/oxidized/.config/oxidized/router.db"
24
+ delimiter: !ruby/regexp /:/
25
+ map:
26
+ name: 0
27
+ model: 1
28
+ ```
29
+
30
+ Example `router.db` entry:
31
+
32
+ ```bash
33
+ myswitch.example.com:exalink
34
+ ```
35
+
36
+ ## Notes
37
+
38
+ - Both SSH and Telnet are supported. SSH is recommended.
39
+ - The model collects `show version` (excluding uptime to avoid noisy diffs),
40
+ `show port`, and `show running-config`.
41
+ - Timestamps (`!Time:`) are stripped from the running config to avoid noisy diffs.
42
+ - The device prompt format is `hostname#` or `hostname>`.
43
+ - This model was developed and tested against software version 1.16.0.
@@ -0,0 +1,75 @@
1
+ # Fortinet models
2
+ There are two models for Fortinet devices:
3
+ - fortigate: for the FortiGate firewalls
4
+ - fortios: for VM-Based appliances (FortiManager, FortiADC, FortiAnalyzer...)
5
+
6
+ # Notes for both models
7
+ ## Configuration changes / hiding passwords
8
+ Fortigate and Fortios re-encrypt their passwords every time the configuration is shown.
9
+ This results in a lot of apparent configuration changes on every pull.
10
+
11
+ To avoid this, you have two options:
12
+ - remove secrets
13
+ - save significant changes only
14
+
15
+ ### Remove secrets
16
+ If you don't want to have a new version every time the configuration is
17
+ downloaded, you can hide all secrets. Beware that you won't have a full backup, as all passwords will be replaced with <configuration removed>
18
+
19
+ ```yaml
20
+ models:
21
+ fortigate:
22
+ vars:
23
+ remove_secret: true
24
+ ```
25
+
26
+ ### Save significant changes only
27
+ You can [store the configuration only on significant changes](/docs/Configuration.md#store-configuration-only-on-significant-changes)
28
+ by setting the [variable](#options-credentials-vars-etc-precedence)
29
+ `output_store_mode` to `on_significant`. On FortiGate and FortiOS, this
30
+ prevents Oxidized from saving a configuration when there were only changes to
31
+ the encrypted passwords. Beware that you won't have the last backup if you only
32
+ changed a password.
33
+
34
+ ```yaml
35
+ vars:
36
+ output_store_mode: on_significant
37
+ ```
38
+
39
+ # Notes for the FortiGate model
40
+ ## Create user oxidized with ED25519 public key
41
+ You can use a user/password for retrieving the configuration or use a SSH public key:
42
+
43
+ ```text
44
+ config system admin
45
+ edit oxidized
46
+ set trusthost1 192.0.2.1 255.255.255.255
47
+ set accprofile "super_admin_readonly"
48
+ set ssh-public-key1 "ssh-ed25519 AAAAThisIsJustAnExampleKey_UseYourOxidizedPUBLICKEY oxidized@librenms"
49
+ end
50
+ ```
51
+
52
+ ## config vs. full config
53
+ On FortiGate, you can get a configuration without default values (`show`) or
54
+ including all default values (`show full-configuration`).
55
+
56
+ The full configuration can be long and may cause timeouts.
57
+ Starting with with oxidized 0.30.1, the default is to get the short configuration.
58
+
59
+ If you need the full configuration, you can activate it in oxidized config file:
60
+ ```yaml
61
+ models:
62
+ fortigate:
63
+ vars:
64
+ fullconfig: true
65
+ ```
66
+ ## Autoupdate
67
+ You can get the result of `diagnose autoupdate version` by setting the [variable](#options-credentials-vars-etc-precedence) `fortigate_autoupdate` to `true`:
68
+
69
+ ```yaml
70
+ vars:
71
+ fortigate_autoupdate: true
72
+ ```
73
+
74
+ Note that the variable `fortios_autoupdate` is deprecated and will be removed
75
+ in a future Version of Oxidized. Use `fortigate_autoupdate` instead.
@@ -0,0 +1,8 @@
1
+ # Grandstream HT8xx
2
+
3
+ You need to have enabled access to device by SSH.
4
+ Connection using user/password for retrieve the configuration containing XML file with all params stored in device memory.
5
+
6
+ Tested on hardware: v1 and software version: 1.0.61.2.
7
+
8
+ Back to [Model-Notes](README.md)
@@ -0,0 +1,59 @@
1
+ ### Ivanti Connect Secure (ICS)
2
+
3
+ #### Overview
4
+
5
+ This model provides support for Ivanti Connect Secure (ICS) appliances using REST API ([official documentation](https://help.ivanti.com/ps/help/en_US/ICS/22.x/22.7R2/22.xICSAG.pdf)).
6
+ ICS stores its configuration as a binary ZIP archive (with `system.cfg` and `user.cfg` files) which is retrieved using the `/api/v1/system/binary-configuration` endpoint.
7
+
8
+ The model performs an initial authentication against `/api/v1/realm_auth` using Basic Auth (`username`/`password`) and retrieves a temporary `api_key`.
9
+ This key is then used for all further API requests during the Oxidized collection cycle.
10
+
11
+ The model is designed to work with standard ICS deployments without requiring command-line access to the device.
12
+
13
+ #### How Configuration Is Retrieved
14
+
15
+ 1. Oxidized authenticates using:
16
+
17
+ ```bash
18
+ POST /api/v1/realm_auth
19
+ ```
20
+
21
+ with:
22
+ - Basic Auth: `username` + `password`
23
+ - JSON body `{"realm": "<realm>"}`
24
+
25
+
26
+ 2. ICS returns a temporary:
27
+
28
+ ```json
29
+ { "api_key": "<token>" }
30
+ ```
31
+
32
+
33
+ 3. The configuration is fetched from:
34
+
35
+ ```bash
36
+ GET /api/v1/system/binary-configuration
37
+ ```
38
+
39
+ with:
40
+ - `api_key` as `username`
41
+ - `''` as `password`
42
+
43
+ ICS responds with a BASE64-encoded ZIP archive containing the device configuration.
44
+ The model stores this BASE64 value as a single uninterrupted line.
45
+
46
+
47
+ #### Required Node Configuration
48
+
49
+ In source (CSV, HTTP, SQL, etc.), simply define:
50
+
51
+ ```yaml
52
+ model: ivanti
53
+ username: <your username>
54
+ password: <your password>
55
+ vars:
56
+ realm: <your realm> # Optional, default = "Users"
57
+ ```
58
+
59
+ The model will automatically handle authentication and obtain the API key as stated above.
@@ -12,4 +12,17 @@ and attach the public key.
12
12
 
13
13
  Oxidized can now retrieve your configuration!
14
14
 
15
+ ## Save significant changes only
16
+
17
+ You can [store the configuration only on significant changes](/docs/Configuration.md#store-configuration-only-on-significant-changes)
18
+ by setting the [variable](/docs/Configuration.md#options-credentials-vars-etc-precedence)
19
+ `output_store_mode` to `on_significant`. On RouterOS, this prevents Oxidized from saving a
20
+ new configuration version when only the system history has changed without any actual
21
+ configuration change.
22
+
23
+ ```yaml
24
+ vars:
25
+ output_store_mode: on_significant
26
+ ```
27
+
15
28
  Back to [Model-Notes](README.md)
@@ -0,0 +1,23 @@
1
+ # TrueNAS
2
+
3
+ This should support both older TrueNAS CORE (FreeBSD-based) and newer
4
+ TrueNAS SCALE (Linux-based) devices.
5
+
6
+ ## Authentication
7
+
8
+ Ensure that the user configured for oxidized to login to your device has the
9
+ permissions to read the configuration database. On older CORE instances, this
10
+ would just work without sudo. On newer devices, the `/data/freenas-v1.db` file
11
+ can only be read by the root user.
12
+
13
+ On SCALE devices with Apps support, it's also necessary to add some privileges
14
+ to read the container configurations for any apps you have installed, which can
15
+ be found under `/mnt/.ix-apps`.
16
+
17
+ You can make sure that the user that oxidized uses to login (`oxidized` in this
18
+ example) can dump the configuration using `sudo` by adding something like this
19
+ to your `/etc/sudoers` file:
20
+
21
+ ```
22
+ oxidized ALL=(ALL) NOPASSWD: /usr/bin/find /mnt/.ix-apps/app_configs *, /usr/bin/sqlite3 -readonly file\:/data/freenas-v1.db *
23
+ ```
@@ -4,6 +4,7 @@ effort to use. There are three different default unit tests for models:
4
4
  - [Device Simulation](ModelUnitTests.md#device-simulation)
5
5
  - [Device Prompt](ModelUnitTests.md#device-prompt)
6
6
  - [Secrets](ModelUnitTests.md#secrets)
7
+ - [Significant Changes](ModelUnitTests.md#significant-changes)
7
8
 
8
9
  You only need to provide test files under [/spec/model/data](/spec/model/data),
9
10
  and the tests will be run automatically with `rake test`. See
@@ -187,6 +188,28 @@ pass:
187
188
  - 'hash-mgmt-user rocks password hash <secret removed> usertype read-only'
188
189
  ```
189
190
 
191
+ ## Significant Changes
192
+ You can test if the model correctly detects significant changes from a YAML
193
+ simulation file (`#simulation.yaml`) when run with variable
194
+ `output_store_mode` set to `on_significant`.
195
+
196
+ The output is checked against a file with the same
197
+ prefix as the yaml simulation file, but with the suffix
198
+ `#significant_changes.yaml`.
199
+
200
+ The `#significant_changes.yaml` file contains two sections with a list of
201
+ strings or regular expressions to test:
202
+ - pass: the test passes only if the output contains these strings (significant changes).
203
+ - fail: the test fails if the output contain these strings (non-significant changes).
204
+
205
+ ```yaml
206
+ pass:
207
+ - "! Processor ID: FCL2XXXXXXX"
208
+ fail:
209
+ - "! Last configuration change at 13:57:08 CET Wed Mar 13 2024"
210
+ - "! NVRAM config last updated at 15:26:39 CET Wed Mar 13 2024 by oxidized"
211
+ ```
212
+
190
213
  ## Custom tests
191
214
  When you write custom tests for your models, please do not use the filenames
192
215
  mentioned above, as it will interfere with the standard tests. If you need to
data/docs/Outputs.md CHANGED
@@ -211,9 +211,9 @@ output:
211
211
 
212
212
  Please note that user list is only updated once at creation.
213
213
 
214
- ## Output: Http
214
+ ## Output: HTTP
215
215
 
216
- The HTTP output will POST a config to the specified HTTP URL. Basic username/password authentication is supported.
216
+ The HTTP output will POST a config as JSON to the specified HTTP URL. It supports HTTP Basic Authentication, custom headers, and SSL/TLS verification control.
217
217
 
218
218
  Example HTTP output configuration:
219
219
 
@@ -221,11 +221,25 @@ Example HTTP output configuration:
221
221
  output:
222
222
  default: http
223
223
  http:
224
- user: admin
225
- password: changeit
226
224
  url: "http://192.168.162.50:8080/db/coll"
225
+ user: admin # Optional - for HTTP basic auth
226
+ password: changeit # Optional - for HTTP basic auth
227
+ ssl_verify: false # Optional - verify SSL certs (default: false)
228
+ headers: # Optional - custom HTTP headers
229
+ X-Custom-Header: "value"
230
+ X-API-Key: "secret"
227
231
  ```
228
232
 
233
+ ### Configuration Options
234
+
235
+ | Option | Required | Description |
236
+ |--------------|----------|---------------------------------------------------------|
237
+ | `url` | Yes | Full HTTP/HTTPS URL to POST the config to |
238
+ | `user` | No | Username for HTTP Basic Authentication |
239
+ | `password` | No | Password for HTTP Basic Authentication |
240
+ | `ssl_verify` | No | When `true`, verify SSL certificates (default: `false`) |
241
+ | `headers` | No | Hash of custom HTTP headers to include in the request |
242
+
229
243
  ## Output types
230
244
 
231
245
  If you prefer to have different outputs in different files and/or directories, you can easily do this by modifying the corresponding model. To change the behaviour for IOS, you would edit `lib/oxidized/model/ios.rb` (run `gem contents oxidized` to find out the full file path).