oxidized 0.20.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +4 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
  4. data/.github/no-response.yml +13 -0
  5. data/.github/workflows/publishdocker.yml +13 -0
  6. data/.gitignore +4 -0
  7. data/.rubocop.yml +73 -0
  8. data/.rubocop_todo.yml +120 -0
  9. data/.travis.yml +6 -1
  10. data/CHANGELOG.md +693 -243
  11. data/Dockerfile +27 -19
  12. data/LICENSE +201 -0
  13. data/README.md +234 -913
  14. data/Rakefile +48 -7
  15. data/TODO.md +29 -23
  16. data/bin/console +1 -1
  17. data/bin/oxidized +6 -5
  18. data/docs/Configuration.md +313 -0
  19. data/docs/Creating-Models.md +140 -0
  20. data/docs/Hooks.md +274 -0
  21. data/docs/Model-Notes/AireOS.md +11 -0
  22. data/docs/Model-Notes/ArbOS.md +11 -0
  23. data/docs/Model-Notes/Comware.md +13 -0
  24. data/docs/Model-Notes/Cumulus.md +40 -0
  25. data/docs/Model-Notes/EOS.md +12 -0
  26. data/docs/Model-Notes/IOS.md +29 -0
  27. data/docs/Model-Notes/JunOS.md +33 -0
  28. data/docs/Model-Notes/LinuxGeneric.md +24 -0
  29. data/docs/Model-Notes/Netgear.md +87 -0
  30. data/docs/Model-Notes/Nokia.md +9 -0
  31. data/docs/Model-Notes/README.md +24 -0
  32. data/docs/Model-Notes/SmartAX-Huawei.md +35 -0
  33. data/docs/Model-Notes/VRP-Huawei.md +34 -0
  34. data/docs/Model-Notes/Viptela.md +12 -0
  35. data/docs/Model-Notes/XGS4600-Zyxel.md +36 -0
  36. data/docs/Outputs.md +190 -0
  37. data/docs/Ruby-API.md +199 -0
  38. data/docs/Sources.md +171 -0
  39. data/docs/Supported-OS-Types.md +227 -0
  40. data/docs/Troubleshooting.md +66 -0
  41. data/extra/nagios_check_failing_nodes.rb +9 -2
  42. data/extra/oxidized-report-git-commits +21 -40
  43. data/extra/oxidized-ubuntu.haproxy +45 -0
  44. data/extra/oxidized.logrotate +7 -0
  45. data/extra/oxidized.service +13 -0
  46. data/extra/rest_client.rb +7 -10
  47. data/extra/syslog.rb +47 -42
  48. data/lib/oxidized/cli.rb +41 -31
  49. data/lib/oxidized/config/vars.rb +9 -14
  50. data/lib/oxidized/config.rb +20 -13
  51. data/lib/oxidized/core.rb +8 -10
  52. data/lib/oxidized/hook/awssns.rb +6 -7
  53. data/lib/oxidized/hook/ciscosparkdiff.rb +43 -0
  54. data/lib/oxidized/hook/exec.rb +19 -24
  55. data/lib/oxidized/hook/githubrepo.rb +17 -17
  56. data/lib/oxidized/hook/noophook.rb +1 -1
  57. data/lib/oxidized/hook/slackdiff.rb +32 -19
  58. data/lib/oxidized/hook/xmppdiff.rb +59 -0
  59. data/lib/oxidized/hook.rb +63 -64
  60. data/lib/oxidized/input/cli.rb +22 -12
  61. data/lib/oxidized/input/exec.rb +28 -0
  62. data/lib/oxidized/input/ftp.rb +16 -15
  63. data/lib/oxidized/input/http.rb +72 -0
  64. data/lib/oxidized/input/input.rb +6 -6
  65. data/lib/oxidized/input/ssh.rb +64 -56
  66. data/lib/oxidized/input/telnet.rb +59 -102
  67. data/lib/oxidized/input/tftp.rb +9 -10
  68. data/lib/oxidized/jobs.rb +9 -10
  69. data/lib/oxidized/manager.rb +42 -44
  70. data/lib/oxidized/model/acos.rb +19 -20
  71. data/lib/oxidized/model/acsw.rb +62 -0
  72. data/lib/oxidized/model/adtran.rb +26 -0
  73. data/lib/oxidized/model/aen.rb +19 -0
  74. data/lib/oxidized/model/aireos.rb +9 -10
  75. data/lib/oxidized/model/airfiber.rb +22 -0
  76. data/lib/oxidized/model/alteonos.rb +58 -0
  77. data/lib/oxidized/model/alvarion.rb +0 -4
  78. data/lib/oxidized/model/aos.rb +11 -5
  79. data/lib/oxidized/model/aos7.rb +6 -7
  80. data/lib/oxidized/model/aosw.rb +30 -27
  81. data/lib/oxidized/model/apc_aos.rb +2 -5
  82. data/lib/oxidized/model/arbos.rb +26 -0
  83. data/lib/oxidized/model/aricentiss.rb +49 -0
  84. data/lib/oxidized/model/asa.rb +61 -22
  85. data/lib/oxidized/model/asyncos.rb +46 -0
  86. data/lib/oxidized/model/audiocodes.rb +28 -0
  87. data/lib/oxidized/model/audiocodesmp.rb +28 -0
  88. data/lib/oxidized/model/awplus.rb +84 -0
  89. data/lib/oxidized/model/axos.rb +16 -0
  90. data/lib/oxidized/model/boss.rb +77 -0
  91. data/lib/oxidized/model/br6910.rb +42 -45
  92. data/lib/oxidized/model/c4cmts.rb +6 -10
  93. data/lib/oxidized/model/cambium.rb +23 -0
  94. data/lib/oxidized/model/casa.rb +1 -1
  95. data/lib/oxidized/model/catos.rb +1 -3
  96. data/lib/oxidized/model/cisconga.rb +1 -3
  97. data/lib/oxidized/model/ciscosma.rb +42 -0
  98. data/lib/oxidized/model/ciscosmb.rb +30 -10
  99. data/lib/oxidized/model/ciscovpn3k.rb +11 -0
  100. data/lib/oxidized/model/cnos.rb +33 -0
  101. data/lib/oxidized/model/comnetms.rb +43 -0
  102. data/lib/oxidized/model/comtrol.rb +41 -0
  103. data/lib/oxidized/model/comware.rb +28 -16
  104. data/lib/oxidized/model/coriant8600.rb +3 -5
  105. data/lib/oxidized/model/coriantgroove.rb +26 -0
  106. data/lib/oxidized/model/corianttmos.rb +1 -3
  107. data/lib/oxidized/model/cumulus.rb +60 -49
  108. data/lib/oxidized/model/datacom.rb +1 -4
  109. data/lib/oxidized/model/dcnos.rb +46 -0
  110. data/lib/oxidized/model/dellx.rb +76 -0
  111. data/lib/oxidized/model/dlink.rb +5 -4
  112. data/lib/oxidized/model/dnos.rb +11 -5
  113. data/lib/oxidized/model/eciapollo.rb +34 -0
  114. data/lib/oxidized/model/edgecos.rb +49 -0
  115. data/lib/oxidized/model/edgeos.rb +12 -5
  116. data/lib/oxidized/model/edgeswitch.rb +2 -4
  117. data/lib/oxidized/model/enterasys.rb +28 -0
  118. data/lib/oxidized/model/eos.rb +8 -8
  119. data/lib/oxidized/model/fabricos.rb +4 -6
  120. data/lib/oxidized/model/fastiron.rb +66 -0
  121. data/lib/oxidized/model/fiberdriver.rb +2 -2
  122. data/lib/oxidized/model/firebrick.rb +31 -0
  123. data/lib/oxidized/model/firelinuxos.rb +41 -0
  124. data/lib/oxidized/model/firewareos.rb +3 -6
  125. data/lib/oxidized/model/fortios.rb +31 -19
  126. data/lib/oxidized/model/ftos.rb +8 -5
  127. data/lib/oxidized/model/fujitsupy.rb +5 -7
  128. data/lib/oxidized/model/gaiaos.rb +7 -11
  129. data/lib/oxidized/model/gcombnps.rb +84 -0
  130. data/lib/oxidized/model/grandstream.rb +9 -0
  131. data/lib/oxidized/model/hatteras.rb +9 -6
  132. data/lib/oxidized/model/hirschmann.rb +39 -0
  133. data/lib/oxidized/model/hpebladesystem.rb +20 -18
  134. data/lib/oxidized/model/hpemsa.rb +10 -0
  135. data/lib/oxidized/model/hpmsm.rb +84 -0
  136. data/lib/oxidized/model/ibos.rb +55 -0
  137. data/lib/oxidized/model/icotera.rb +27 -0
  138. data/lib/oxidized/model/ios.rb +63 -70
  139. data/lib/oxidized/model/iosxe.rb +5 -0
  140. data/lib/oxidized/model/iosxr.rb +2 -3
  141. data/lib/oxidized/model/ipos.rb +10 -6
  142. data/lib/oxidized/model/ironware.rb +20 -19
  143. data/lib/oxidized/model/isam.rb +5 -6
  144. data/lib/oxidized/model/junos.rb +9 -11
  145. data/lib/oxidized/model/linuxgeneric.rb +74 -0
  146. data/lib/oxidized/model/masteros.rb +3 -6
  147. data/lib/oxidized/model/mlnxos.rb +9 -10
  148. data/lib/oxidized/model/model.rb +72 -46
  149. data/lib/oxidized/model/mtrlrfs.rb +1 -4
  150. data/lib/oxidized/model/ndms.rb +23 -0
  151. data/lib/oxidized/model/netgear.rb +35 -15
  152. data/lib/oxidized/model/netonix.rb +2 -2
  153. data/lib/oxidized/model/netscaler.rb +6 -3
  154. data/lib/oxidized/model/nos.rb +5 -7
  155. data/lib/oxidized/model/nsxconfig.rb +22 -0
  156. data/lib/oxidized/model/nsxfirewall.rb +22 -0
  157. data/lib/oxidized/model/nxos.rb +13 -3
  158. data/lib/oxidized/model/oneos.rb +15 -9
  159. data/lib/oxidized/model/openbsd.rb +63 -0
  160. data/lib/oxidized/model/opengear.rb +3 -5
  161. data/lib/oxidized/model/openwrt.rb +78 -0
  162. data/lib/oxidized/model/opnsense.rb +19 -0
  163. data/lib/oxidized/model/os10.rb +46 -0
  164. data/lib/oxidized/model/outputs.rb +5 -7
  165. data/lib/oxidized/model/panos.rb +11 -12
  166. data/lib/oxidized/model/pfsense.rb +11 -6
  167. data/lib/oxidized/model/planet.rb +14 -17
  168. data/lib/oxidized/model/powerconnect.rb +24 -19
  169. data/lib/oxidized/model/procurve.rb +43 -11
  170. data/lib/oxidized/model/purityos.rb +12 -0
  171. data/lib/oxidized/model/qtech.rb +41 -0
  172. data/lib/oxidized/model/quantaos.rb +4 -6
  173. data/lib/oxidized/model/raisecom.rb +19 -0
  174. data/lib/oxidized/model/routeros.rb +26 -8
  175. data/lib/oxidized/model/saos.rb +1 -2
  176. data/lib/oxidized/model/screenos.rb +8 -11
  177. data/lib/oxidized/model/sgos.rb +45 -0
  178. data/lib/oxidized/model/siklu.rb +1 -3
  179. data/lib/oxidized/model/slxos.rb +59 -0
  180. data/lib/oxidized/model/smartax.rb +25 -0
  181. data/lib/oxidized/model/sonicos.rb +51 -0
  182. data/lib/oxidized/model/speedtouch.rb +34 -0
  183. data/lib/oxidized/model/sros.rb +96 -0
  184. data/lib/oxidized/model/stoneos.rb +32 -0
  185. data/lib/oxidized/model/supermicro.rb +6 -41
  186. data/lib/oxidized/model/tdre.rb +30 -0
  187. data/lib/oxidized/model/telco.rb +24 -0
  188. data/lib/oxidized/model/timos.rb +6 -114
  189. data/lib/oxidized/model/tmos.rb +6 -3
  190. data/lib/oxidized/model/tplink.rb +11 -11
  191. data/lib/oxidized/model/trango.rb +21 -42
  192. data/lib/oxidized/model/ucs.rb +30 -0
  193. data/lib/oxidized/model/viptela.rb +29 -0
  194. data/lib/oxidized/model/voltaire.rb +9 -12
  195. data/lib/oxidized/model/voss.rb +17 -6
  196. data/lib/oxidized/model/vrp.rb +11 -6
  197. data/lib/oxidized/model/vyatta.rb +8 -6
  198. data/lib/oxidized/model/weos.rb +20 -0
  199. data/lib/oxidized/model/xos.rb +20 -8
  200. data/lib/oxidized/model/zhoneolt.rb +2 -2
  201. data/lib/oxidized/model/zynos.rb +1 -3
  202. data/lib/oxidized/model/zynoscli.rb +36 -0
  203. data/lib/oxidized/model/zynosgs.rb +38 -0
  204. data/lib/oxidized/node/stats.rb +33 -8
  205. data/lib/oxidized/node.rb +86 -95
  206. data/lib/oxidized/nodes.rb +48 -44
  207. data/lib/oxidized/output/file.rb +32 -37
  208. data/lib/oxidized/output/git.rb +138 -153
  209. data/lib/oxidized/output/gitcrypt.rb +228 -242
  210. data/lib/oxidized/output/http.rb +35 -34
  211. data/lib/oxidized/output/output.rb +2 -3
  212. data/lib/oxidized/source/csv.rb +50 -44
  213. data/lib/oxidized/source/http.rb +58 -58
  214. data/lib/oxidized/source/source.rb +9 -10
  215. data/lib/oxidized/source/sql.rb +47 -45
  216. data/lib/oxidized/string.rb +18 -14
  217. data/lib/oxidized/version.rb +17 -1
  218. data/lib/oxidized/worker.rb +72 -33
  219. data/oxidized.gemspec +20 -19
  220. metadata +180 -36
  221. data/.ruby-version +0 -1
  222. data/Gemfile.lock +0 -44
data/Rakefile CHANGED
@@ -1,8 +1,21 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+ require_relative 'lib/oxidized/version'
3
4
 
4
5
  gemspec = eval(File.read(Dir['*.gemspec'].first))
5
- file = [gemspec.name, gemspec.version].join('-') + '.gem'
6
+ gemfile = [gemspec.name, gemspec.version].join('-') + '.gem'
7
+
8
+ # Integrate Rubocop if available
9
+ begin
10
+ require 'rubocop/rake_task'
11
+
12
+ RuboCop::RakeTask.new
13
+ task(:default).prerequisites << task(:rubocop)
14
+ rescue LoadError
15
+ task :rubocop do
16
+ puts 'Install rubocop to run its rake tasks'
17
+ end
18
+ end
6
19
 
7
20
  desc 'Validate gemspec'
8
21
  task :gemspec do
@@ -19,10 +32,16 @@ task :test do
19
32
  end
20
33
  end
21
34
 
22
- ## desc 'Install gem'
23
- ## task :install => :build do
24
- ## system "sudo -Es sh -c \'umask 022; gem install gems/#{file}\'"
25
- ## end
35
+ task build: %i[chmod version_set]
36
+ task :version_set do
37
+ Oxidized.version_set
38
+ Bundler::GemHelper.instance.gemspec.version = Oxidized::VERSION
39
+ end
40
+
41
+ # desc 'Install gem'
42
+ # task install: :build do
43
+ # system "sudo -Es sh -c \'umask 022; gem install gems/#{gemfile}\'"
44
+ # end
26
45
 
27
46
  desc 'Remove gems'
28
47
  task :clean do
@@ -35,8 +54,30 @@ task :tag do
35
54
  end
36
55
 
37
56
  desc 'Push to rubygems'
38
- task :push => :tag do
39
- system "gem push pkg/#{file}"
57
+ task push: :tag do
58
+ system "gem push pkg/#{gemfile}"
59
+ end
60
+
61
+ desc 'Normalise file permissions'
62
+ task :chmod do
63
+ xbit = %w[
64
+ bin/oxidized
65
+ bin/console
66
+ extra/auto-reload-config.runit
67
+ extra/nagios_check_failing_nodes.rb
68
+ extra/oxidized-report-git-commits
69
+ extra/oxidized.init
70
+ extra/oxidized.init.d
71
+ extra/oxidized.runit
72
+ extra/syslog.rb
73
+ extra/update-ca-certificates.runit
74
+ ]
75
+ dirs = []
76
+ %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }.each do |file|
77
+ dirs.push(File.dirname(file))
78
+ xbit.include?(file) ? File.chmod(0o0755, file) : File.chmod(0o0644, file)
79
+ end
80
+ dirs.sort.uniq.each { |dir| File.chmod(0o0755, dir) }
40
81
  end
41
82
 
42
83
  task default: :test
data/TODO.md CHANGED
@@ -1,23 +1,29 @@
1
- # refactor core
2
- * move state from memory to disk, sqlite probably
3
- * allows us to retain stats etc over restart
4
- * simplifies code
5
- * keep only running nodes in memory
6
- * negligible I/O cost, as majority is I/O wait getting config
7
-
8
- # separate login to owon package
9
- * oxidized-script is not only use-case
10
- * it would be good to have minimal package used to login to routers
11
- * oxidized just one consumer of that functionality
12
- * what to do with models, we need model to know how to login. Should models be separated to another package? oxidized-core, oxidized-models and oxidized-login?
13
- * how can we allow interactive login in oxidized-login? With functional VTY etc? REPL loop in input/ssh and input/telnet?
14
-
15
- # thread number
16
- * think about algo
17
- * if job ended later than now-iteration have rand(node.size) == 0 to add thread
18
- * if now is less than job_ended+iteration same chance to remove thread?
19
- * should we try to avoid max threads from being hit? (like maybe non-success thread is pulling average?)
20
-
21
- # docs, testing
22
- * yard docs
23
- * minitest tests
1
+ # To Do
2
+
3
+ ## refactor core
4
+
5
+ * move state from memory to disk, sqlite probably
6
+ * allows us to retain stats etc over restart
7
+ * simplifies code
8
+ * keep only running nodes in memory
9
+ * negligible I/O cost, as majority is I/O wait getting config
10
+
11
+ ## separate login to own package
12
+
13
+ * oxidized-script is not only use-case
14
+ * it would be good to have minimal package used to login to routers
15
+ * oxidized just one consumer of that functionality
16
+ * what to do with models, we need model to know how to login. Should models be separated to another package? oxidized-core, oxidized-models and oxidized-login?
17
+ * how can we allow interactive login in oxidized-login? With functional VTY etc? REPL loop in input/ssh and input/telnet?
18
+
19
+ ## thread number
20
+
21
+ * think about algo
22
+ * if job ended later than now-iteration have rand(node.size) == 0 to add thread
23
+ * if now is less than job_ended+iteration same chance to remove thread?
24
+ * should we try to avoid max threads from being hit? (like maybe non-success thread is pulling average?)
25
+
26
+ ## docs, testing
27
+
28
+ * yard docs
29
+ * minitest tests
data/bin/console CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib = File.expand_path('../../lib', __FILE__)
3
+ lib = File.expand_path('../lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  require 'oxidized'
data/bin/oxidized CHANGED
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  # FIX ME, killing oxidized needs -9
5
4
  trap("INT") { exit } # sinatra will otherwise steal this from us
6
5
 
7
6
  begin
8
- require 'oxidized/cli'
7
+ require_relative '../lib/oxidized/cli'
9
8
  Oxidized::CLI.new.run
10
- rescue => error
11
- warn "#{error}"
12
- debug = Oxidied.config.debug rescue true
9
+ rescue StandardError => error
10
+ warn error.to_s
11
+ debug = Oxidized.config.debug rescue true
13
12
  raise if debug
13
+
14
+ exit 1
14
15
  end
@@ -0,0 +1,313 @@
1
+ # Configuration
2
+
3
+ ## Debugging
4
+
5
+ In case a model plugin doesn't work correctly (ios, procurve, etc.), you can enable live debugging of SSH/Telnet sessions. Just add a `debug` option containing the value true to the `input` section. The log files will be created depending on the parent directory of the logfile option.
6
+
7
+ The following example will log an active ssh/telnet session `/home/oxidized/.config/oxidized/log/<IP-Address>-<PROTOCOL>`. The file will be truncated on each consecutive ssh/telnet session, so you need to put a `tailf` or `tail -f` on that file!
8
+
9
+ ```yaml
10
+ log: /home/oxidized/.config/oxidized/log
11
+
12
+ ...
13
+
14
+ input:
15
+ default: ssh, telnet
16
+ debug: true
17
+ ssh:
18
+ secure: false
19
+ http:
20
+ ssl_verify: true
21
+ ```
22
+
23
+ ## Privileged mode
24
+
25
+ To start privileged mode before pulling the configuration, Oxidized needs to send the enable command. You can globally enable this, by adding the following snippet to the global section of the configuration file.
26
+
27
+ ```yaml
28
+ vars:
29
+ enable: S3cre7
30
+ ```
31
+
32
+ ## Removing secrets
33
+
34
+ To strip out secrets from configurations before storing them, Oxidized needs the `remove_secret` flag. You can globally enable this by adding the following snippet to the global section of the configuration file.
35
+
36
+ ```yaml
37
+ vars:
38
+ remove_secret: true
39
+ ```
40
+
41
+ Device models that contain substitution filters to remove sensitive data will now be run on any fetched configuration.
42
+
43
+ As a partial example from ios.rb:
44
+
45
+ ```ruby
46
+ cmd :secret do |cfg|
47
+ cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
48
+ (...)
49
+ cfg
50
+ end
51
+ ```
52
+
53
+ The above strips out snmp community strings from your saved configs.
54
+
55
+ **NOTE:** Removing secrets reduces the usefulness as a full configuration backup, but it may make sharing configs easier.
56
+
57
+ ## Disabling SSH exec channels
58
+
59
+ Oxidized uses exec channels to make information extraction simpler, but there are some situations where this doesn't work well, e.g. configuring devices. This feature can be turned off by setting the `ssh_no_exec`
60
+ variable.
61
+
62
+ ```yaml
63
+ vars:
64
+ ssh_no_exec: true
65
+ ```
66
+
67
+ ## Disabling SSH keepalives
68
+
69
+ Oxidized SSH input makes use of SSH keepalives to prevent timeouts from slower devices and to quickly tear down stale sessions in larger deployments. There have been reports of SSH keepalives breaking compatibility with certain OS types. They can be disabled using the `ssh_no_keepalive` variable on a per-node basis (by specifying it in the source) or configured application-wide.
70
+
71
+ ```yaml
72
+ vars:
73
+ ssh_no_keepalive: true
74
+ ```
75
+
76
+ ## SSH Auth Methods
77
+
78
+ By default, Oxidized registers the following auth methods: `none`, `publickey` and `password`. However you can configure this globally, by groups, models or nodes.
79
+
80
+ ```yaml
81
+ vars:
82
+ auth_methods: [ "none", "publickey", "password", "keyboard-interactive" ]
83
+ ```
84
+
85
+ ## Public Key Authentication with SSH
86
+
87
+ Instead of password-based login, Oxidized can make use of key-based SSH authentication.
88
+
89
+ You can tell Oxidized to use one or more private keys globally, or specify the key to be used on a per-node basis. The latter can be done by mapping the `ssh_keys` variable through the active source.
90
+
91
+ Global:
92
+
93
+ ```yaml
94
+ vars:
95
+ ssh_keys: "~/.ssh/id_rsa"
96
+ ```
97
+
98
+ Per-Node:
99
+
100
+ ```yaml
101
+ ...
102
+ map:
103
+ name: 0
104
+ model: 1
105
+ vars_map:
106
+ enable: 2
107
+ ssh_keys: 3
108
+ ...
109
+ ```
110
+
111
+ If you are using a non-standard path, especially when copying the private key via a secured channel, make sure that the permissions are set correctly:
112
+
113
+ ```bash
114
+ foo@bar:~$ ls -la ~/.ssh/
115
+ total 20
116
+ drwx------ 2 oxidized oxidized 4096 Mar 13 17:03 .
117
+ drwx------ 5 oxidized oxidized 4096 Mar 13 21:40 ..
118
+ -r-------- 1 oxidized oxidized 103 Mar 13 17:03 authorized_keys
119
+ -rw------- 1 oxidized oxidized 399 Mar 13 17:02 id_ed25519
120
+ -rw-r--r-- 1 oxidized oxidized 94 Mar 13 17:02 id_ed25519.pub
121
+ ```
122
+
123
+ Finally, multiple private keys can be specified as an array of file paths, such as `["~/.ssh/id_rsa", "~/.ssh/id_another_rsa"]`.
124
+
125
+ ## SSH Proxy Command
126
+
127
+ Oxidized can `ssh` through a proxy as well. To do so we just need to set `ssh_proxy` variable with the proxy host information and optionally set the `ssh_proxy_port` with the SSH port if it is not listening no port 22.
128
+
129
+ This can be provided on a per-node basis by mapping the proper fields from your source.
130
+
131
+ An example for a `csv` input source that maps the 4th field as the `ssh_proxy` value and the 5th field as `ssh_proxy_port`.
132
+
133
+ ```yaml
134
+ ...
135
+ map:
136
+ name: 0
137
+ model: 1
138
+ vars_map:
139
+ enable: 2
140
+ ssh_proxy: 3
141
+ ssh_proxy_port: 4
142
+ ...
143
+ ```
144
+
145
+ ## SSH enabling legacy algorithms
146
+
147
+ When connecting to older firmware over SSH, it is sometimes necessary to enable legacy/disabled settings like KexAlgorithms, HostKeyAlgorithms, MAC or the Encryption.
148
+
149
+ These settings can be provided on a per-node basis by mapping the ssh_kex, ssh_host_key, ssh_hmac and the ssh_encryption fields from you source.
150
+
151
+ ```yaml
152
+ ...
153
+ map:
154
+ name: 0
155
+ model: 1
156
+ vars_map:
157
+ enable: 2
158
+ ssh_kex: 3
159
+ ssh_host_key: 4
160
+ ssh_hmac: 5
161
+ ssh_encryption: 6
162
+ ...
163
+ ```
164
+
165
+ ## FTP Passive Mode
166
+
167
+ Oxidized uses ftp passive mode by default. Some devices require passive mode to be disabled. To do so, we can set `input.ftp.passive` to false - this will make use of FTP active mode.
168
+
169
+ ```yaml
170
+ input:
171
+ ftp:
172
+ passive: false
173
+ ```
174
+
175
+ ## Advanced Configuration
176
+
177
+ Below is an advanced example configuration. You will be able to (optionally) override options per device. The router.db format used is `hostname:model:username:password:enable_password`. Hostname and model will be the only required options, all others override the global configuration sections.
178
+
179
+ ```yaml
180
+ ---
181
+ username: oxidized
182
+ password: S3cr3tx
183
+ model: junos
184
+ interval: 3600 #interval in seconds
185
+ log: ~/.config/oxidized/log
186
+ debug: false
187
+ threads: 30
188
+ timeout: 20
189
+ retries: 3
190
+ prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
191
+ crash:
192
+ directory: ~/.config/oxidized/crashes
193
+ hostnames: false
194
+ vars:
195
+ enable: S3cr3tx
196
+ groups: {}
197
+ rest: 127.0.0.1:8888
198
+ pid: ~/.config/oxidized/oxidized.pid
199
+ input:
200
+ default: ssh, telnet
201
+ debug: false
202
+ ssh:
203
+ secure: false
204
+ output:
205
+ default: git
206
+ git:
207
+ user: Oxidized
208
+ email: oxidized@example.com
209
+ repo: "~/.config/oxidized/oxidized.git"
210
+ source:
211
+ default: csv
212
+ csv:
213
+ file: ~/.config/oxidized/router.db
214
+ delimiter: !ruby/regexp /:/
215
+ map:
216
+ name: 0
217
+ model: 1
218
+ username: 2
219
+ password: 3
220
+ vars_map:
221
+ enable: 4
222
+ model_map:
223
+ cisco: ios
224
+ juniper: junos
225
+ ```
226
+
227
+ ## Advanced Group Configuration
228
+
229
+ For group specific credentials
230
+
231
+ ```yaml
232
+ groups:
233
+ mikrotik:
234
+ username: admin
235
+ password: blank
236
+ ubiquiti:
237
+ username: ubnt
238
+ password: ubnt
239
+ ```
240
+
241
+ and add group mapping
242
+
243
+ ```yaml
244
+ map:
245
+ model: 0
246
+ name: 1
247
+ group: 2
248
+ ```
249
+
250
+ For model specific credentials
251
+
252
+ You can add 'username: nil' if the device only expects a Password at prompt.
253
+
254
+ ```yaml
255
+ models:
256
+ junos:
257
+ username: admin
258
+ password: password
259
+ ironware:
260
+ username: admin
261
+ password: password
262
+ vars:
263
+ enable: enablepassword
264
+ apc_aos:
265
+ username: apc
266
+ password: password
267
+ cisco:
268
+ username: nil
269
+ password: pass
270
+ ```
271
+
272
+ ## RESTful API and Web Interface
273
+
274
+ 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.
275
+
276
+ ```yaml
277
+ # Listen on http://127.0.0.1:8888/
278
+ rest: 127.0.0.1:8888
279
+ ```
280
+
281
+ ```yaml
282
+ # Listen on http://10.0.0.1:8000/oxidized/
283
+ rest: 10.0.0.1:8000/oxidized
284
+ ```
285
+
286
+ ## Triggered backups
287
+
288
+ A node can be moved to head-of-queue via the REST API `GET/POST /node/next/[NODE]`. This can be useful to immediately schedule a fetch of the configuration after some other event such as a syslog message indicating a configuration update on the device.
289
+
290
+ In the default configuration this node will be processed when the next job worker becomes available, it could take some time if existing backups are in progress. To execute moved jobs immediately a new job can be added automatically:
291
+
292
+ ```yaml
293
+ next_adds_job: true
294
+ ```
295
+
296
+ This will allow for a more timely fetch of the device configuration.
297
+
298
+ ## Disabling DNS resolution
299
+
300
+ In some instances it might not be desirable to attempt to resolve names of nodes. One such use case is when nodes are accessed through an SSH proxy, where the remote end resolves the names differently than the host on which Oxidized runs would.
301
+
302
+ Names can instead be passed verbatim to the input:
303
+
304
+ ```yaml
305
+ resolve_dns: false
306
+ ```
307
+
308
+ ## Environment variables
309
+
310
+ You can use some environment variables to change default root directories values.
311
+
312
+ * `OXIDIZED_HOME` may be used to set oxidized configuration directory, which defaults to `~/.config/oxidized`
313
+ * `OXIDIZED_LOGS` may be used to set oxidzied logs and crash directories root, which default to `~/.config/oxidized`
@@ -0,0 +1,140 @@
1
+ # Creating and Extending Models
2
+
3
+ Oxidized supports a growing list of [operating system types](Supported-OS-Types.md). Out of the box, most model implementations collect configuration data. Some implementations also include a conservative set of additional commands that collect basic device information (device make and model, software version, licensing information, ...) which are appended to the configuration as comments.
4
+
5
+ A user may wish to extend an existing model to collect the output of additional commands. Oxidized offers smart loading of models in order to facilitate this with ease, without the need to introduce changes to the upstream source code.
6
+
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
+
9
+ ## Creating a new model
10
+
11
+ An Oxidized model, at minimum, requires just three elements:
12
+
13
+ * A model file, this file should be placed in the ~/.config/oxidized directory and named after the target OS type.
14
+ * A class defined within this file with the same name as the file itself that inherits from `Oxidized::Model`, the base model class.
15
+ * At least one command that will be executed and the output of which will be collected by Oxidized.
16
+
17
+ A bare-bone example for a fictional model running the OS type `rootware` could be introduced by creating the file `~/.config/oxidized/rootware.rb`, with the following content:
18
+
19
+ ```ruby
20
+ class RootWare < Oxidized::Model
21
+
22
+ cmd 'show complete-config'
23
+ ```
24
+
25
+ This model, as-is will:
26
+
27
+ * Log into the device and expect the default prompt.
28
+ * Upon matching it, execute the command `show complete-config`
29
+ * Collect the output.
30
+
31
+ It is often useful to, at minimum, define the following additional elements for any newly introduced module:
32
+
33
+ * A regexp for the prompt, via the `prompt` statement.
34
+ * A comment prefix, via the `comment` statement.
35
+ * A regexp for telnet username and password prompts.
36
+ * A mechanism for handling `enable` or similar functionality.
37
+
38
+ The API documentation contains a list of [methods](https://github.com/ytti/oxidized/blob/master/docs/Ruby-API.md#model) that can be used in modules.
39
+
40
+ A more fleshed out example can be found in the `IOS` and `JunOS` models.
41
+
42
+ ## Extending an existing model with a new command
43
+
44
+ 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.
45
+
46
+ Create the file `~/.config/oxidized/model/junos.rb` with the following contents:
47
+
48
+ ```ruby
49
+ require 'oxidized/model/junos.rb'
50
+
51
+
52
+ class JunOS
53
+
54
+
55
+ cmd 'show interfaces diagnostics optics' do |cfg|
56
+ comment cfg
57
+ end
58
+
59
+
60
+ end
61
+ ```
62
+
63
+ Due to smart loading, the user-supplied `~/.config/oxidized/model/junos.rb` file will take precedence over the model with the same name included in the Oxidized distribution.
64
+
65
+ The code then uses `require` to initially load the Oxidized-supplied model, and extends the class defined therein with an additional command.
66
+
67
+ Intuitively, it is also possible to:
68
+
69
+ * Completely re-define an existing model by creating a file in `~/.config/oxidized/model/` with the same name as an existing model, but not `require`-ing the upstream model file.
70
+ * Create a named variation of an existing model, by creating a file with a new name (such as `~/.config/oxidized/model/junos-extra.rb`), Then `require` the original model and extend its base class as in the above example. The named variation can then be specified as an OS type for specific devices that can benefit from the extra functionality. This allows for preservation of the base functionality for the default model types.
71
+ * Create a completely new model, with a new name, for a new operating system type.
72
+ * 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.
73
+
74
+ ## Advanced features
75
+
76
+ The loosely-coupled architecture of Oxidized allows for easy extensibility in more advanced use cases as well.
77
+
78
+ The example below extends the functionality of the `JunOS` model further to collect `display set` formatted configuration from the device, and utilizes the multi-output functionality of the `git` output to place the returned configuration in a separate file within a git repository.
79
+
80
+ It is possible to configure the `git` output to create new subdirectories under an existing repository instead of creating new repositories for each new defined output type (the default) by including the following configuration in the `~/.config/oxidized/config` file:
81
+
82
+ ```yaml
83
+ output:
84
+ git:
85
+ type_as_directory: true
86
+ ```
87
+
88
+ Then, `~/.config/oxidized/model/junos.rb` is adapted as following:
89
+
90
+ ```ruby
91
+ require 'oxidized/model/junos.rb'
92
+
93
+
94
+ class JunOS
95
+
96
+
97
+ cmd 'show interface diagnostic optics' do |cfg|
98
+ comment cfg
99
+ end
100
+
101
+ cmd 'show configuration | display set' do |cfg|
102
+ cfg.type = "junos-set"
103
+ cfg.name = "set"
104
+ cfg
105
+ end
106
+
107
+
108
+ end
109
+ ```
110
+
111
+ The output of the `show configuration | display set` command is marked with a new arbitrary alternative output type, `junos-set`. The `git` output will use the output type to create a new subdirectory by the same name. In this subdirectory, the `git` output will create files with the name `<devicename>--set` that will contain the output of this command for each device.
112
+
113
+ ## Monkey-patching blocks in existing models
114
+
115
+ In addition to adding new commands and blocks to existing models, Oxidized offers convenience methods for monkey-patching existing commands and blocks within existing models.
116
+
117
+ When defining a monkey-patched block, two boolean arguments can be passed as part of the block definition:
118
+
119
+ * `clear: true`, which resets the existing block, allowing the user to completely override its contents.
120
+ * `prepend: true`, which ensures that the contents of the block are prepended, rather than appended (the default) to an existing block.
121
+
122
+ This functionality is supported for `cfg`, `cmd`, `pre`, `post`, and `expect` blocks.
123
+
124
+ Examples:
125
+
126
+ ```ruby
127
+ cmd :secret clear: true do
128
+ ... "(new code for secret removal which replaces the existing :secret definition in the model)" ...
129
+ end
130
+ ```
131
+
132
+ ```ruby
133
+ cmd :ssh do prepend: true do
134
+ ... "(code that should run first, before any code in the existing :ssh definition in the model)" ...
135
+ end
136
+ ```
137
+
138
+ ## Help
139
+
140
+ If you experience difficulties creating a new model, you can often get help by installing an Internet reachable sanitized device and opening a new issue on Github asking for help with creating the model. You should research what is the device vendor name is, the vendor's OS type name is, the exact device model name and firmware version. This information should be included in the issue.