oxidized 0.30.1 → 0.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +3 -4
- data/.github/workflows/stale.yml +4 -2
- data/.rubocop.yml +18 -3
- data/.rubocop_todo.yml +4 -11
- data/CHANGELOG.md +93 -1
- data/CONTRIBUTING.md +5 -0
- data/Dockerfile +84 -20
- data/README.md +5 -21
- data/Rakefile +31 -2
- data/docs/Configuration.md +50 -14
- data/docs/Creating-Models.md +75 -4
- data/docs/DeviceSimulation.md +184 -0
- data/docs/Hooks.md +39 -5
- data/docs/Issues.md +97 -0
- data/docs/Model-Notes/APC_AOS.md +29 -16
- data/docs/Model-Notes/Cumulus.md +5 -0
- data/docs/Model-Notes/FSOS.md +6 -0
- data/docs/Model-Notes/FortiOS.md +21 -5
- data/docs/Model-Notes/HPEAruba.md +31 -0
- data/docs/Model-Notes/OS6.md +10 -0
- data/docs/Model-Notes/RouterOS.md +15 -0
- data/docs/Model-Notes/SikluMHTG.md +7 -0
- data/docs/ModelUnitTests.md +186 -0
- data/docs/Outputs.md +2 -0
- data/docs/Release.md +18 -15
- data/docs/Sources.md +21 -0
- data/docs/Supported-OS-Types.md +14 -7
- data/docs/Troubleshooting.md +35 -0
- data/examples/podman-compose/Makefile +59 -17
- data/examples/podman-compose/README.md +63 -27
- data/examples/podman-compose/docker-compose.yml +11 -2
- data/examples/podman-compose/gitserver/.gitignore +1 -0
- data/examples/podman-compose/gitserver/Dockerfile +14 -0
- data/examples/podman-compose/model-simulation/Dockerfile-model +1 -1
- data/examples/podman-compose/model-simulation/asternos.sh +2 -0
- data/examples/podman-compose/oxidized-config/.gitignore +2 -0
- data/examples/podman-compose/oxidized-config/config +1 -1
- data/examples/podman-compose/oxidized-config/config_csv-file +46 -0
- data/examples/podman-compose/oxidized-config/config_csv-gitserver +56 -0
- data/examples/podman-compose/oxidized-ssh/.gitignore +1 -0
- data/extra/device2yaml.rb +245 -0
- data/extra/gitdiff-msteams.sh +32 -5
- data/extra/nagios_check_failing_nodes.rb +1 -1
- data/extra/rest_client.rb +1 -1
- data/lib/oxidized/config.rb +8 -2
- data/lib/oxidized/hook/githubrepo.rb +37 -7
- data/lib/oxidized/hook/slackdiff.rb +29 -7
- data/lib/oxidized/input/http.rb +1 -0
- data/lib/oxidized/input/ssh.rb +13 -5
- data/lib/oxidized/input/telnet.rb +1 -1
- data/lib/oxidized/manager.rb +17 -16
- data/lib/oxidized/model/aos7.rb +2 -0
- data/lib/oxidized/model/aoscx.rb +16 -2
- data/lib/oxidized/model/aosw.rb +8 -2
- data/lib/oxidized/model/apc_aos.rb +1 -1
- data/lib/oxidized/model/arubainstant.rb +90 -0
- data/lib/oxidized/model/asa.rb +2 -1
- data/lib/oxidized/model/asyncos.rb +1 -1
- data/lib/oxidized/model/audiocodes.rb +2 -2
- data/lib/oxidized/model/cnos.rb +13 -10
- data/lib/oxidized/model/cumulus.rb +19 -2
- data/lib/oxidized/model/dlink.rb +1 -0
- data/lib/oxidized/model/dlinknextgen.rb +3 -0
- data/lib/oxidized/model/edgecos.rb +2 -1
- data/lib/oxidized/model/enterprise_sonic.rb +46 -0
- data/lib/oxidized/model/eos.rb +2 -0
- data/lib/oxidized/model/f5os.rb +17 -0
- data/lib/oxidized/model/firewareos.rb +10 -1
- data/lib/oxidized/model/fortios.rb +24 -1
- data/lib/oxidized/model/fsos.rb +5 -1
- data/lib/oxidized/model/garderos.rb +43 -0
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ibos.rb +1 -0
- data/lib/oxidized/model/ios.rb +20 -12
- data/lib/oxidized/model/iosxr.rb +1 -1
- data/lib/oxidized/model/junos.rb +1 -1
- data/lib/oxidized/model/kornfeldos.rb +33 -0
- data/lib/oxidized/model/lenovonos.rb +2 -0
- data/lib/oxidized/model/linuxgeneric.rb +1 -1
- data/lib/oxidized/model/model.rb +2 -2
- data/lib/oxidized/model/netgear.rb +1 -1
- data/lib/oxidized/model/nodegrid.rb +1 -1
- data/lib/oxidized/model/nsxdfw.rb +30 -0
- data/lib/oxidized/model/nxos.rb +2 -1
- data/lib/oxidized/model/os6.rb +48 -0
- data/lib/oxidized/model/rgos.rb +1 -1
- data/lib/oxidized/model/riverbed.rb +104 -0
- data/lib/oxidized/model/routeros.rb +2 -2
- data/lib/oxidized/model/saos.rb +18 -1
- data/lib/oxidized/model/siklumhtg.rb +22 -0
- data/lib/oxidized/model/sonicos.rb +8 -2
- data/lib/oxidized/model/tplink.rb +1 -0
- data/lib/oxidized/model/uplinkolt.rb +46 -0
- data/lib/oxidized/model/vyatta.rb +2 -2
- data/lib/oxidized/model/xos.rb +7 -0
- data/lib/oxidized/node.rb +30 -18
- data/lib/oxidized/nodes.rb +13 -5
- data/lib/oxidized/output/file.rb +45 -42
- data/lib/oxidized/output/git.rb +185 -160
- data/lib/oxidized/output/gitcrypt.rb +188 -186
- data/lib/oxidized/output/http.rb +53 -51
- data/lib/oxidized/output/output.rb +6 -4
- data/lib/oxidized/source/csv.rb +44 -49
- data/lib/oxidized/source/http.rb +63 -81
- data/lib/oxidized/source/jsonfile.rb +63 -0
- data/lib/oxidized/source/source.rb +73 -18
- data/lib/oxidized/source/sql.rb +66 -59
- data/lib/oxidized/version.rb +2 -2
- data/oxidized.gemspec +25 -18
- metadata +115 -21
data/docs/Configuration.md
CHANGED
@@ -9,7 +9,7 @@ The following example will log an active ssh/telnet session `/home/oxidized/.con
|
|
9
9
|
```yaml
|
10
10
|
log: /home/oxidized/.config/oxidized/log
|
11
11
|
|
12
|
-
...
|
12
|
+
# ...
|
13
13
|
|
14
14
|
input:
|
15
15
|
default: ssh, telnet
|
@@ -45,7 +45,7 @@ As a partial example from ios.rb:
|
|
45
45
|
```ruby
|
46
46
|
cmd :secret do |cfg|
|
47
47
|
cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
|
48
|
-
|
48
|
+
# ...
|
49
49
|
cfg
|
50
50
|
end
|
51
51
|
```
|
@@ -98,14 +98,14 @@ vars:
|
|
98
98
|
Per-Node:
|
99
99
|
|
100
100
|
```yaml
|
101
|
-
...
|
101
|
+
# ...
|
102
102
|
map:
|
103
103
|
name: 0
|
104
104
|
model: 1
|
105
105
|
vars_map:
|
106
106
|
enable: 2
|
107
107
|
ssh_keys: 3
|
108
|
-
...
|
108
|
+
# ...
|
109
109
|
```
|
110
110
|
|
111
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:
|
@@ -131,7 +131,7 @@ This can be provided on a per-node basis by mapping the proper fields from your
|
|
131
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
132
|
|
133
133
|
```yaml
|
134
|
-
...
|
134
|
+
# ...
|
135
135
|
map:
|
136
136
|
name: 0
|
137
137
|
model: 1
|
@@ -139,7 +139,7 @@ vars_map:
|
|
139
139
|
enable: 2
|
140
140
|
ssh_proxy: 3
|
141
141
|
ssh_proxy_port: 4
|
142
|
-
...
|
142
|
+
# ...
|
143
143
|
```
|
144
144
|
|
145
145
|
## SSH enabling legacy algorithms
|
@@ -149,7 +149,7 @@ When connecting to older firmware over SSH, it is sometimes necessary to enable
|
|
149
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
150
|
|
151
151
|
```yaml
|
152
|
-
...
|
152
|
+
# ...
|
153
153
|
map:
|
154
154
|
name: 0
|
155
155
|
model: 1
|
@@ -159,7 +159,7 @@ vars_map:
|
|
159
159
|
ssh_host_key: 4
|
160
160
|
ssh_hmac: 5
|
161
161
|
ssh_encryption: 6
|
162
|
-
...
|
162
|
+
# ...
|
163
163
|
```
|
164
164
|
|
165
165
|
## FTP Passive Mode
|
@@ -174,7 +174,16 @@ input:
|
|
174
174
|
|
175
175
|
## Advanced Configuration
|
176
176
|
|
177
|
-
Below is an advanced example configuration.
|
177
|
+
Below is an advanced example configuration.
|
178
|
+
|
179
|
+
You will be able to (optionally) override options per device.
|
180
|
+
The router.db format used is `hostname:model:username:password:enable_password`.
|
181
|
+
Hostname and model will be the only required options, all others override the
|
182
|
+
global configuration sections.
|
183
|
+
|
184
|
+
Custom model names can be mapped to an oxidized model name with a string or
|
185
|
+
a regular expression.
|
186
|
+
|
178
187
|
|
179
188
|
```yaml
|
180
189
|
---
|
@@ -226,6 +235,7 @@ source:
|
|
226
235
|
model_map:
|
227
236
|
cisco: ios
|
228
237
|
juniper: junos
|
238
|
+
!ruby/regexp /procurve/: procurve
|
229
239
|
```
|
230
240
|
|
231
241
|
## Advanced Group Configuration
|
@@ -242,13 +252,15 @@ groups:
|
|
242
252
|
password: ubnt
|
243
253
|
```
|
244
254
|
|
245
|
-
Model specific variables within groups
|
255
|
+
Model specific variables/credentials within groups
|
246
256
|
|
247
257
|
```yaml
|
248
258
|
groups:
|
249
259
|
foo:
|
250
260
|
models:
|
251
261
|
arista:
|
262
|
+
username: admin
|
263
|
+
password: password
|
252
264
|
vars:
|
253
265
|
ssh_keys: "~/.ssh/id_rsa_foo_arista"
|
254
266
|
vyatta:
|
@@ -260,11 +272,14 @@ groups:
|
|
260
272
|
vars:
|
261
273
|
ssh_keys: "~/.ssh/id_rsa_bar_routeros"
|
262
274
|
vyatta:
|
275
|
+
username: admin
|
276
|
+
password: pass
|
263
277
|
vars:
|
264
278
|
ssh_keys: "~/.ssh/id_rsa_bar_vyatta"
|
265
279
|
```
|
266
280
|
|
267
|
-
For mapping multiple group values to a common name
|
281
|
+
For mapping multiple group values to a common name, you can use strings and
|
282
|
+
regular expressions:
|
268
283
|
|
269
284
|
```yaml
|
270
285
|
group_map:
|
@@ -272,17 +287,18 @@ group_map:
|
|
272
287
|
alias2: groupA
|
273
288
|
alias3: groupB
|
274
289
|
alias4: groupB
|
290
|
+
!ruby/regexp /specialgroup/: groupS
|
275
291
|
aliasN: groupZ
|
276
|
-
...
|
292
|
+
# ...
|
277
293
|
```
|
278
294
|
|
279
295
|
add group mapping to a source
|
280
296
|
|
281
297
|
```yaml
|
282
298
|
source:
|
283
|
-
...
|
299
|
+
# ...
|
284
300
|
<source>:
|
285
|
-
...
|
301
|
+
# ...
|
286
302
|
map:
|
287
303
|
model: 0
|
288
304
|
name: 1
|
@@ -311,15 +327,35 @@ models:
|
|
311
327
|
password: pass
|
312
328
|
```
|
313
329
|
|
330
|
+
### Options (credentials, vars, etc.) precedence:
|
331
|
+
From least to most important:
|
332
|
+
- global options
|
333
|
+
- model specific options
|
334
|
+
- group specific options
|
335
|
+
- model specific options in groups
|
336
|
+
- options defined on single nodes
|
337
|
+
|
338
|
+
More important options overwrite less important ones if they are set.
|
339
|
+
|
314
340
|
## RESTful API and Web Interface
|
315
341
|
|
316
342
|
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.
|
317
343
|
|
344
|
+
```yaml
|
345
|
+
# Listen on http://[::1]:8888/
|
346
|
+
rest: "[::1]:8888"
|
347
|
+
```
|
348
|
+
|
318
349
|
```yaml
|
319
350
|
# Listen on http://127.0.0.1:8888/
|
320
351
|
rest: 127.0.0.1:8888
|
321
352
|
```
|
322
353
|
|
354
|
+
```yaml
|
355
|
+
# Listen on http://[2001:db8:0:face:b001:0:dead:beaf]:8888/oxidized/
|
356
|
+
rest: "[2001:db8:0:face:b001:0:dead:beaf]:8888"
|
357
|
+
```
|
358
|
+
|
323
359
|
```yaml
|
324
360
|
# Listen on http://10.0.0.1:8000/oxidized/
|
325
361
|
rest: 10.0.0.1:8000/oxidized
|
data/docs/Creating-Models.md
CHANGED
@@ -6,6 +6,14 @@ A user may wish to extend an existing model to collect the output of additional
|
|
6
6
|
|
7
7
|
This methodology allows local site changes to be preserved during Oxidized version updates / gem updates. It also enables convenient local development of new models.
|
8
8
|
|
9
|
+
## Index
|
10
|
+
- [Creating a new model](#creating-a-new-model)
|
11
|
+
- [Extending an existing model with a new command](#extending-an-existing-model-with-a-new-command)
|
12
|
+
- [Create unit tests for the model](#create-unit-tests-for-the-model)
|
13
|
+
- [Advanced features](#advanced-features)
|
14
|
+
- [Monkey-patching blocks in existing models](#monkey-patching-blocks-in-existing-models)
|
15
|
+
- [Help](#help)
|
16
|
+
|
9
17
|
## Creating a new model
|
10
18
|
|
11
19
|
An Oxidized model, at minimum, requires just three elements:
|
@@ -21,13 +29,19 @@ class RootWare < Oxidized::Model
|
|
21
29
|
using Refinements
|
22
30
|
|
23
31
|
cmd 'show complete-config'
|
32
|
+
|
33
|
+
cfg :ssh do
|
34
|
+
pre_logout 'exit'
|
35
|
+
end
|
36
|
+
end
|
24
37
|
```
|
25
38
|
|
26
39
|
This model, as-is will:
|
27
40
|
|
28
|
-
* Log into the device and expect the default prompt.
|
41
|
+
* Log into the device with ssh and expect the default prompt.
|
29
42
|
* Upon matching it, execute the command `show complete-config`
|
30
43
|
* Collect the output.
|
44
|
+
* Logout with the command `exit`
|
31
45
|
|
32
46
|
It is often useful to, at minimum, define the following additional elements for any newly introduced module:
|
33
47
|
|
@@ -40,6 +54,52 @@ The API documentation contains a list of [methods](https://github.com/ytti/oxidi
|
|
40
54
|
|
41
55
|
A more fleshed out example can be found in the `IOS` and `JunOS` models.
|
42
56
|
|
57
|
+
### Common task: mechanism for handling 'enable' mode
|
58
|
+
The following code snippet demonstrates how to handle sending the 'enable'
|
59
|
+
command and an enable password.
|
60
|
+
|
61
|
+
This example is taken from the `IOS` model. It covers scenarios where users
|
62
|
+
need to enable privileged mode, either without providing a password (by setting
|
63
|
+
`enable: true` in the configuration) or with a password.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
cfg :telnet, :ssh do
|
67
|
+
post_login do
|
68
|
+
if vars(:enable) == true
|
69
|
+
cmd "enable"
|
70
|
+
elsif vars(:enable)
|
71
|
+
cmd "enable", /^[pP]assword:/
|
72
|
+
cmd vars(:enable)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
Note: remove `:telnet, ` if your device does not support telnet.
|
78
|
+
|
79
|
+
### Common Task: remove ANSI escape codes
|
80
|
+
> :warning: This common task is experimental.
|
81
|
+
> If it does not work for you, please open an issue so that we can adapt the
|
82
|
+
> code snippet.
|
83
|
+
|
84
|
+
Some devices produce ANSI escape codes to enhance the appearance of output.
|
85
|
+
However, this can make prompt matching difficult and some of these ANSI escape
|
86
|
+
codes might end up in the resulting configuration.
|
87
|
+
|
88
|
+
You can remove most [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands) using the following Ruby
|
89
|
+
code in your model:
|
90
|
+
```
|
91
|
+
# Remove ANSI escape codes
|
92
|
+
expect /\e\[[0-?]*[ -\/]*[@-~]\r?/ do |data, re|
|
93
|
+
data.gsub re, ''
|
94
|
+
end
|
95
|
+
```
|
96
|
+
Explanation of the Regular Expression:
|
97
|
+
- `\e\[` : Control Sequence Introducer (CSI), which starts with "ESC [".
|
98
|
+
- `[0-?]*` : "Parameter" bytes (range 0x30–0x3F, corresponding to ASCII `0–9:;<=>?`).
|
99
|
+
- `[ -\/]*`: "Intermediate" bytes (range 0x20–0x2F, corresponding to ASCII ` !"#$%&'()*+,-./`).
|
100
|
+
- `[@-~]` : The "final" byte (range 0x40–0x7E, corresponding to ASCII ``@A–Z[\]^_`a–z{|}~).[``).
|
101
|
+
- `\r?` : Some ESC codes include a carriage return, which we do not want in the resulting config.
|
102
|
+
|
43
103
|
## Extending an existing model with a new command
|
44
104
|
|
45
105
|
The example below can be used to extend the `JunOS` model to collect the output of `show interfaces diagnostics optics` and append the output to the configuration file as a comment. This command retrieves DOM information on pluggable optics present in a `JunOS`-powered chassis.
|
@@ -72,6 +132,17 @@ Intuitively, it is also possible to:
|
|
72
132
|
* Create a completely new model, with a new name, for a new operating system type.
|
73
133
|
* Testing/validation of an updated model from the [Oxidized GitHub repo models](https://github.com/ytti/oxidized/tree/master/lib/oxidized/model) by placing an updated model in the proper location without disrupting the gem-supplied model files.
|
74
134
|
|
135
|
+
## Create Unit Tests for the Model
|
136
|
+
If you want the model to be integrated into Oxidized, you can
|
137
|
+
[submit a pull request on GitHub](https://github.com/ytti/oxidized/pulls).
|
138
|
+
This is a greatly appreciated submission, as there are probably other users
|
139
|
+
using the same network device as you are.
|
140
|
+
|
141
|
+
A good (and optional) practice for submissions is to provide a
|
142
|
+
[unit test for your model](/docs/ModelUnitTests.md). This reduces the risk that
|
143
|
+
further developments could break it, and facilitates debugging issues without
|
144
|
+
having access to a physical network device for the model.
|
145
|
+
|
75
146
|
## Advanced features
|
76
147
|
|
77
148
|
The loosely-coupled architecture of Oxidized allows for easy extensibility in more advanced use cases as well.
|
@@ -124,19 +195,19 @@ Examples:
|
|
124
195
|
|
125
196
|
```ruby
|
126
197
|
cmd :secret, clear: true do
|
127
|
-
... "(new code for secret removal which replaces the existing :secret definition in the model)" ...
|
198
|
+
# ... "(new code for secret removal which replaces the existing :secret definition in the model)" ...
|
128
199
|
end
|
129
200
|
```
|
130
201
|
|
131
202
|
```ruby
|
132
203
|
cmd 'show version', clear: true do |cfg|
|
133
|
-
... "(new code for parsing 'show version', replaces the existing definition in the model)" ...
|
204
|
+
# ... "(new code for parsing 'show version', replaces the existing definition in the model)" ...
|
134
205
|
end
|
135
206
|
```
|
136
207
|
|
137
208
|
```ruby
|
138
209
|
cmd :ssh, prepend: true do
|
139
|
-
... "(code that should run first, before any code in the existing :ssh definition in the model)" ...
|
210
|
+
# ... "(code that should run first, before any code in the existing :ssh definition in the model)" ...
|
140
211
|
end
|
141
212
|
```
|
142
213
|
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# Device Simulation
|
2
|
+
Oxidized supports [150+ devices](/docs/Supported-OS-Types.md).
|
3
|
+
|
4
|
+
No developer has access to all of these devices, which makes the task of
|
5
|
+
maintaining Oxidized difficult:
|
6
|
+
|
7
|
+
- Issues can't be resolved because the developer has no access to the device.
|
8
|
+
- Further developments can produce regressions.
|
9
|
+
|
10
|
+
In order to address this, we can simulate the devices. An example of a
|
11
|
+
simulation is the [model unit tests](/spec/model), but one could also simulate a
|
12
|
+
device within an SSH server.
|
13
|
+
|
14
|
+
The simulation of devices is currently focused on SSH-based devices. This may be
|
15
|
+
extended to other inputs like Telnet or FTP in the future.
|
16
|
+
|
17
|
+
## YAML Simulation Data
|
18
|
+
The underlying data for the simulation is a [YAML](https://yaml.org/) file in
|
19
|
+
which we store all relevant information about the device. The most important
|
20
|
+
information is the responses to the commands used in the Oxidized models.
|
21
|
+
|
22
|
+
The YAML simulation files are stored under
|
23
|
+
[/spec/model/data/](/spec/model/data/), with the naming convention
|
24
|
+
`<model>:<description>:simulation.yaml`, where `<model>` is the lowercase name
|
25
|
+
of the Oxidized model and `<description>` is the name of the test case.
|
26
|
+
`<description>` is generally formatted as `<hardware>_<software>` or
|
27
|
+
`<hardware>_<software>_<information>`.
|
28
|
+
|
29
|
+
### Creating a YAML Simulation File with device2yaml.rb
|
30
|
+
A device does not only output the ASCII text we can see in the console.
|
31
|
+
It adds ANSI escape codes for nice colors, bold and underline, \r, and so on.
|
32
|
+
These are key factors in prompt issues, so they must be represented in the YAML
|
33
|
+
file. We use the Ruby string format with interpolations like \r, \e, and so on.
|
34
|
+
Another important point is trailing spaces at the end of lines. Some text
|
35
|
+
editors automatically remove trailing spaces, so we code them with \x20.
|
36
|
+
|
37
|
+
Although a YAML file could be written by hand, this is quite a tedious task to
|
38
|
+
catch all the extra codes and code them into YAML. This can be automated with
|
39
|
+
the Ruby script [extra/device2yaml.rb](/extra/device2yaml.rb).
|
40
|
+
|
41
|
+
`device2yaml.rb` needs Ruby and the gem
|
42
|
+
[net-ssh](https://rubygems.org/gems/net-ssh/) to run. On Debian, you can install
|
43
|
+
them with `sudo apt install ruby-net-ssh`.
|
44
|
+
|
45
|
+
Run `extra/device2yaml.rb`, the online help tells you the options.
|
46
|
+
```
|
47
|
+
oxidized$ extra/device2yaml.rb
|
48
|
+
Missing a host to connect to...
|
49
|
+
|
50
|
+
Usages:
|
51
|
+
- device2yaml.rb [user@]host -i file [options]
|
52
|
+
- device2yaml.rb [user@]host -c "command1
|
53
|
+
command2
|
54
|
+
command3" [options]
|
55
|
+
|
56
|
+
-i and -c are mutualy exclusive, one must be specified
|
57
|
+
|
58
|
+
[options]:
|
59
|
+
-c, --commands "command list" specify the commands to be run
|
60
|
+
-i, --input file Specify an input file for commands to be run
|
61
|
+
-o, --output file Specify an output YAML-file
|
62
|
+
-t, --timeout value Specify the idle timeout beween commands (default: 5 seconds)
|
63
|
+
-e, --exec-mode Run ssh in exec mode (without tty)
|
64
|
+
-h, --help Print this help
|
65
|
+
```
|
66
|
+
|
67
|
+
- `[user@]host` specifies the user and host to connect to the device. The
|
68
|
+
password will be prompted interactively by the script. If you do not specify a
|
69
|
+
user, it will use the user executing the script.
|
70
|
+
- The commands that will be run on the device must be defined in
|
71
|
+
`deviceyaml.rb`. You can give the commands online with `-c` or read them from a
|
72
|
+
file (one line per command) with `-i`. The commands should match exactly the
|
73
|
+
ones of the model (no abbreviations) and include the commands of the
|
74
|
+
`post_login` and `pre_logout` sections. When using `-c` and editing the shell
|
75
|
+
command line, `CTRL-V CTRL-J` is very useful to add a line break.
|
76
|
+
- `device2yaml.rb` waits an idle timeout after the last received data
|
77
|
+
before sending the next command. The default is 5 seconds. If your device makes
|
78
|
+
a longer pause than 5 seconds before or within a command, you will see that the
|
79
|
+
output of the command is shortened or slips into the next command in the YAML
|
80
|
+
file. You will have to change the idle timeout to a greater value to address
|
81
|
+
this.
|
82
|
+
- When run without the output argument, `device2yaml.rb` will only print the SSH
|
83
|
+
output to the standard output. You must use `-o <model:HW_SW:simulation.yaml>`
|
84
|
+
to store the collected data in a YAML file.
|
85
|
+
- If your Oxidized model uses SSH exec mode (look for `exec true` in the model),
|
86
|
+
you will have to use the option `-e` to run `device2yaml.rb` in SSH exec mode.
|
87
|
+
|
88
|
+
Note that `device2yaml.rb` takes some time to run because of the idle timeout of
|
89
|
+
(default) 5 seconds between each command. You can press the "Escape" key if you
|
90
|
+
know there is no more data to come for the current command (when you see the
|
91
|
+
prompt for the next command), and the script will stop waiting and directly
|
92
|
+
process the next command.
|
93
|
+
|
94
|
+
|
95
|
+
Running the script against an ios device would look like:
|
96
|
+
```shell
|
97
|
+
extra/device2yaml.rb oxidized@r61 -c "terminal length 0
|
98
|
+
terminal width 0
|
99
|
+
show version
|
100
|
+
show vtp status
|
101
|
+
show inventory
|
102
|
+
show running-config
|
103
|
+
exit" -o spec/model/data/ios:C8200L_16.12.1:simulation.yaml
|
104
|
+
```
|
105
|
+
### Publishing the YAML Simulation File to Oxidized
|
106
|
+
Publishing the YAML simulation file of your device helps maintain Oxidized. This
|
107
|
+
task may take some time, and we are very grateful that you take this time for
|
108
|
+
the community!
|
109
|
+
|
110
|
+
You should pay attention to removing or replacing anything you don't want to
|
111
|
+
share with the rest of the world, for example:
|
112
|
+
|
113
|
+
- Passwords
|
114
|
+
- IP Addresses
|
115
|
+
- Serial numbers
|
116
|
+
|
117
|
+
You can also shorten the configuration if you want - we don't need 48 times the
|
118
|
+
same configuration for each interface, but it doesn't hurt either.
|
119
|
+
|
120
|
+
Take your time, this is an important task: after you have uploaded your file on
|
121
|
+
GitHub, it may be impossible to remove it.
|
122
|
+
You can use search/replace to make consistent and faster changes, for example
|
123
|
+
change the hostname everywhere.
|
124
|
+
|
125
|
+
The YAML simulation files are stored under
|
126
|
+
[/spec/model/data/](/spec/model/data/), with the naming convention
|
127
|
+
`<model>:<description>:simulation.yaml`, where `<model>` is the lowercase name
|
128
|
+
of the Oxidized model and `<description>` is the name of the test case.
|
129
|
+
`<description>` is generally formatted as `<hardware>_<software>` or
|
130
|
+
`<hardware>_<software>_<information>`.
|
131
|
+
|
132
|
+
Using a correct name for the file is important to ensure it is included in
|
133
|
+
automatic model unit tests.
|
134
|
+
|
135
|
+
Examples:
|
136
|
+
|
137
|
+
- spec/model/data/aoscx:R0X25A-6410_FL.10.10.1100:simulation.yaml
|
138
|
+
- spec/model/data/asa:5512_9.12-4-67_single-context:simulation.yaml
|
139
|
+
- spec/model/data/ios:C9200L-24P-4G_17.09.04a:simulation.yaml
|
140
|
+
|
141
|
+
When you are finished, commit and push to your forked repository on GitHub, and
|
142
|
+
submit a Pull Request. Thank you for your help!
|
143
|
+
|
144
|
+
### Interactive Mode
|
145
|
+
The `device2yaml.rb` script is basic and sometimes needs some help, especially
|
146
|
+
when dealing with a device that sends its output page by page and requires you
|
147
|
+
to press space for the next page. `device2yaml.rb` does not know how to handle
|
148
|
+
this.
|
149
|
+
|
150
|
+
While `device2yaml.rb` is running, you can type anything on the keyboard, and it
|
151
|
+
will be sent to the remote device. So you can press space or 'n' to get the next
|
152
|
+
page.
|
153
|
+
|
154
|
+
You can also use this to enter an enable password.
|
155
|
+
|
156
|
+
If you press the "Esc" key, `device2yaml.rb` will not wait for the idle timeout
|
157
|
+
and will process the next command right away.
|
158
|
+
|
159
|
+
### YAML Format
|
160
|
+
The YAML file has two sections:
|
161
|
+
- init_prompt: describing the lines sent by the device before we can send a
|
162
|
+
command. It usually includes MOTD banners and must include the first prompt.
|
163
|
+
- commands: the commands the Oxidized model sends to the network device and
|
164
|
+
their outputs.
|
165
|
+
|
166
|
+
The outputs are multiline and use YAML block scalars (`|`), with the trailing \n
|
167
|
+
removed (`-` after `|`). The outputs include the echo of the given command and
|
168
|
+
the next prompt. Escape characters are coded in Ruby style (\n, \r...).
|
169
|
+
|
170
|
+
Here is a shortened example of a YAML file:
|
171
|
+
```yaml
|
172
|
+
---
|
173
|
+
init_prompt: |-
|
174
|
+
\e[4m\rLAB-R1234_Garderos#\e[m\x20
|
175
|
+
commands:
|
176
|
+
show system version: |-
|
177
|
+
show system version
|
178
|
+
grs-gwuz-armel/003_005_068 (Garderos; 2021-04-30 16:19:35)
|
179
|
+
\e[4m\rLAB-R1234_Garderos#\e[m\x20
|
180
|
+
# ...
|
181
|
+
exit: ""
|
182
|
+
```
|
183
|
+
|
184
|
+
|
data/docs/Hooks.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
You can define an arbitrary number of hooks that subscribe to different events. The hook system is modular and different kind of hook types can be enabled.
|
4
4
|
|
5
|
+
1. [Events](#events)
|
6
|
+
2. Hook types
|
7
|
+
* [exec](#hook-type-exec)
|
8
|
+
* [githubrepo](#hook-type-githubrepo)
|
9
|
+
* [awssns](#hook-type-awssns)
|
10
|
+
* [slackdiff](#hook-type-slackdiff)
|
11
|
+
* [ciscosparkdiff](#ciscosparkdiff)
|
12
|
+
* [xmppdiff](#hook-type-xmppdiff)
|
13
|
+
|
5
14
|
## Configuration
|
6
15
|
|
7
16
|
Following configuration keys need to be defined for all hooks:
|
@@ -184,6 +193,31 @@ hooks:
|
|
184
193
|
privatekey: /root/.ssh/id_rsa
|
185
194
|
```
|
186
195
|
|
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.
|
220
|
+
|
187
221
|
## Hook type: awssns
|
188
222
|
|
189
223
|
The `awssns` hook publishes messages to AWS SNS topics. This allows you to notify other systems of device configuration changes, for example a config orchestration pipeline. Multiple services can subscribe to the same AWS topic.
|
@@ -225,13 +259,15 @@ gem install slack-ruby-client
|
|
225
259
|
|
226
260
|
### slackdiff hook configuration example
|
227
261
|
|
262
|
+
> Please note that the channel needs to be your Slack channel ID.
|
263
|
+
|
228
264
|
```yaml
|
229
265
|
hooks:
|
230
266
|
slack:
|
231
267
|
type: slackdiff
|
232
268
|
events: [post_store]
|
233
269
|
token: SLACK_BOT_TOKEN
|
234
|
-
channel: "
|
270
|
+
channel: "CHANNEL_ID"
|
235
271
|
```
|
236
272
|
|
237
273
|
The token parameter is a Slack API token that can be generated following [this tutorial](https://api.slack.com/tutorials/tracks/getting-a-token). Until Slack stops supporting them, legacy tokens can also be used.
|
@@ -244,13 +280,11 @@ hooks:
|
|
244
280
|
type: slackdiff
|
245
281
|
events: [post_store]
|
246
282
|
token: SLACK_BOT_TOKEN
|
247
|
-
channel: "
|
283
|
+
channel: "CHANNEL_ID"
|
248
284
|
diff: false
|
249
285
|
message: "%{node} %{group} %{model} updated https://git.intranet/network-changes/commit/%{commitref}"
|
250
286
|
```
|
251
287
|
|
252
|
-
Note the channel name must be in quotes.
|
253
|
-
|
254
288
|
A proxy can optionally be specified if needed to reach the Slack API endpoint.
|
255
289
|
|
256
290
|
```yaml
|
@@ -259,7 +293,7 @@ hooks:
|
|
259
293
|
type: slackdiff
|
260
294
|
events: [post_store]
|
261
295
|
token: SLACK_BOT_TOKEN
|
262
|
-
channel: "#
|
296
|
+
channel: "#CHANNEL_ID"
|
263
297
|
proxy: http://myproxy:8080
|
264
298
|
```
|
265
299
|
|
data/docs/Issues.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Writing good issues
|
2
|
+
If you're experiencing a problem with Oxidized or need a new feature, you can
|
3
|
+
[submit an issue on github](https://github.com/ytti/oxidized/issues). We have
|
4
|
+
a great community where users help each other through the issue system.
|
5
|
+
|
6
|
+
This guide provides tips on writing your issue to make it easier for the
|
7
|
+
community and developers to understand and respond effectively.
|
8
|
+
|
9
|
+
Why write good issues?
|
10
|
+
- A clear and detailed issue improves the chances of getting your problem resolved.
|
11
|
+
- By spending time to write a good issue, you save developers time, contributing
|
12
|
+
to Oxidized’s progress without writing a line of code.
|
13
|
+
|
14
|
+
## Submit to the correct project
|
15
|
+
Choose the appropriate GitHub project based on your issue:
|
16
|
+
|
17
|
+
- For issues with the web frontend or REST API, go to
|
18
|
+
[oxidized-web](https://github.com/ytti/oxidized-web/).
|
19
|
+
- For issues with oxidized-script, use
|
20
|
+
[oxidized-script](https://github.com/ytti/oxidized-script). (note: as of
|
21
|
+
November 2024, oxidized-script is not actively maintained).
|
22
|
+
- For issues with third-party software relying on Oxidized, open an issue in
|
23
|
+
that specific project.
|
24
|
+
- For issues with Oxidized itself, go to
|
25
|
+
[oxidized](https://github.com/ytti/oxidized).
|
26
|
+
|
27
|
+
## Format your issue
|
28
|
+
- Use [GitHub Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) to format your issue.
|
29
|
+
- Preview your text before submitting to ensure it renders correctly.
|
30
|
+
- Avoid screenshots of text. Instead, use [code formating](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#quoting-code) for any relevant code snippets.
|
31
|
+
|
32
|
+
## Choose your title well
|
33
|
+
Keep the title brief yet descriptive. Aim to summarize the main issue or request in a few words.
|
34
|
+
|
35
|
+
## Provide detailled informations
|
36
|
+
Include as many relevant details as possible. At a minimum, specify:
|
37
|
+
|
38
|
+
- Oxidized version and operating system.
|
39
|
+
- Relevant parts of your Oxidized configuration and a brief explanation of your setup.
|
40
|
+
- Output of the error, if relevant.
|
41
|
+
- For issues related to specific devices, consider creating a YAML Simulation file (instructions below).
|
42
|
+
|
43
|
+
Also, provide clear steps to reproduce the issue, if applicable.
|
44
|
+
|
45
|
+
## Making feature requests
|
46
|
+
Feature requests are welcome, but please understand that unaddressed requests
|
47
|
+
may be closed after some time. If you need a feature urgently, consider
|
48
|
+
contributing code via a pull request (PR) or hiring a developer.
|
49
|
+
|
50
|
+
## Sumbit a YAML Simulation File
|
51
|
+
To help developers troubleshoot device-specific issues, you may be asked to submit a
|
52
|
+
[YAML simulation file](/docs/DeviceSimulation.md#creating-a-yaml-file-with-device2yamlrb) for your device.
|
53
|
+
|
54
|
+
Here's a brief overview how to do it, you can find more details in the link
|
55
|
+
above.
|
56
|
+
- Fork Oxidized on github
|
57
|
+
- Install dependencies (git and Ruby's Net::SSH):
|
58
|
+
```
|
59
|
+
# Adapt when not using a debian-based distro
|
60
|
+
sudo apt install git ruby-net-ssh
|
61
|
+
```
|
62
|
+
- Clone your forked Oxidized repository:
|
63
|
+
```
|
64
|
+
git clone git@github.com:<your github user>/oxidized.git
|
65
|
+
```
|
66
|
+
- run the `extra/device2yaml.rb` script (you’ll be provided with the command to
|
67
|
+
run) from the repository root:
|
68
|
+
|
69
|
+
```
|
70
|
+
extra/device2yaml.rb oxidized@r61 -c "terminal length 0
|
71
|
+
terminal width 0
|
72
|
+
show version
|
73
|
+
show vtp status
|
74
|
+
show inventory
|
75
|
+
show running-config
|
76
|
+
exit" -o spec/model/data/ios:C8200L_16.12.1:simulation.yaml
|
77
|
+
```
|
78
|
+
|
79
|
+
- The script waits 5 seconds between commands, and outputs the response of the
|
80
|
+
device. You can press "ESC" if you see the prompt and want to pass to next
|
81
|
+
command without waiting for the timeout.
|
82
|
+
- The result will be stored in `spec/model/data/`.
|
83
|
+
- Replace any sensitive information with placeholder values in the output file.
|
84
|
+
- Commit & push the file to github
|
85
|
+
```
|
86
|
+
git add spec/model/data/ios:C8200L_16.12.1:simulation.yaml
|
87
|
+
git commit -m "Device simulation for C8200L"
|
88
|
+
git push
|
89
|
+
```
|
90
|
+
- Create a pull request (PR) in GitHub, referencing the issue number (e.g.,
|
91
|
+
"YAML simulation file for issue #1234").
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|