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.
- checksums.yaml +4 -4
- data/.coderabbit.yaml +21 -0
- data/.github/workflows/publishdocker.yml +11 -9
- data/.github/workflows/ruby.yml +1 -3
- data/.rubocop.yml +16 -2
- data/.rubocop_todo.yml +21 -2
- data/CHANGELOG.md +76 -3
- data/README.md +2 -3
- data/Rakefile +1 -1
- data/docs/Configuration.md +40 -2
- data/docs/Creating-Models.md +129 -14
- data/docs/Docker.md +2 -1
- data/docs/Hooks.md +92 -67
- data/docs/Inputs.md +44 -12
- data/docs/Model-Notes/APC.md +72 -0
- data/docs/Model-Notes/ExaLink.md +43 -0
- data/docs/Model-Notes/Fortinet.md +75 -0
- data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
- data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
- data/docs/Model-Notes/RouterOS.md +13 -0
- data/docs/Model-Notes/TrueNAS.md +23 -0
- data/docs/ModelUnitTests.md +23 -0
- data/docs/Outputs.md +18 -4
- data/docs/Release.md +7 -2
- data/docs/Ruby-API.md +86 -5
- data/docs/Supported-OS-Types.md +21 -9
- data/docs/Troubleshooting.md +1 -1
- data/extra/device2yaml.rb +2 -3
- data/extra/hooks/modelrules.rb +55 -0
- data/extra/hooks/modelrulesadvanced.rb +167 -0
- data/extra/hooks/srcipmap.rb +54 -0
- data/lib/oxidized/cli/support.rb +152 -0
- data/lib/oxidized/cli.rb +9 -0
- data/lib/oxidized/hook/githubrepo.rb +2 -1
- data/lib/oxidized/hook.rb +58 -8
- data/lib/oxidized/input/debugtext.rb +40 -0
- data/lib/oxidized/input/debugyaml.rb +82 -0
- data/lib/oxidized/input/exec.rb +1 -10
- data/lib/oxidized/input/ftp.rb +0 -17
- data/lib/oxidized/input/http.rb +39 -21
- data/lib/oxidized/input/input.rb +33 -13
- data/lib/oxidized/input/scp.rb +10 -64
- data/lib/oxidized/input/ssh.rb +36 -79
- data/lib/oxidized/input/sshbase.rb +102 -0
- data/lib/oxidized/input/telnet.rb +12 -13
- data/lib/oxidized/input/tftp.rb +7 -7
- data/lib/oxidized/model/aoscx.rb +18 -12
- data/lib/oxidized/model/aosw.rb +10 -11
- data/lib/oxidized/model/apc_aos.rb +4 -0
- data/lib/oxidized/model/apcaos.rb +39 -0
- data/lib/oxidized/model/arubainstant.rb +11 -20
- data/lib/oxidized/model/asa.rb +7 -7
- data/lib/oxidized/model/comware.rb +3 -1
- data/lib/oxidized/model/cumulus.rb +3 -3
- data/lib/oxidized/model/defacto.rb +26 -0
- data/lib/oxidized/model/dlinknextgen.rb +1 -0
- data/lib/oxidized/model/dslcommands.rb +93 -0
- data/lib/oxidized/model/dslsetup.rb +102 -0
- data/lib/oxidized/model/efos.rb +5 -5
- data/lib/oxidized/model/exalink.rb +36 -0
- data/lib/oxidized/model/fastiron.rb +2 -2
- data/lib/oxidized/model/firelinuxos.rb +1 -3
- data/lib/oxidized/model/fortigate.rb +160 -0
- data/lib/oxidized/model/fortios.rb +28 -69
- data/lib/oxidized/model/fsos.rb +1 -3
- data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ios.rb +23 -15
- data/lib/oxidized/model/ironware.rb +5 -3
- data/lib/oxidized/model/ivanti.rb +54 -0
- data/lib/oxidized/model/junos.rb +2 -2
- data/lib/oxidized/model/linuxgeneric.rb +4 -2
- data/lib/oxidized/model/macros.rb +60 -0
- data/lib/oxidized/model/mlnxos.rb +11 -7
- data/lib/oxidized/model/model.rb +28 -126
- data/lib/oxidized/model/ndms.rb +6 -0
- data/lib/oxidized/model/netgear.rb +5 -3
- data/lib/oxidized/model/nxos.rb +6 -3
- data/lib/oxidized/model/outputs.rb +5 -0
- data/lib/oxidized/model/perle.rb +14 -8
- data/lib/oxidized/model/routeros.rb +4 -0
- data/lib/oxidized/model/smartbyte.rb +48 -0
- data/lib/oxidized/model/tplink.rb +4 -6
- data/lib/oxidized/model/truenas.rb +63 -3
- data/lib/oxidized/model/voss.rb +3 -0
- data/lib/oxidized/model/vyos.rb +4 -1
- data/lib/oxidized/node.rb +25 -23
- data/lib/oxidized/nodes.rb +2 -0
- data/lib/oxidized/output/file.rb +7 -1
- data/lib/oxidized/output/git.rb +11 -1
- data/lib/oxidized/output/gitcrypt.rb +1 -1
- data/lib/oxidized/output/http.rb +12 -3
- data/lib/oxidized/source/csv.rb +5 -0
- data/lib/oxidized/source/jsonfile.rb +5 -0
- data/lib/oxidized/source/sql.rb +5 -0
- data/lib/oxidized/version.rb +2 -2
- data/lib/oxidized/worker.rb +36 -15
- data/lib/refinements.rb +18 -0
- data/oxidized.gemspec +28 -24
- metadata +103 -55
- data/docs/Model-Notes/APC_AOS.md +0 -65
- data/docs/Model-Notes/FortiOS.md +0 -44
data/docs/Release.md
CHANGED
|
@@ -61,7 +61,7 @@ They test different ruby versions an run security checks on the code (codeql).
|
|
|
61
61
|
6. Install an test the gem locally
|
|
62
62
|
```shell
|
|
63
63
|
gem install --user-install pkg/oxidized-0.xx.yy.gem
|
|
64
|
-
~/.local/share/gem/ruby/3.
|
|
64
|
+
~/.local/share/gem/ruby/3.3.0/bin/oxidized
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
## Release in github
|
|
@@ -71,9 +71,14 @@ git push origin 0.xx.yy
|
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Make a release from the tag in github.
|
|
74
|
-
-
|
|
74
|
+
- Name the release `0.xx.yy`
|
|
75
|
+
- Generate release notes
|
|
76
|
+
- Remove `## What's changed`
|
|
77
|
+
- Take the release notes from CHANGELOG.md
|
|
75
78
|
- List new contributors (generated automatically)
|
|
76
79
|
- Keep the Full Changelog (generated automatically)
|
|
80
|
+
- Preview
|
|
81
|
+
- Publish
|
|
77
82
|
|
|
78
83
|
Close the corresponding milestone in github.
|
|
79
84
|
|
data/docs/Ruby-API.md
CHANGED
|
@@ -10,11 +10,15 @@ The following objects exist in Oxidized.
|
|
|
10
10
|
- [Model](#model)
|
|
11
11
|
- [At the top level](#at-the-top-level)
|
|
12
12
|
- [cfg](#cfg)
|
|
13
|
+
- [inputs](#inputs)
|
|
13
14
|
- [cmd](#cmd)
|
|
14
15
|
- [comment](#comment)
|
|
15
16
|
- [prompt](#prompt)
|
|
16
17
|
- [expect](#expect)
|
|
17
18
|
- [pre / post](#pre--post)
|
|
19
|
+
- [macro :enable](#macro-enable)
|
|
20
|
+
- [clean :escape_codes](#clean-escape_codes)
|
|
21
|
+
- [clean :cut](#clean-cut)
|
|
18
22
|
- [At the second level](#at-the-second-level)
|
|
19
23
|
- [comment](#comment-1)
|
|
20
24
|
- [password](#password)
|
|
@@ -26,9 +30,11 @@ The following objects exist in Oxidized.
|
|
|
26
30
|
- [clear: true](#clear-true)
|
|
27
31
|
- [prepend: true](#prepend-true)
|
|
28
32
|
- [Refinements - String Convenience Methods](#refinements)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
- [cut_tail](#cut_tail)
|
|
34
|
+
- [cut_head](#cut_head)
|
|
35
|
+
- [cut_both](#cut_both)
|
|
36
|
+
- [keep_lines](#keep_lines)
|
|
37
|
+
- [reject_lines](#reject_lines)
|
|
32
38
|
|
|
33
39
|
## Input
|
|
34
40
|
|
|
@@ -87,6 +93,40 @@ The block may contain commands to change some behaviour for the given methods
|
|
|
87
93
|
|
|
88
94
|
Supports [monkey patching](#monkey-patching).
|
|
89
95
|
|
|
96
|
+
#### 'inputs'
|
|
97
|
+
`inputs` can be used to specify multiple inputs to be run on the model. It
|
|
98
|
+
takes a list of either input symbols or lists of input symbols:
|
|
99
|
+
```ruby
|
|
100
|
+
inputs [:ssh, %i[scp ftp]]
|
|
101
|
+
inputs [:ssh, :scp]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Oxidized will run the model against each item of `inputs`. If an item is a
|
|
105
|
+
list of symbols (`%i[scp ftp]`), it will try each input in the order
|
|
106
|
+
configured in the `input/default` section of the oxidized configuration file.
|
|
107
|
+
|
|
108
|
+
If `inputs` is not specified, Oxidized will try each input that has a `cfg`
|
|
109
|
+
section in the model, in the order configured in the `input/default` section
|
|
110
|
+
of the oxidized configuration file.
|
|
111
|
+
|
|
112
|
+
To specify which command is to run against which input, use the `input`
|
|
113
|
+
parameter of the `cmd` configuration:
|
|
114
|
+
```ruby
|
|
115
|
+
cmd 'upsabout', input: :ssh do |cfg|
|
|
116
|
+
comment cfg
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
cmd 'config.ini', input: %i[scp ftp] do |cfg|
|
|
120
|
+
"; ========== config.ini ==========\n" + cfg
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`cmd` without `input` parameter will run against every input.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
See the [ApcAos model](/lib/oxidized/model/apcaos.rb) for a full example.
|
|
128
|
+
|
|
129
|
+
|
|
90
130
|
#### `cmd`
|
|
91
131
|
|
|
92
132
|
Is used to specify commands that should be executed on a model in order to
|
|
@@ -96,6 +136,7 @@ gather its configuration. It can be called with:
|
|
|
96
136
|
* A string and a block
|
|
97
137
|
* `:all` and a block
|
|
98
138
|
* `:secret` and a block
|
|
139
|
+
* `:significant_changes` and a block
|
|
99
140
|
|
|
100
141
|
The block takes a single parameter `cfg` containing the output of the command
|
|
101
142
|
being processed.
|
|
@@ -116,14 +157,27 @@ given block before emitting it to hide secrets if secret hiding is enabled. The
|
|
|
116
157
|
block should replace any secrets with `'<hidden>'` and return the resulting
|
|
117
158
|
string.
|
|
118
159
|
|
|
160
|
+
Calling `cmd` with `:significant_changes` and a block will pass the final
|
|
161
|
+
configuration to the given block. The resulting string should contain
|
|
162
|
+
significant changes only and will be used to
|
|
163
|
+
[decide if the configuration should be stored](Configuration.md#store-configuration-only-on-significant-changes).
|
|
164
|
+
|
|
119
165
|
Execution order is `:all`, `:secret`, and lastly the command specific block, if
|
|
120
166
|
given.
|
|
121
167
|
|
|
122
|
-
The `cmd "string"` method
|
|
168
|
+
The `cmd "string"` method accepts a lambda function via the `:if` argument
|
|
123
169
|
to execute the command only when the lambda evaluates to true.
|
|
124
170
|
The lambda function is evaluated at runtime in the instance context.
|
|
125
171
|
See [Conditional `cmd`](Creating-Models.md#conditional-cmd) for details.
|
|
126
172
|
|
|
173
|
+
The `cmd "string"` method accepts a list of supported inputs via the `:input`
|
|
174
|
+
argument to limit this command to specific inputs.
|
|
175
|
+
```ruby
|
|
176
|
+
cmd 'config.ini', input: %i[scp ftp] do |cfg|
|
|
177
|
+
"; ========== config.ini ==========\n" + cfg
|
|
178
|
+
end
|
|
179
|
+
```
|
|
180
|
+
|
|
127
181
|
Supports [monkey patching](#monkey-patching).
|
|
128
182
|
|
|
129
183
|
#### pre / post
|
|
@@ -167,6 +221,28 @@ it's further processed.
|
|
|
167
221
|
|
|
168
222
|
Supports [monkey patching](#monkey-patching).
|
|
169
223
|
|
|
224
|
+
#### `macro :enable`
|
|
225
|
+
Implements an [handling of enable](Creating-Models.md#handling-enable-mode) for the model.
|
|
226
|
+
|
|
227
|
+
#### `clean :escape_codes`
|
|
228
|
+
[Remove ANSI escape codes](Creating-Models.md#remove-ansi-escape-codes) from the output.
|
|
229
|
+
|
|
230
|
+
#### `clean :cut`
|
|
231
|
+
Removes (default) the first and last line of the outputs (most of the time
|
|
232
|
+
command echo and prompt).
|
|
233
|
+
Arguments: head (default: 1), tail (default: 1)
|
|
234
|
+
```ruby
|
|
235
|
+
clean :cut, head: 2, tail: 0
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Equivalent to:
|
|
239
|
+
```ruby
|
|
240
|
+
cmd :all do |cfg|
|
|
241
|
+
cfg.cut_both(2, 0)
|
|
242
|
+
end
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
|
|
170
246
|
### At the second level
|
|
171
247
|
|
|
172
248
|
The following methods are available:
|
|
@@ -223,7 +299,6 @@ This functionality is supported by `cfg`, `cmd`, `pre_*`, `post_*`, and `expect`
|
|
|
223
299
|
blocks.
|
|
224
300
|
|
|
225
301
|
#### `clear: true`
|
|
226
|
-
|
|
227
302
|
Resets the existing block, allowing the user to completely override its contents.
|
|
228
303
|
|
|
229
304
|
#### `prepend: true`
|
|
@@ -253,3 +328,9 @@ single line was present.
|
|
|
253
328
|
|
|
254
329
|
Returns a multi-line string without the first and last lines, or an empty string
|
|
255
330
|
if fewer than three lines were present.
|
|
331
|
+
|
|
332
|
+
#### `keep_lines`
|
|
333
|
+
Returns a multi-line string with only the lines matching any pattern (String or Regexp) given in an array.
|
|
334
|
+
|
|
335
|
+
#### `reject_lines`
|
|
336
|
+
Returns a multi-line string without the lines matching any pattern (String or Regexp) given in an array.
|
data/docs/Supported-OS-Types.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|Vendor |OS model |oxidized model |model maintainers|comment / model notes|
|
|
4
4
|
|--------------------|------------------------------|-------------------------------------------------|-----------------|---------------------|
|
|
5
|
+
|-generic- |Cisco-like |[defacto](/lib/oxidized/model/defacto.rb) |@ytti, @robertcheramy|[The defacto model may work on cisco like CLIs](/docs/Creating-Models.md#use-the-defacto-model)|
|
|
5
6
|
|6WIND |VSR |[sixwind](/lib/oxidized/model/sixwind.rb) |@hcaldicott |
|
|
6
7
|
|A10 Networks |ACOS |[acos](/lib/oxidized/model/acos.rb) | |
|
|
7
8
|
|Accedian Performance Elements (NIDs)|AEN |[aen](/lib/oxidized/model/aen.rb)
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
|Allied Telesis |Alliedware Plus |[awplus](/lib/oxidized/model/awplus.rb)
|
|
18
19
|
| |AT-8000S, AT-8000GS series |[powerconnect](/lib/oxidized/model/powerconnect.rb)
|
|
19
20
|
|Alvarion |BreezeACCESS |[alvarion](/lib/oxidized/model/alvarion.rb)
|
|
20
|
-
|APC |AOS |[
|
|
21
|
+
|APC |AOS |[apcaos](/lib/oxidized/model/apcaos.rb) |@robertcheramy |[APC](Model-Notes/APC.md)
|
|
21
22
|
|Arbor Networks |ArbOS |[arbos](/lib/oxidized/model/arbos.rb) | |[ArbOS](Model-Notes/ArbOS.md)
|
|
22
23
|
|Arista |EOS |[eos](/lib/oxidized/model/eos.rb) | |[EOS](Model-Notes/EOS.md)
|
|
23
24
|
|Arris |C4CMTS |[c4cmts](/lib/oxidized/model/c4cmts.rb)
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
| |AsyncOS |[asyncos](/lib/oxidized/model/asyncos.rb)
|
|
53
54
|
| |CatOS |[catos](/lib/oxidized/model/catos.rb)
|
|
54
55
|
| |Cisco Catalyst Express |[ciscoce](/lib/oxidized/model/ciscoce.rb)
|
|
56
|
+
| |ExaLink Fusion (Nexus 3550-F) |[exalink](/lib/oxidized/model/exalink.rb) |@obol89 |[ExaLink](Model-Notes/ExaLink.md)
|
|
55
57
|
| |FireLinuxOS |[firelinuxos](/lib/oxidized/model/firelinuxos.rb)
|
|
56
58
|
| |IOS |[ios](/lib/oxidized/model/ios.rb) |@robertcheramy |[IOS](Model-Notes/IOS.md)
|
|
57
59
|
| |IOSXR |[iosxr](/lib/oxidized/model/iosxr.rb)
|
|
@@ -74,7 +76,7 @@
|
|
|
74
76
|
|DELL |PowerConnect |[powerconnect](/lib/oxidized/model/powerconnect.rb)
|
|
75
77
|
| |AOSW |[aosw](/lib/oxidized/model/aosw.rb) | |Same model as Aruba Wireless
|
|
76
78
|
| |DellX |[dellx](/lib/oxidized/model/dellx.rb)
|
|
77
|
-
| |Dell EMC Networking OS6 |[os6](/lib/oxidized/model/os6.rb)
|
|
79
|
+
| |Dell EMC Networking OS6 |[os6](/lib/oxidized/model/os6.rb) | |[Dell EMC Networking OS6](Model-Notes/OS6.md)
|
|
78
80
|
| |Dell EMC Networking OS10 |[os10](/lib/oxidized/model/os10.rb) | |[Dell EMC Networking OS10](Model-Notes/OS10.md)
|
|
79
81
|
|D-Link |D-Link |[dlink](/lib/oxidized/model/dlink.rb)
|
|
80
82
|
| |D-Link cisco like CLI |[dlinknextgen](/lib/oxidized/model/dlinknextgen.rb)
|
|
@@ -98,12 +100,15 @@
|
|
|
98
100
|
|Firebrick |FBxxxx |[firebrick](/lib/oxidized/model/firebrick.rb)
|
|
99
101
|
|Force10 |DNOS |[dnos](/lib/oxidized/model/dnos.rb)
|
|
100
102
|
| |FTOS |[ftos](/lib/oxidized/model/ftos.rb)
|
|
101
|
-
|FortiGate
|
|
102
|
-
|
|
|
103
|
+
|Fortinet |FortiGate |[fortigate](/lib/oxidized/model/fortigate.rb) |@robertcheramy |[Fortinet](Model-Notes/Fortinet.md)
|
|
104
|
+
| |FortiOS |[fortios](/lib/oxidized/model/fortios.rb) |@robertcheramy |[Fortinet](Model-Notes/Fortinet.md)
|
|
105
|
+
| |FortiWLC |[fortiwlc](/lib/oxidized/model/fortiwlc.rb)
|
|
103
106
|
|Fujitsu |PRIMERGY Blade switch 1/10Gbe |[fujitsupy](/lib/oxidized/model/fujitsupy.rb)
|
|
104
107
|
| |1FINITY Switches |[onefinity](/lib/oxidized/model/onefinity.rb)
|
|
108
|
+
|[Garderos](https://garderos.com/) |GRS (Garderos Router Software) |[garderos](/lib/oxidized/model/garderos.rb) | @robertcheramy |Routers for harsh environments
|
|
105
109
|
|GCOM Technologies |Broadband Network Platform Software|[gcombnps](/lib/oxidized/model/gcombnps.rb)
|
|
106
110
|
|Grandstream Networks|GSX |[grandstream](/lib/oxidized/model/grandstream.rb)
|
|
111
|
+
| |HT8xx |[grandstream](/lib/oxidized/model/grandstreamht8xx.rb) | @mklopocki | [Grandstream](Model-Notes/GrandstreamHT8xx.md)
|
|
107
112
|
|Hatteras |Hatteras |[hatteras](/lib/oxidized/model/hatteras.rb)
|
|
108
113
|
|Hillstone Networks |StoneOS |[stoneos](/lib/oxidized/model/stoneos.rb)
|
|
109
114
|
|Hirschmann |Classic |[hirschmann](/lib/oxidized/model/hirschmann.rb)
|
|
@@ -119,6 +124,7 @@
|
|
|
119
124
|
|Icotera |6400 series |[icotera](/lib/oxidized/model/icotera.rb)
|
|
120
125
|
|Ingate |SIParator/Firewalls |[ingate](/lib/oxidized/model/ingate.rb) |@thanegill
|
|
121
126
|
|IP Infusion |OcNOS |[ocnos](/lib/oxidized/model/ocnos.rb)
|
|
127
|
+
|Ivanti |Ivanti Connect Secure (ICS) |[ivanti](/lib/oxidized/model/ivanti.rb) |@candleflip |[ICS](Model-Notes/IvantiConnectSecure.md)
|
|
122
128
|
|Juniper |JunOS |[junos](/lib/oxidized/model/junos.rb) | |[MX/QFX/EX/SRX/J Series](Model-Notes/JunOS.md)
|
|
123
129
|
| |ScreenOS (Netscreen) |[screenos](/lib/oxidized/model/screenos.rb)
|
|
124
130
|
|LANCOM Systems GmbH |LCOS |[lancom](/lib/oxidized/model/lancom.rb)
|
|
@@ -127,7 +133,7 @@
|
|
|
127
133
|
|Linuxgeneric |CentOS |[linuxgeneric](/lib/oxidized/model/linuxgeneric.rb)| |[LinuxGeneric](Model-Notes/LinuxGeneric.md)
|
|
128
134
|
|Mellanox |MLNX-OS |[mlnxos](/lib/oxidized/model/mlnxos.rb)
|
|
129
135
|
| |Voltaire |[voltaire](/lib/oxidized/model/voltaire.rb)
|
|
130
|
-
|Mikrotik |RouterOS |[routeros](/lib/oxidized/model/routeros.rb) |
|
|
136
|
+
|Mikrotik |RouterOS |[routeros](/lib/oxidized/model/routeros.rb) | |[RouterOS](Model-Notes/RouterOS.md)
|
|
131
137
|
| |SwOS and SwOS Lite |[swos](/lib/oxidized/model/swos.rb)
|
|
132
138
|
|Mimosa |Mimosa (B11) |[mimosab11](/lib/oxidized/model/mimosab11.rb)
|
|
133
139
|
|Motorola |RFS |[mtrlrfs](/lib/oxidized/model/mtrlrfs.rb)
|
|
@@ -138,6 +144,7 @@
|
|
|
138
144
|
|Netgear |Netgear switches |[netgear](/lib/oxidized/model/netgear.rb) | |[Netgear](Model-Notes/Netgear.md)
|
|
139
145
|
|Netonix |WISP Switch (As Netonix) |[netonix](/lib/oxidized/model/netonix.rb)
|
|
140
146
|
|Nokia (formerly TiMetra, Alcatel, Alcatel-Lucent)|SR OS (TiMOS)|[sros](/lib/oxidized/model/sros.rb) | |[Nokia ISAM](Model-Notes/Nokia.md)
|
|
147
|
+
| |SR OS Model-Driven CLI (7705 SAR, 7210 SAS, 7450 ESS, 7750 SR, 7950 XRS, NSP) |[srosmd](/lib/oxidized/model/srosmd.rb) | |
|
|
141
148
|
|OneAccess |OneOS |[oneos](/lib/oxidized/model/oneos.rb)
|
|
142
149
|
| |TDRE |[tdre](/lib/oxidized/model/tdre.rb)
|
|
143
150
|
|OpenBSD | |[openbsd](/lib/oxidized/model/openbsd.rb)
|
|
@@ -152,13 +159,16 @@
|
|
|
152
159
|
|Pure Storage |PurityOS |[purityos](/lib/oxidized/model/purityos.rb)
|
|
153
160
|
|Radware |AlteonOS |[alteonos](/lib/oxidized/model/alteonos.rb)
|
|
154
161
|
|Raisecom |Raisecom |[raisecom](/lib/oxidized/model/raisecom.rb)
|
|
162
|
+
|Riverbed |SteelHead |[riverbed](/lib/oxidized/model/riverbed.rb)
|
|
155
163
|
|Ruijie Networks |RGOS |[rgos](/lib/oxidized/model/rgos.rb)
|
|
156
164
|
|QTECH |QSW-2800, QSW-3400, QSW-3450, QSW-3500|[qtech](/lib/oxidized/model/qtech.rb)
|
|
157
165
|
|Quanta |Quanta / VxWorks 6.6 (1.1.0.8)|[quantaos](/lib/oxidized/model/quantaos.rb)
|
|
158
166
|
|Siklu |EtherHaul |[siklu](/lib/oxidized/model/siklu.rb) |@bdg-robert
|
|
159
167
|
| |Multihaul TG |[siklumhtg](/lib/oxidized/model/siklumhtg.rb) |@bdg-robert |[Siklu Multihaul TG](Model-Notes/SikluMHTG.md)
|
|
160
168
|
|Seiko Solutions |SmartCS, SmartCS mini |[smartcs](/lib/oxidized/model/smartcs.rb)
|
|
169
|
+
|SmartByte |LT-S8228G series |[smartbyte](/lib/oxidized/model/smartbyte.rb) |@freddy36
|
|
161
170
|
|SonicWALL |SonicOS |[sonicos](/lib/oxidized/model/sonicos.rb)
|
|
171
|
+
|[SONiC](https://sonicfoundation.dev/) |Enterprise SONiC |[enterprise_sonic](/lib/oxidized/model/enterprise_sonic.rb) | |
|
|
162
172
|
|SNR |SNR-S300G, S2xxx, S3xxx, S4xxx|[dcnos](/lib/oxidized/model/dcnos.rb)
|
|
163
173
|
|Speedtouch |Thomson Speedtouch |[speedtouch](/lib/oxidized/model/speedtouch.rb)
|
|
164
174
|
|Supermicro |SSE-G2252, G2252P |[edgecos](/lib/oxidized/model/edgecos.rb)
|
|
@@ -176,14 +186,14 @@
|
|
|
176
186
|
| |Edgeos |[edgeos](/lib/oxidized/model/edgeos.rb)
|
|
177
187
|
| |EdgeSwitch |[edgeswitch](/lib/oxidized/model/edgeswitch.rb)
|
|
178
188
|
| |AirFiber |[airfiber](/lib/oxidized/model/airfiber.rb)
|
|
179
|
-
| |UnifiAP |[unifiap](/lib/oxidized/model/unifiap.rb)
|
|
180
|
-
|Uplink |EP4440-DP |[EP4440](/lib/oxidized/model/uplinkolt.rb)
|
|
189
|
+
| |UnifiAP |[unifiap](/lib/oxidized/model/unifiap.rb) |@clifcox |Also suports AirOS, and some Unifi switches
|
|
190
|
+
|Uplink |EP4440-DP |[EP4440](/lib/oxidized/model/uplinkolt.rb) | |Might support all EP4440 series
|
|
181
191
|
|VMWare |NSX Edge (configuration) |[nsxconfig](/lib/oxidized/model/nsxconfig.rb)
|
|
182
192
|
| |NSX Edge (firewall rules) |[nsxfirewall](/lib/oxidized/model/nsxfirewall.rb)
|
|
183
193
|
| |NSX Distributed Firewall |[nsxdfw](/lib/oxidized/model/nsxdfw.rb)
|
|
184
|
-
|VYOS Networks |VYOS |[vyos](/lib/oxidized/model/vyos.rb)
|
|
185
|
-
| |Fork of Vyatta, tracking the supported versions (>= 1.4.x)
|
|
194
|
+
|VYOS Networks |VYOS |[vyos](/lib/oxidized/model/vyos.rb) | |Fork of Vyatta, tracking the supported versions (>= 1.4.x)
|
|
186
195
|
|Watchguard |Fireware OS |[firewareos](/lib/oxidized/model/firewareos.rb)
|
|
196
|
+
|Waystream (PacketFront)|iBOS (Intelligent Broadband OS)|[ibos](/lib/oxidized/model/ibos.rb)
|
|
187
197
|
|Westell |Westell 8178G, Westell 8266G |[weos](/lib/oxidized/model/weos.rb)
|
|
188
198
|
|Yadro |KornfeldOS |[kornfeldos](/lib/oxidized/model/kornfeldos.rb)
|
|
189
199
|
|YAMAHA |YAMAHA NVR/RTX Series |[yamaha](/lib/oxidized/model/yamaha.rb)
|
|
@@ -193,5 +203,7 @@
|
|
|
193
203
|
|Zyxel |ZyNOS |[zynos](/lib/oxidized/model/zynos.rb) | |[XGS4600 Series](Model-Notes/XGS4600-Zyxel.md)
|
|
194
204
|
| |ZyNOS GS-series variant |[zynosgs](/lib/oxidized/model/zynosgs.rb)
|
|
195
205
|
| |ZyNOS ADSL |[zynosadsl](/lib/oxidized/model/zynosadsl.rb)
|
|
206
|
+
| |ZyNOS CLI (DSLAMs, e.g. SAM1316)|[zynoscli](/lib/oxidized/model/zynoscli.rb)
|
|
207
|
+
| |ZyNOS MGS series |[zynosmgs](/lib/oxidized/model/zynosmgs.rb)
|
|
196
208
|
| |NDMS |[ndms](/lib/oxidized/model/ndms.rb)
|
|
197
209
|
| |1308 |[zy1308](/lib/oxidized/model/zy1308.rb)
|
data/docs/Troubleshooting.md
CHANGED
|
@@ -86,7 +86,7 @@ ssh-keyscan gitserver.git.com >> ~/.ssh/known_hosts
|
|
|
86
86
|
|
|
87
87
|
If you are running oxidized in a container, you need to map /home/oxidized/.ssh in the
|
|
88
88
|
container to a local repository and save the known_hosts in the local repository. You can
|
|
89
|
-
find an example how to do this under [
|
|
89
|
+
find an example how to do this under [Docker.md](Docker.md#store-the-ssh-keys-a-remote-git-repository)
|
|
90
90
|
|
|
91
91
|
## Oxidized ignores the changes I made to its git repository
|
|
92
92
|
First of all: you shouldn't manipulate the git repository of oxidized. Don't
|
data/extra/device2yaml.rb
CHANGED
|
@@ -91,9 +91,8 @@ def yaml_output(prepend = '')
|
|
|
91
91
|
|
|
92
92
|
prepend = @sequence_prepend_output + prepend
|
|
93
93
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
@ssh_output.each_line(chomp: true) do |line|
|
|
94
|
+
# each_line(chomp: true) would remove \r\n, so we prefer split
|
|
95
|
+
@ssh_output.split("\n", -1).each do |line|
|
|
97
96
|
# encode line and remove the first and the trailing double quote
|
|
98
97
|
line = line.dump[1..-2]
|
|
99
98
|
if firstline
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
### script in ~/config/oxidized/hook/modelrules.rb ## or OXDIZED_HOME equivalent
|
|
2
|
+
###
|
|
3
|
+
### router.db:
|
|
4
|
+
### router1:1.1.1.1:routeros::mikrotik
|
|
5
|
+
### router2:2.2.2.2:ios:switch:cisco
|
|
6
|
+
### router3:3.3.3.3:routeros:switch:mikrotik
|
|
7
|
+
###
|
|
8
|
+
### config:
|
|
9
|
+
### source:
|
|
10
|
+
### default: csv
|
|
11
|
+
### csv:
|
|
12
|
+
### file: "/Users/ytti/.config/oxidized/router.db"
|
|
13
|
+
### delimiter: !ruby/regexp /:/
|
|
14
|
+
### map:
|
|
15
|
+
### name: 0
|
|
16
|
+
### ip: 1
|
|
17
|
+
### model: 2
|
|
18
|
+
### group: 3
|
|
19
|
+
### hooks:
|
|
20
|
+
### somename:
|
|
21
|
+
### type: modelrules
|
|
22
|
+
### events: ["source_node_transform"]
|
|
23
|
+
### rules:
|
|
24
|
+
### - vendor: mikrotik
|
|
25
|
+
### group: switch
|
|
26
|
+
### model: eltex
|
|
27
|
+
###
|
|
28
|
+
### Nodes BEFORE script:
|
|
29
|
+
### {name: "router1", ip: "1.1.1.1", model: "routeros", group: ""}
|
|
30
|
+
### {name: "router2", ip: "2.2.2.2", model: "ios", group: "switch"}
|
|
31
|
+
### {name: "router3", ip: "3.3.3.3", model: "routeros", group: "switch"}
|
|
32
|
+
###
|
|
33
|
+
### Nodes AFTER script:
|
|
34
|
+
### {name: "router1", ip: "1.1.1.1", model: "routeros", group: ""}
|
|
35
|
+
### {name: "router2", ip: "2.2.2.2", model: "ios", group: "switch"}
|
|
36
|
+
### {name: "router3", ip: "3.3.3.3", model: "eltex", group: "switch"}
|
|
37
|
+
class ModelRules < Oxidized::Hook
|
|
38
|
+
def validate_cfg!
|
|
39
|
+
raise KeyError, 'hook.rules is required' unless cfg.has_key?('rules')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def run_hook(ctx)
|
|
43
|
+
# node is the node[key] that we'd return without manipulation
|
|
44
|
+
node = ctx.node ## e.g. node[:ip], node[:model] - what ever config maps
|
|
45
|
+
|
|
46
|
+
## node_raw is source specific, in CSV it is just the field number, in HTTP it is JSON
|
|
47
|
+
vendor = ctx.node_raw[4]
|
|
48
|
+
|
|
49
|
+
cfg.rules.each do |rule|
|
|
50
|
+
node[:model] = rule['model'] if node[:group] == rule['group'] && vendor == rule['vendor']
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
node
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Advanced dynamic model selection hook for Oxidized
|
|
2
|
+
# --------------------------------------------------
|
|
3
|
+
# This hook allows you to assign Oxidized models based on any device attributes
|
|
4
|
+
# (name, vendor, group, type, IP, etc.) using flexible rules defined in the config.
|
|
5
|
+
# It uses the `source_node_transform` event and works with any source (CSV, HTTP, SQL).
|
|
6
|
+
#
|
|
7
|
+
# The hook is designed to be generic: you can specify any field that exists in the
|
|
8
|
+
# node data after source mapping (see `map` section in the source configuration).
|
|
9
|
+
# Rules are evaluated in order; the first matching rule assigns its `model`.
|
|
10
|
+
#
|
|
11
|
+
# ⚠️ IMPORTANT: For the hook to load correctly:
|
|
12
|
+
# - The filename must match the hook type (e.g., `modelrulesadvanced.rb`).
|
|
13
|
+
# - The class name must be the CamelCase version of the filename without underscores
|
|
14
|
+
# (e.g., filename `modelrulesadvanced.rb` → class `Modelrulesadvanced`).
|
|
15
|
+
# - In the Oxidized config, specify `type: modelrulesadvanced` (the filename without .rb).
|
|
16
|
+
#
|
|
17
|
+
# ⚠️ DOCKER NOTE: This hook was developed and tested in a Docker container.
|
|
18
|
+
# Ensure that your hooks directory inside the container is
|
|
19
|
+
# `/home/oxidized/.config/oxidized/hook` (singular "hook"), not "hooks".
|
|
20
|
+
# In docker-compose, mount your local hooks folder to this path, e.g.:
|
|
21
|
+
# volumes:
|
|
22
|
+
# - ./extra/hooks:/home/oxidized/.config/oxidized/hook
|
|
23
|
+
#
|
|
24
|
+
# Example scenario with NetBox:
|
|
25
|
+
# Suppose your NetBox instance returns devices with the following data (simplified):
|
|
26
|
+
# gw-001 | Mikrotik | RB750 | ro_ud | 192.168.0.167/24
|
|
27
|
+
# gw-002 | Mikrotik | RB750 | ro_ud | 192.168.0.177/24
|
|
28
|
+
# gw-003 | Mikrotik | RB750 | ro_bd | 192.168.0.178/24
|
|
29
|
+
# gw-004 | Mikrotik | RB750 | switch | 192.168.0.181/24
|
|
30
|
+
# gw-005 | Cisco | 2960 | switch | 192.168.0.179/24
|
|
31
|
+
# gw-006 | Mikrotik | RB750 | switch | 192.168.0.180/24
|
|
32
|
+
# gw-007 | Arista | 3456 | ro_ud | 192.168.0.190/24
|
|
33
|
+
#
|
|
34
|
+
# Desired model assignment:
|
|
35
|
+
# - gw-001 (exception by name) → asa
|
|
36
|
+
# - MikroTik in group `switch` with IP 192.168.0.180/24 → eltex
|
|
37
|
+
# - All other MikroTik → routeros
|
|
38
|
+
# - Cisco switches → ios
|
|
39
|
+
# - Arista devices → eos
|
|
40
|
+
#
|
|
41
|
+
# Example configuration (top-level in Oxidized config):
|
|
42
|
+
# ---
|
|
43
|
+
# username: oxidized_ssh_user
|
|
44
|
+
# password: oxidized_ssh_password
|
|
45
|
+
#
|
|
46
|
+
# hooks:
|
|
47
|
+
# modelrulesadvanced:
|
|
48
|
+
# type: modelrulesadvanced
|
|
49
|
+
# events: [source_node_transform]
|
|
50
|
+
# rules:
|
|
51
|
+
# - description: "Exception: gw-001 uses ASA model"
|
|
52
|
+
# name: gw-001
|
|
53
|
+
# model: asa
|
|
54
|
+
# - description: "Mikrotik switch with IP 192.168.0.180/24 uses eltex"
|
|
55
|
+
# vendor: Mikrotik
|
|
56
|
+
# group: switch
|
|
57
|
+
# ip: 192.168.0.180/24
|
|
58
|
+
# model: eltex
|
|
59
|
+
# - description: "All other Mikrotik devices"
|
|
60
|
+
# vendor: Mikrotik
|
|
61
|
+
# model: routeros
|
|
62
|
+
# - description: "Cisco switches"
|
|
63
|
+
# vendor: Cisco
|
|
64
|
+
# group: switch
|
|
65
|
+
# model: ios
|
|
66
|
+
# - description: "Arista devices"
|
|
67
|
+
# vendor: Arista
|
|
68
|
+
# model: eos
|
|
69
|
+
#
|
|
70
|
+
# resolve_dns: false
|
|
71
|
+
# interval: 3600
|
|
72
|
+
# rest: 0.0.0.0:8888
|
|
73
|
+
# debug: true # optional – enables detailed logging from the hook
|
|
74
|
+
#
|
|
75
|
+
# source:
|
|
76
|
+
# default: http
|
|
77
|
+
# http:
|
|
78
|
+
# url: http://netbox.test/api/dcim/devices/?status=active&has_primary_ip=true
|
|
79
|
+
# headers:
|
|
80
|
+
# Authorization: Token YOUR_API_TOKEN
|
|
81
|
+
# map:
|
|
82
|
+
# name: name
|
|
83
|
+
# vendor: device_type.manufacturer.name
|
|
84
|
+
# type: device_type.model
|
|
85
|
+
# group: role.slug
|
|
86
|
+
# ip: primary_ip.address
|
|
87
|
+
# secure: false
|
|
88
|
+
# hosts_location: results
|
|
89
|
+
# pagination: true
|
|
90
|
+
# pagination_key_name: next
|
|
91
|
+
#
|
|
92
|
+
# output:
|
|
93
|
+
# default: file
|
|
94
|
+
# file:
|
|
95
|
+
# directory: "/home/oxidized/.config/oxidized/configs"
|
|
96
|
+
#
|
|
97
|
+
# groups:
|
|
98
|
+
# ro_ud: {}
|
|
99
|
+
# ro_bd: {}
|
|
100
|
+
# switch: {}
|
|
101
|
+
#
|
|
102
|
+
# How it works:
|
|
103
|
+
# 1. Oxidized loads node data from the source (NetBox) and applies the `map`.
|
|
104
|
+
# 2. For each node, the `source_node_transform` event is triggered.
|
|
105
|
+
# 3. This hook receives a context object `ctx` containing:
|
|
106
|
+
# - `ctx.node` – the mapped node attributes (hash)
|
|
107
|
+
# - `ctx.node_raw` – the original source record (useful for unmapped fields)
|
|
108
|
+
# 4. The hook iterates through the rules defined in `cfg.rules`.
|
|
109
|
+
# 5. For each rule, it checks that every specified key (except `model` and `description`)
|
|
110
|
+
# matches the corresponding value in `ctx.node`. Comparison is case‑insensitive and
|
|
111
|
+
# strips surrounding spaces.
|
|
112
|
+
# 6. The first matching rule assigns its `model` to `ctx.node[:model]`.
|
|
113
|
+
# 7. If no rule matches, the node's `model` remains unchanged.
|
|
114
|
+
# 8. The modified (or original) node is returned; returning `nil` would exclude the node.
|
|
115
|
+
#
|
|
116
|
+
# Notes:
|
|
117
|
+
# - Rule order is crucial: place more specific rules (e.g., with IP or name) before generic ones.
|
|
118
|
+
# - The `description` field is optional and only appears in debug logs.
|
|
119
|
+
# - Any field present in `ctx.node` after mapping can be used as a match key.
|
|
120
|
+
# - For HTTP sources (NetBox), you can access additional fields via `ctx.node_raw["field"]`.
|
|
121
|
+
# - Debug logging requires `debug: true` in the global config.
|
|
122
|
+
|
|
123
|
+
class Modelrulesadvanced < Oxidized::Hook
|
|
124
|
+
# Validate that the hook configuration contains a 'rules' array.
|
|
125
|
+
def validate_cfg!
|
|
126
|
+
raise KeyError, "hook.rules is required" unless cfg.has_key?("rules")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Main hook method – called for each node during source_node_transform event.
|
|
130
|
+
def run_hook(ctx)
|
|
131
|
+
node = ctx.node
|
|
132
|
+
rules = cfg.rules || []
|
|
133
|
+
|
|
134
|
+
matched_model = nil
|
|
135
|
+
rules.each_with_index do |rule, idx|
|
|
136
|
+
match = true
|
|
137
|
+
rule.each do |key, value|
|
|
138
|
+
next if %w[model description].include?(key)
|
|
139
|
+
|
|
140
|
+
# Retrieve the corresponding value from the node (symbol or string key)
|
|
141
|
+
node_value = node[key.to_sym] || node[key.to_s]
|
|
142
|
+
if node_value.to_s.strip.downcase != value.to_s.strip.downcase
|
|
143
|
+
match = false
|
|
144
|
+
break
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
next unless match
|
|
148
|
+
|
|
149
|
+
matched_model = rule["model"]
|
|
150
|
+
desc = rule["description"] ? " (#{rule['description']})" : ""
|
|
151
|
+
logger.debug "ModelRulesAdvanced: rule #{idx + 1}#{desc} matched -> #{matched_model}"
|
|
152
|
+
break
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if matched_model
|
|
156
|
+
old_model = node[:model] || node["model"]
|
|
157
|
+
node[:model] = matched_model
|
|
158
|
+
logger.debug "ModelRulesAdvanced: changed model from #{old_model.inspect} to #{matched_model.inspect}"
|
|
159
|
+
else
|
|
160
|
+
# rubocop:disable Layout/LineLength
|
|
161
|
+
logger.debug "ModelRulesAdvanced: no rule matched, keeping existing model: #{node[:model] || node['model'].inspect}"
|
|
162
|
+
# rubocop:enable Layout/LineLength
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
node
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
### script in ~/config/oxidized/hook/srcipmap.rb ## or OXDIZED_HOME equivalent
|
|
2
|
+
###
|
|
3
|
+
### router.db:
|
|
4
|
+
### router1:1.1.1.1:cisco:c7200:10.10.10.1:somerole
|
|
5
|
+
### router2:2.2.2.2:juniper:mx80:10.10.10.2:wlc
|
|
6
|
+
### router3:3.3.3.3:juniper:mx2020:10.10.10.3:anotherrole
|
|
7
|
+
###
|
|
8
|
+
### config:
|
|
9
|
+
### source:
|
|
10
|
+
### default: csv
|
|
11
|
+
### csv:
|
|
12
|
+
### file: "/Users/ytti/.config/oxidized/router.db"
|
|
13
|
+
### delimiter: !ruby/regexp /:/
|
|
14
|
+
### map:
|
|
15
|
+
### name: 0
|
|
16
|
+
### ip: 1
|
|
17
|
+
### model: 2
|
|
18
|
+
### model_map:
|
|
19
|
+
### juniper: junos
|
|
20
|
+
### cisco: ios
|
|
21
|
+
### hooks:
|
|
22
|
+
### somename:
|
|
23
|
+
### type: srcipmap
|
|
24
|
+
### events: ["source_node_transform"]
|
|
25
|
+
###
|
|
26
|
+
###
|
|
27
|
+
###
|
|
28
|
+
### Nodes BEFORE script:
|
|
29
|
+
### {name: "router1", ip: "1.1.1.1", model: "ios"}
|
|
30
|
+
### {name: "router2", ip: "2.2.2.2", model: "junos"}
|
|
31
|
+
### {name: "router3", ip: "3.3.3.3", model: "junos"
|
|
32
|
+
###
|
|
33
|
+
### Nodes AFTER script:
|
|
34
|
+
### {name: "router1", ip: "1.1.1.1", model: "ios"}
|
|
35
|
+
### {name: "router2", ip: "10.10.10.2", model: "junos"}
|
|
36
|
+
### {name: "router3", ip: "3.3.3.3", model: "junos"}
|
|
37
|
+
|
|
38
|
+
class SrcIpMap < Oxidized::Hook
|
|
39
|
+
def run_hook(ctx)
|
|
40
|
+
# node is the node[key] that we'd return without manipulation
|
|
41
|
+
node = ctx.node
|
|
42
|
+
|
|
43
|
+
## node_raw is source specific, in CSV it is just the field number
|
|
44
|
+
_platform = ctx.node_raw[3]
|
|
45
|
+
oob_ip = ctx.node_raw[4]
|
|
46
|
+
role = ctx.node_raw[5]
|
|
47
|
+
|
|
48
|
+
### the magic
|
|
49
|
+
node[:ip] = oob_ip if role == 'wlc'
|
|
50
|
+
|
|
51
|
+
### remember to return the manipulated object, nil if you want to ignore loading node
|
|
52
|
+
node
|
|
53
|
+
end
|
|
54
|
+
end
|