oxidized 0.29.1 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. checksums.yaml +4 -4
  2. data/.coderabbit.yaml +21 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +45 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  5. data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
  6. data/.github/workflows/codeql.yml +4 -4
  7. data/.github/workflows/publishdocker.yml +108 -13
  8. data/.github/workflows/ruby.yml +3 -12
  9. data/.github/workflows/stale.yml +6 -1
  10. data/.gitignore +2 -0
  11. data/.rubocop.yml +69 -13
  12. data/.rubocop_todo.yml +13 -143
  13. data/CHANGELOG.md +431 -4
  14. data/CONTRIBUTING.md +189 -0
  15. data/Dockerfile +89 -34
  16. data/README.md +59 -188
  17. data/Rakefile +58 -12
  18. data/bin/oxidized +2 -5
  19. data/docs/Configuration.md +382 -149
  20. data/docs/Creating-Models.md +262 -10
  21. data/docs/DeviceSimulation.md +196 -0
  22. data/docs/Docker.md +246 -0
  23. data/docs/Hooks.md +146 -51
  24. data/docs/Inputs.md +237 -0
  25. data/docs/Issues.md +123 -0
  26. data/docs/Model-Notes/APC.md +72 -0
  27. data/docs/Model-Notes/Cumulus.md +5 -0
  28. data/docs/Model-Notes/EatonNetwork.md +18 -0
  29. data/docs/Model-Notes/ExaLink.md +43 -0
  30. data/docs/Model-Notes/FSOS.md +17 -0
  31. data/docs/Model-Notes/Fortinet.md +75 -0
  32. data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
  33. data/docs/Model-Notes/HPEAruba.md +32 -0
  34. data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
  35. data/docs/Model-Notes/OS6.md +10 -0
  36. data/docs/Model-Notes/README.md +1 -20
  37. data/docs/Model-Notes/RouterOS.md +28 -0
  38. data/docs/Model-Notes/SikluMHTG.md +7 -0
  39. data/docs/Model-Notes/TrueNAS.md +23 -0
  40. data/docs/Model-Notes/XGS4600-Zyxel.md +5 -0
  41. data/docs/ModelUnitTests.md +219 -0
  42. data/docs/Outputs.md +102 -5
  43. data/docs/Release.md +102 -0
  44. data/docs/Ruby-API.md +135 -2
  45. data/docs/Sources.md +34 -0
  46. data/docs/Supported-OS-Types.md +207 -270
  47. data/docs/Troubleshooting.md +43 -1
  48. data/extra/device2yaml.rb +259 -0
  49. data/extra/gitdiff-msteams.sh +32 -5
  50. data/extra/hooks/modelrules.rb +55 -0
  51. data/extra/hooks/modelrulesadvanced.rb +167 -0
  52. data/extra/hooks/srcipmap.rb +54 -0
  53. data/extra/nagios_check_failing_nodes.rb +1 -1
  54. data/extra/oxidized.runit +1 -1
  55. data/extra/rest_client.rb +5 -4
  56. data/extra/syslog.rb +11 -6
  57. data/lib/oxidized/cli/support.rb +152 -0
  58. data/lib/oxidized/cli.rb +21 -6
  59. data/lib/oxidized/config/vars.rb +33 -14
  60. data/lib/oxidized/config.rb +28 -17
  61. data/lib/oxidized/core.rb +50 -8
  62. data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
  63. data/lib/oxidized/hook/exec.rb +5 -4
  64. data/lib/oxidized/hook/githubrepo.rb +55 -18
  65. data/lib/oxidized/hook/noophook.rb +2 -2
  66. data/lib/oxidized/hook/slackdiff.rb +50 -14
  67. data/lib/oxidized/hook/xmppdiff.rb +9 -9
  68. data/lib/oxidized/hook.rb +68 -16
  69. data/lib/oxidized/input/cli.rb +8 -3
  70. data/lib/oxidized/input/debugtext.rb +40 -0
  71. data/lib/oxidized/input/debugyaml.rb +82 -0
  72. data/lib/oxidized/input/exec.rb +2 -11
  73. data/lib/oxidized/input/ftp.rb +2 -19
  74. data/lib/oxidized/input/http.rb +67 -17
  75. data/lib/oxidized/input/input.rb +35 -14
  76. data/lib/oxidized/input/scp.rb +27 -0
  77. data/lib/oxidized/input/ssh.rb +59 -83
  78. data/lib/oxidized/input/sshbase.rb +102 -0
  79. data/lib/oxidized/input/telnet.rb +20 -19
  80. data/lib/oxidized/input/tftp.rb +8 -8
  81. data/lib/oxidized/job.rb +18 -7
  82. data/lib/oxidized/jobs.rb +11 -1
  83. data/lib/oxidized/logger.rb +51 -0
  84. data/lib/oxidized/manager.rb +18 -17
  85. data/lib/oxidized/model/acos.rb +2 -1
  86. data/lib/oxidized/model/addpack.rb +26 -0
  87. data/lib/oxidized/model/adtran.rb +5 -1
  88. data/lib/oxidized/model/adva.rb +3 -3
  89. data/lib/oxidized/model/airfiber.rb +1 -1
  90. data/lib/oxidized/model/aos7.rb +11 -0
  91. data/lib/oxidized/model/aoscx.rb +37 -29
  92. data/lib/oxidized/model/aosw.rb +39 -29
  93. data/lib/oxidized/model/apc_aos.rb +7 -2
  94. data/lib/oxidized/model/apcaos.rb +39 -0
  95. data/lib/oxidized/model/aricentiss.rb +9 -2
  96. data/lib/oxidized/model/arubainstant.rb +93 -0
  97. data/lib/oxidized/model/asa.rb +11 -10
  98. data/lib/oxidized/model/asternos.rb +22 -0
  99. data/lib/oxidized/model/asyncos.rb +3 -3
  100. data/lib/oxidized/model/audiocodes.rb +2 -2
  101. data/lib/oxidized/model/awplus.rb +15 -12
  102. data/lib/oxidized/model/axos.rb +1 -1
  103. data/lib/oxidized/model/bdcom.rb +1 -0
  104. data/lib/oxidized/model/c4cmts.rb +1 -2
  105. data/lib/oxidized/model/ciscosma.rb +1 -1
  106. data/lib/oxidized/model/ciscosmb.rb +6 -1
  107. data/lib/oxidized/model/cnos.rb +13 -10
  108. data/lib/oxidized/model/comtrol.rb +1 -1
  109. data/lib/oxidized/model/comware.rb +5 -3
  110. data/lib/oxidized/model/cumulus.rb +14 -2
  111. data/lib/oxidized/model/defacto.rb +26 -0
  112. data/lib/oxidized/model/dellx.rb +1 -1
  113. data/lib/oxidized/model/dlink.rb +5 -2
  114. data/lib/oxidized/model/dlinknextgen.rb +55 -0
  115. data/lib/oxidized/model/dnos.rb +3 -0
  116. data/lib/oxidized/model/dslcommands.rb +93 -0
  117. data/lib/oxidized/model/dslsetup.rb +102 -0
  118. data/lib/oxidized/model/eatonnetwork.rb +70 -0
  119. data/lib/oxidized/model/edgecos.rb +3 -1
  120. data/lib/oxidized/model/edgeos.rb +7 -6
  121. data/lib/oxidized/model/edgeswitch.rb +3 -1
  122. data/lib/oxidized/model/efos.rb +41 -0
  123. data/lib/oxidized/model/eltex.rb +4 -2
  124. data/lib/oxidized/model/enterasys800.rb +2 -2
  125. data/lib/oxidized/model/enterprise_sonic.rb +46 -0
  126. data/lib/oxidized/model/eos.rb +3 -1
  127. data/lib/oxidized/model/exalink.rb +36 -0
  128. data/lib/oxidized/model/f5os.rb +17 -0
  129. data/lib/oxidized/model/fabricos.rb +2 -2
  130. data/lib/oxidized/model/fastiron.rb +5 -3
  131. data/lib/oxidized/model/firebrick.rb +2 -2
  132. data/lib/oxidized/model/firelinuxos.rb +13 -6
  133. data/lib/oxidized/model/firewareos.rb +10 -1
  134. data/lib/oxidized/model/fortigate.rb +160 -0
  135. data/lib/oxidized/model/fortios.rb +38 -48
  136. data/lib/oxidized/model/fsos.rb +46 -0
  137. data/lib/oxidized/model/gaiaos.rb +4 -4
  138. data/lib/oxidized/model/garderos.rb +38 -0
  139. data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
  140. data/lib/oxidized/model/h3c.rb +1 -1
  141. data/lib/oxidized/model/ibos.rb +1 -0
  142. data/lib/oxidized/model/ingate.rb +47 -0
  143. data/lib/oxidized/model/ios.rb +57 -30
  144. data/lib/oxidized/model/iosxr.rb +2 -2
  145. data/lib/oxidized/model/ironware.rb +7 -5
  146. data/lib/oxidized/model/ivanti.rb +54 -0
  147. data/lib/oxidized/model/junos.rb +12 -5
  148. data/lib/oxidized/model/kornfeldos.rb +33 -0
  149. data/lib/oxidized/model/lenovonos.rb +2 -0
  150. data/lib/oxidized/model/linksyssrw.rb +3 -3
  151. data/lib/oxidized/model/linuxgeneric.rb +4 -2
  152. data/lib/oxidized/model/macros.rb +60 -0
  153. data/lib/oxidized/model/mimosab11.rb +34 -0
  154. data/lib/oxidized/model/ml66.rb +33 -0
  155. data/lib/oxidized/model/mlnxos.rb +18 -14
  156. data/lib/oxidized/model/model.rb +98 -103
  157. data/lib/oxidized/model/mtrlrfs.rb +1 -0
  158. data/lib/oxidized/model/ndms.rb +6 -0
  159. data/lib/oxidized/model/netgear.rb +14 -3
  160. data/lib/oxidized/model/netonix.rb +1 -1
  161. data/lib/oxidized/model/netscaler.rb +1 -1
  162. data/lib/oxidized/model/nodegrid.rb +1 -1
  163. data/lib/oxidized/model/nsxdfw.rb +31 -0
  164. data/lib/oxidized/model/nsxfirewall.rb +2 -1
  165. data/lib/oxidized/model/nxos.rb +20 -15
  166. data/lib/oxidized/model/ocnos.rb +42 -0
  167. data/lib/oxidized/model/onefinity.rb +18 -0
  168. data/lib/oxidized/model/openbsd.rb +1 -1
  169. data/lib/oxidized/model/opengear.rb +36 -1
  170. data/lib/oxidized/model/openwrt.rb +6 -6
  171. data/lib/oxidized/model/opnsense.rb +9 -1
  172. data/lib/oxidized/model/os6.rb +48 -0
  173. data/lib/oxidized/model/outputs.rb +5 -0
  174. data/lib/oxidized/model/panos.rb +2 -0
  175. data/lib/oxidized/model/perle.rb +41 -0
  176. data/lib/oxidized/model/pfsense.rb +9 -0
  177. data/lib/oxidized/model/powerconnect.rb +32 -11
  178. data/lib/oxidized/model/procurve.rb +6 -2
  179. data/lib/oxidized/model/qtech.rb +3 -1
  180. data/lib/oxidized/model/quantaos.rb +8 -6
  181. data/lib/oxidized/model/rgos.rb +33 -0
  182. data/lib/oxidized/model/riverbed.rb +104 -0
  183. data/lib/oxidized/model/routeros.rb +18 -11
  184. data/lib/oxidized/model/saos.rb +18 -1
  185. data/lib/oxidized/model/saos10.rb +38 -0
  186. data/lib/oxidized/model/siklu.rb +1 -1
  187. data/lib/oxidized/model/siklumhtg.rb +22 -0
  188. data/lib/oxidized/model/sixwind.rb +28 -0
  189. data/lib/oxidized/model/slxos.rb +3 -3
  190. data/lib/oxidized/model/smartbyte.rb +48 -0
  191. data/lib/oxidized/model/sonicos.rb +27 -20
  192. data/lib/oxidized/model/speedtouch.rb +1 -1
  193. data/lib/oxidized/model/sros.rb +3 -3
  194. data/lib/oxidized/model/srosmd.rb +1 -1
  195. data/lib/oxidized/model/supermicro.rb +1 -1
  196. data/lib/oxidized/model/telco.rb +1 -1
  197. data/lib/oxidized/model/tmos.rb +1 -0
  198. data/lib/oxidized/model/tnsr.rb +57 -0
  199. data/lib/oxidized/model/tplink.rb +5 -5
  200. data/lib/oxidized/model/trango.rb +4 -2
  201. data/lib/oxidized/model/truenas.rb +64 -3
  202. data/lib/oxidized/model/ucs.rb +1 -1
  203. data/lib/oxidized/model/unifiap.rb +144 -0
  204. data/lib/oxidized/model/uplinkolt.rb +46 -0
  205. data/lib/oxidized/model/voltaire.rb +1 -1
  206. data/lib/oxidized/model/voss.rb +3 -0
  207. data/lib/oxidized/model/vrp.rb +5 -1
  208. data/lib/oxidized/model/vyatta.rb +9 -3
  209. data/lib/oxidized/model/vyos.rb +37 -0
  210. data/lib/oxidized/model/xos.rb +10 -1
  211. data/lib/oxidized/model/zhoneolt.rb +4 -2
  212. data/lib/oxidized/model/zynos.rb +67 -3
  213. data/lib/oxidized/model/zynosadsl.rb +14 -0
  214. data/lib/oxidized/model/zynoscli.rb +1 -1
  215. data/lib/oxidized/model/zynosgs.rb +2 -0
  216. data/lib/oxidized/model/zynosmgs.rb +32 -0
  217. data/lib/oxidized/node.rb +99 -64
  218. data/lib/oxidized/nodes.rb +40 -19
  219. data/lib/oxidized/output/file.rb +80 -43
  220. data/lib/oxidized/output/git.rb +295 -151
  221. data/lib/oxidized/output/gitcrypt.rb +193 -185
  222. data/lib/oxidized/output/http.rb +63 -51
  223. data/lib/oxidized/output/output.rb +20 -4
  224. data/lib/oxidized/signals.rb +44 -0
  225. data/lib/oxidized/source/csv.rb +49 -49
  226. data/lib/oxidized/source/http.rb +76 -63
  227. data/lib/oxidized/source/jsonfile.rb +68 -0
  228. data/lib/oxidized/source/source.rb +73 -18
  229. data/lib/oxidized/source/sql.rb +71 -59
  230. data/lib/oxidized/version.rb +6 -4
  231. data/lib/oxidized/worker.rb +57 -29
  232. data/lib/oxidized.rb +4 -24
  233. data/lib/refinements.rb +21 -1
  234. data/oxidized.gemspec +45 -21
  235. metadata +248 -41
  236. data/lib/oxidized/model/timos.rb +0 -10
data/lib/oxidized/jobs.rb CHANGED
@@ -44,6 +44,14 @@ module Oxidized
44
44
  @want = @max if @want > @max
45
45
  end
46
46
 
47
+ def increment
48
+ # Increments the job count if safe to do so, which means:
49
+ # a) less threads running than the total amount of nodes
50
+ # b) we want less than the max specified number of threads
51
+
52
+ @want = [(@want + 1), @nodes.size, @max].min
53
+ end
54
+
47
55
  def work
48
56
  # if a) we want less or same amount of threads as we now running
49
57
  # and b) we want less threads running than the total amount of nodes
@@ -51,7 +59,9 @@ module Oxidized
51
59
  # then we want one more thread (rationale is to fix hanging thread causing HOLB)
52
60
  return unless @want <= size && @want < @nodes.size
53
61
 
54
- @want += 1 if (Time.now.utc - @last) > MAX_INTER_JOB_GAP
62
+ return unless @want <= size
63
+
64
+ increment if (Time.now.utc - @last) > MAX_INTER_JOB_GAP
55
65
  end
56
66
  end
57
67
  end
@@ -0,0 +1,51 @@
1
+ require 'semantic_logger'
2
+
3
+ module Oxidized
4
+ module Logger
5
+ include SemanticLogger::Loggable
6
+
7
+ def self.setup
8
+ config = Oxidized.config
9
+ FileUtils.mkdir_p(Config::LOG) unless File.directory?(Config::LOG)
10
+
11
+ SemanticLogger.add_signal_handler
12
+
13
+ if config.use_syslog?
14
+ SemanticLogger.add_appender(appender: :syslog)
15
+ logger.warn("The configuration 'use_syslog' is deprecated. " \
16
+ "Remove it and use 'logger' instead")
17
+ elsif config.log?
18
+ SemanticLogger.add_appender(file_name: File.expand_path(config.log))
19
+ logger.warn("The configuration 'log' is deprecated. " \
20
+ "Remove it and use 'logger' instead")
21
+ elsif config.logger?
22
+ SemanticLogger.default_level = config.logger.level if config.logger.level?
23
+ config.logger.appenders.each { |a| add_appender a } if config.logger.has_key?('appenders')
24
+ end
25
+
26
+ # No appenders configured
27
+ SemanticLogger.add_appender(io: $stderr) if SemanticLogger.appenders.empty?
28
+
29
+ return if %i[trace debug].include?(SemanticLogger.default_level)
30
+
31
+ SemanticLogger.default_level = :debug if config.debug?
32
+ end
33
+
34
+ def self.add_appender(appender)
35
+ case appender['type']
36
+ when 'file'
37
+ params = { file_name: File.expand_path(appender['file']) }
38
+ when 'stderr'
39
+ params = { io: $stderr }
40
+ when 'stdout'
41
+ params = { io: $stdout }
42
+ when 'syslog'
43
+ params = { appender: :syslog, application: "oxidized" }
44
+ else
45
+ raise InvalidConfig, "Unknown logger #{appender['type']}, edit #{Oxidized::Config.configfile}"
46
+ end
47
+ params[:level] = appender['level'] if appender.has_key?('level')
48
+ SemanticLogger.add_appender(**params)
49
+ end
50
+ end
51
+ end
@@ -5,15 +5,16 @@ module Oxidized
5
5
  require 'oxidized/source/source'
6
6
  class Manager
7
7
  class << self
8
- def load(dir, file)
8
+ def load(dir, file, namespace)
9
9
  require File.join dir, file + '.rb'
10
- klass = nil
11
- [Oxidized, Object].each do |mod|
12
- klass = mod.constants.find { |const| const.to_s.casecmp(file).zero? }
13
- klass ||= mod.constants.find { |const| const.to_s.downcase == 'oxidized' + file.downcase }
14
- klass = mod.const_get klass if klass
15
- break if klass
16
- end
10
+
11
+ # Search the object to load in namespace
12
+ klass = namespace.constants.find { |const| const.to_s.casecmp(file).zero? }
13
+
14
+ return false unless klass
15
+
16
+ klass = namespace.const_get klass
17
+
17
18
  i = klass.new
18
19
  i.setup if i.respond_to? :setup
19
20
  { file => klass }
@@ -33,32 +34,32 @@ module Oxidized
33
34
  end
34
35
 
35
36
  def add_input(name)
36
- loader @input, Config::InputDir, "input", name
37
+ loader @input, Config::INPUT_DIR, "input", name, Oxidized
37
38
  end
38
39
 
39
40
  def add_output(name)
40
- loader @output, Config::OutputDir, "output", name
41
+ loader @output, Config::OUTPUT_DIR, "output", name, Oxidized::Output
41
42
  end
42
43
 
43
44
  def add_source(name)
44
- loader @source, Config::SourceDir, "source", name
45
+ loader @source, Config::SOURCE_DIR, "source", name, Oxidized::Source
45
46
  end
46
47
 
47
48
  def add_model(name)
48
- loader @model, Config::ModelDir, "model", name
49
+ loader @model, Config::MODEL_DIR, "model", name, Object
49
50
  end
50
51
 
51
52
  def add_hook(name)
52
- loader @hook, Config::HookDir, "hook", name
53
+ loader @hook, Config::HOOK_DIR, "hook", name, Object
53
54
  end
54
55
 
55
56
  private
56
57
 
57
58
  # if local version of file exists, load it, else load global - return falsy value if nothing loaded
58
- def loader(hash, global_dir, local_dir, name)
59
- dir = File.join(Config::Root, local_dir)
60
- map = Manager.load(dir, name) if File.exist? File.join(dir, name + ".rb")
61
- map ||= Manager.load(global_dir, name)
59
+ def loader(hash, global_dir, local_dir, name, namespace)
60
+ dir = File.join(Config::ROOT, local_dir)
61
+ map = Manager.load(dir, name, namespace) if File.exist? File.join(dir, name + ".rb")
62
+ map ||= Manager.load(global_dir, name, namespace)
62
63
  hash.merge!(map) if map
63
64
  end
64
65
  end
@@ -20,6 +20,7 @@ class ACOS < Oxidized::Model
20
20
  cfg.gsub! /\s(Memory).*/, ' \\1 <removed>'
21
21
  cfg.gsub! /\s(Current time is).*/, ' \\1 <removed>'
22
22
  cfg.gsub! /\s(The system has been up).*/, ' \\1 <removed>'
23
+ cfg.gsub! /\s(Hardware: \d+ CPUs\(Stepping \d+\). Single \d+G drive. Free storage is).*/, ' \\1 <removed>'
23
24
  comment cfg
24
25
  end
25
26
 
@@ -72,7 +73,7 @@ class ACOS < Oxidized::Model
72
73
  out << "! partition: #{partition}"
73
74
  arules.each do |name|
74
75
  cmd("show aflex #{name} partition #{partition}") do |cfg|
75
- content = cfg.split(/Content:/).last.strip
76
+ content = cfg.split("Content:").last.strip
76
77
  out << "aflex create #{name}"
77
78
  out << content
78
79
  out << ".\n"
@@ -0,0 +1,26 @@
1
+ class AddPack < Oxidized::Model
2
+ # Used in AddPack Voip, such as AP100B, AP100_G2, AP700, AP1000, AP1100F
3
+
4
+ using Refinements
5
+ PROMPT = /^.*[>#]\s?$/
6
+
7
+ expect /-- [Mm]ore --/ do |data, re|
8
+ send ' '
9
+ data.sub re, ''
10
+ end
11
+
12
+ prompt PROMPT
13
+ cmd 'enable'
14
+
15
+ cmd 'show running-config' do |cfg|
16
+ cfg.gsub! /^Building configuration.../, ''
17
+ cfg.gsub! /^*show running-config/, ''
18
+ cfg.gsub! PROMPT, ''
19
+ cfg
20
+ end
21
+
22
+ cfg :telnet do
23
+ username /[Ll]ogin:\s?/
24
+ password /[Pp]assword:\s?/
25
+ end
26
+ end
@@ -14,7 +14,11 @@ class Adtran < Oxidized::Model
14
14
  cfg
15
15
  end
16
16
 
17
- cmd 'show running-config'
17
+ cmd 'show running-config' do |cfg|
18
+ # Strip out line at the top which displays the current date/time
19
+ # ! Created : Mon Jun 26 2023 10:07:07
20
+ cfg.gsub! /! Createds+:.*\n/, ''
21
+ end
18
22
 
19
23
  cfg :ssh do
20
24
  if vars :enable
@@ -6,7 +6,7 @@
6
6
  class ADVA < Oxidized::Model
7
7
  using Refinements
8
8
 
9
- prompt /\w+\-+[#>]\s?$/
9
+ prompt /\w+-+[#>]\s?$/
10
10
  comment '# '
11
11
 
12
12
  cmd :secret do |cfg|
@@ -18,7 +18,7 @@ class ADVA < Oxidized::Model
18
18
  cfg.cut_both
19
19
  end
20
20
 
21
- cmd 'show running-config current' do |cfg|
21
+ cmd 'show running-config delta' do |cfg|
22
22
  cfg.each_line.reject { |line| line.match /^Preparing configuration file.*/ }.join
23
23
  end
24
24
 
@@ -44,7 +44,7 @@ class ADVA < Oxidized::Model
44
44
 
45
45
  cmd 'show ports' do |cfg|
46
46
  cfg.each_line do |line|
47
- port = line.match(/\|((access|network)[^\|]+)\|/)
47
+ port = line.match(/\|((access|network)[^|]+)\|/)
48
48
  ports << port if port
49
49
  end
50
50
  end
@@ -3,7 +3,7 @@ class Airfiber < Oxidized::Model
3
3
 
4
4
  # Ubiquiti Airfiber (tested with Airfiber 11FX)
5
5
 
6
- prompt /^AF[\w\.-]+#/i
6
+ prompt /^AF[\w.-]+#/i
7
7
 
8
8
  cmd :all do |cfg|
9
9
  cfg.cut_both
@@ -4,6 +4,8 @@ class AOS7 < Oxidized::Model
4
4
  # Alcatel-Lucent Operating System Version 7 (Linux based)
5
5
  # used in OmniSwitch 6900/10k
6
6
 
7
+ prompt /^([\w.@-]+ ?[#>]\s?)$/
8
+
7
9
  comment '! '
8
10
 
9
11
  cmd :all do |cfg, cmdstring|
@@ -24,14 +26,23 @@ class AOS7 < Oxidized::Model
24
26
  end
25
27
 
26
28
  cmd 'show hardware-info' do |cfg|
29
+ # Remove extra lines occuring when the command runs slow
30
+ cfg.gsub! /^Please wait...\n/, ''
31
+ cfg.gsub! /^\n\n\n/, "\n\n"
27
32
  comment cfg
28
33
  end
29
34
 
30
35
  cmd 'show running-directory' do |cfg|
36
+ # Remove extra lines occuring when the command runs slow
37
+ cfg.gsub! /^Please wait...\n/, ''
38
+ cfg.gsub! /^\n\n/, "\n"
31
39
  comment cfg
32
40
  end
33
41
 
34
42
  cmd 'show configuration snapshot' do |cfg|
43
+ # Remove extra lines occuring when the command runs slow
44
+ cfg.gsub! /^Please wait...\n/, ''
45
+ cfg.gsub! /^\n\n/, "\n"
35
46
  cfg
36
47
  end
37
48
 
@@ -1,25 +1,13 @@
1
1
  class Aoscx < Oxidized::Model
2
2
  using Refinements
3
+ # HPE Aruba Networking - ArubaOS-CX models
3
4
 
4
- # previous command is repeated followed by "\eE", which sometimes ends up on last line
5
- # ssh switches prompt may start with \r, followed by the prompt itself, regex ([\w\s.-]+[#>] ), which ends the line
6
- # telnet switchs may start with various vt100 control characters, regex (\e\[24;[0-9][hH]), follwed by the prompt, followed
7
- # by at least 3 other vt100 characters
8
- prompt /(^\r|\e\[24;[0-9][hH])?([\w\s.-]+[#>] )($|(\e\[24;[0-9][0-9]?[hH]){3})/
5
+ prompt /^[\w\s.-]+[#>] $/
6
+ clean :escape_codes
9
7
 
10
8
  comment '! '
11
9
 
12
- # replace next line control sequence with a new line
13
- expect /(\e\[1M\e\[\??\d+(;\d+)*[A-Za-z]\e\[1L)|(\eE)/ do |data, re|
14
- data.gsub re, "\n"
15
- end
16
-
17
- # replace all used vt100 control sequences
18
- expect /\e\[\??\d+(;\d+)*[A-Za-z]/ do |data, re|
19
- data.gsub re, ''
20
- end
21
-
22
- expect /Press any key to continue(\e\[\??\d+(;\d+)*[A-Za-z])*$/ do
10
+ expect /Press any key to continue$/ do
23
11
  send ' '
24
12
  ""
25
13
  end
@@ -30,19 +18,15 @@ class Aoscx < Oxidized::Model
30
18
  end
31
19
 
32
20
  cmd :all do |cfg|
33
- cfg = cfg.cut_both
34
- cfg = cfg.gsub /^\r/, ''
35
- # Additional filtering for elder switches sending vt100 control chars via telnet
36
- cfg.gsub! /\e\[\??\d+(;\d+)*[A-Za-z]/, ''
37
- # Additional filtering for power usage reporting which obviously changes over time
38
- cfg.gsub! /^(.*AC [0-9]{3}V\/?([0-9]{3}V)?) *([0-9]{1,3}) (.*)/, '\\1 <removed> \\4'
39
- cfg
21
+ cfg.cut_both
40
22
  end
41
23
 
42
24
  cmd :secret do |cfg|
25
+ cfg.gsub! /^(user .* group .*(?: ciphertext)?) \S+/, '\\1 <secret hidden>'
43
26
  cfg.gsub! /^(snmp-server community) \S+(.*)/, '\\1 <secret hidden> \\2'
44
27
  cfg.gsub! /^(snmp-server host \S+) \S+(.*)/, '\\1 <secret hidden> \\2'
45
- cfg.gsub! /^(radius-server host \S+ key) \S+(.*)/, '\\1 <secret hidden> \\2'
28
+ cfg.gsub! /^(snmpv3 user).*?(auth (?:md5|sha(?:\d{1,3})?) auth-pass ciphertext).*?(priv (?:des|aes(?:\d{1,3})?) priv-pass ciphertext).*/, '\\1 <user> \\2 <auth-pass> \\3 <priv-pass>'
29
+ cfg.gsub! /^(radius-server host \S+ key(?: ciphertext)?) \S+ (.*)/, '\\1 <secret hidden> \\2'
46
30
  cfg.gsub! /^(radius-server key).*/, '\\1 <configuration removed>'
47
31
  cfg.gsub! /^(tacacs-server host \S+ key) \S+(.*)/, '\\1 <secret hidden> \\2'
48
32
  cfg.gsub! /^(tacacs-server key).*/, '\\1 <secret hidden>'
@@ -53,11 +37,32 @@ class Aoscx < Oxidized::Model
53
37
  comment cfg
54
38
  end
55
39
 
40
+ def with_section(cfg, section, &block)
41
+ cfg.sub!(/(show environment #{section}.*?-{10,}\n)(.*?)(?=\nshow environment|\z)/m) do
42
+ header = ::Regexp.last_match(1)
43
+ content = ::Regexp.last_match(2)
44
+ block.call(content) if block_given?
45
+ header + content
46
+ end
47
+ end
48
+
56
49
  cmd 'show environment' do |cfg|
57
- cfg.gsub! /^(LC.*\s+)\d+\s+$/, '\\1<hidden>'
58
- cfg.gsub! /^(\d\/\d\/\d.*\s+)\d+\s+$/, '\\1<hidden>'
59
- cfg.gsub! /^(\d+\/\S+\s+\S+\s+)\d+\.\d+\s+C(.*)/, '\\1<hidden>\\2'
60
- cfg.gsub! /^(LC.*\s+)\d+\.\d+\s+(C.*)$/, '\\1 <hidden> \\2'
50
+ with_section(cfg, 'fan') do |content|
51
+ content.gsub!(/^((?:\S+ +){3})(slow |normal|medium|fast |max |N\/A ) (.*?)\d+ +$/, '\\1<speed> \\3<rpm>')
52
+ end
53
+
54
+ with_section(cfg, 'power-consumption') do |content|
55
+ content.gsub!(/^(.*?) (?:\d+\.\d+ +)+\d+\.\d+$/, '\\1 <power hidden>')
56
+ content.gsub!(/^(Total Power Consumption +)\d+\.\d+$/, '\\1<power hidden>')
57
+ end
58
+
59
+ with_section(cfg, 'power-allocation') do |content|
60
+ content.gsub!(/^(.*) \d+ W$/, '\\1 <power>')
61
+ end
62
+
63
+ with_section(cfg, 'temperature') do |content|
64
+ content.gsub!(/^(.*) -?\d+\.\d+ C (.*)$/, '\\1 <hidden>\\2')
65
+ end
61
66
  comment cfg
62
67
  end
63
68
 
@@ -69,7 +74,10 @@ class Aoscx < Oxidized::Model
69
74
  comment cfg
70
75
  end
71
76
 
72
- cmd 'show system | exclude "Up Time" | exclude "CPU" | exclude "Memory"' do |cfg|
77
+ cmd 'show system' do |cfg|
78
+ cfg = cfg.reject_lines [
79
+ "Up Time", "CPU", "Memory", /Pkts .x/, "Lowest", "Missed"
80
+ ]
73
81
  comment cfg
74
82
  end
75
83
 
@@ -12,69 +12,79 @@ class AOSW < Oxidized::Model
12
12
  # All IAPs connected to a Instant Controller will have the same config output. Only the controller needs to be monitored.
13
13
 
14
14
  comment '# '
15
- prompt /^([\w\(:.@-]+(\)?\s?)[#>]\s?)$/
15
+ # see /spec/model/aosw_spec.rb for prompt examples
16
+ prompt /^\(?[\w:.@-]+\)? ?[*^]?(\[[\w\/]+\] ?)?[#>] ?$/
17
+
18
+ # Ignore cariage returns - also for the prompt
19
+ expect "\r" do |data, re|
20
+ data.gsub re, ''
21
+ end
16
22
 
17
23
  cmd :all do |cfg|
18
24
  cfg.cut_both
19
25
  end
20
26
 
21
27
  cmd :secret do |cfg|
22
- cfg.gsub!(/secret (\S+)$/, 'secret <secret removed>')
23
- cfg.gsub!(/enable secret (\S+)$/, 'enable secret <secret removed>')
24
- cfg.gsub!(/PRE-SHARE (\S+)$/, 'PRE-SHARE <secret removed>')
25
- cfg.gsub!(/ipsec (\S+)$/, 'ipsec <secret removed>')
26
- cfg.gsub!(/community (\S+)$/, 'community <secret removed>')
28
+ cfg.gsub!(/secret (\S+)\s?$/, 'secret <secret removed>')
29
+ cfg.gsub!(/enable secret (\S+)\s?$/, 'enable secret <secret removed>')
30
+ cfg.gsub!(/PRE-SHARE (\S+)\s?$/, 'PRE-SHARE <secret removed>')
31
+ cfg.gsub!(/ipsec (\S+)\s?$/, 'ipsec <secret removed>')
32
+ cfg.gsub!(/community (\S+)\s?$/, 'community <secret removed>')
27
33
  cfg.gsub!(/ sha (\S+)/, ' sha <secret removed>')
28
34
  cfg.gsub!(/ des (\S+)/, ' des <secret removed>')
29
35
  cfg.gsub!(/mobility-manager (\S+) user (\S+) (\S+)/, 'mobility-manager \1 user \2 <secret removed>')
30
- cfg.gsub!(/mgmt-user (\S+) (root|guest-provisioning|network-operations|read-only|location-api-mgmt) (\S+)$/, 'mgmt-user \1 \2 <secret removed>') # MAS & Wireless Controler
31
- cfg.gsub!(/mgmt-user (\S+) (\S+)( (read-only|guest-mgmt))?$/, 'mgmt-user \1 <secret removed> \3') # IAP
36
+ cfg.gsub!(/mgmt-user (\S+) (root|guest-provisioning|network-operations|read-only|location-api-mgmt) (\S+)\s?$/, 'mgmt-user \1 \2 <secret removed>') # MAS & Wireless Controler
37
+ cfg.gsub!(/mgmt-user (\S+) (\S+)( (read-only|guest-mgmt))?\s?$/, 'mgmt-user \1 <secret removed> \3') # IAP
32
38
  # MAS format: mgmt-user <username> <accesslevel> <password hash>
33
39
  # IAP format (root user): mgmt-user <username> <password hash>
34
40
  # IAP format: mgmt-user <username> <password hash> <access level>
35
- cfg.gsub!(/key (\S+)$/, 'key <secret removed>')
36
- cfg.gsub!(/wpa-passphrase (\S+)$/, 'wpa-passphrase <secret removed>')
37
- cfg.gsub!(/bkup-passwords (\S+)$/, 'bkup-passwords <secret removed>')
38
- cfg.gsub!(/user (\S+) (\S+) (\S+)$/, 'user \1 <secret removed> \3')
39
- cfg.gsub!(/virtual-controller-key (\S+)$/, 'virtual-controller-key <secret removed>')
41
+ cfg.gsub!(/key (\S+)\s?$/, 'key <secret removed>')
42
+ cfg.gsub!(/vrrp-passphrase (\S+)\s?$/, 'vrrp-passphrase <secret removed>')
43
+ cfg.gsub!(/wpa-passphrase (\S+)\s?$/, 'wpa-passphrase <secret removed>')
44
+ cfg.gsub!(/bkup-passwords (\S+)\s?$/, 'bkup-passwords <secret removed>')
45
+ cfg.gsub!(/ap-console-password (\S+)\s?$/, 'ap-console-password <secret removed>')
46
+ cfg.gsub!(/virtual-controller-key (\S+)\s?$/, 'virtual-controller-key <secret removed>')
40
47
  cfg
41
48
  end
42
49
 
43
50
  cmd 'show version' do |cfg|
44
- cfg = cfg.each_line.reject { |line| line.match(/(Switch|AP) uptime/i) || line.match(/Reboot Time and Cause/i) }
45
- rstrip_cfg comment cfg.join
51
+ cfg = cfg.reject_lines [
52
+ /(Switch|AP) uptime/i,
53
+ /Reboot Time and Cause/i
54
+ ]
55
+ rstrip_cfg comment cfg
46
56
  end
47
57
 
48
58
  cmd 'show inventory' do |cfg|
49
- cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/ # Don't show for unsupported devices (IAP and MAS)
59
+ # Don't show for unsupported devices (IAP and MAS)
60
+ cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
50
61
  rstrip_cfg clean cfg
51
62
  end
52
63
 
53
64
  cmd 'show slots' do |cfg|
54
- cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/ # Don't show for unsupported devices (IAP and MAS)
65
+ # Don't show for unsupported devices (IAP and MAS)
66
+ cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
55
67
  rstrip_cfg comment cfg
56
68
  end
57
69
 
58
70
  cmd 'show license' do |cfg|
59
- cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/ # Don't show for unsupported devices (IAP and MAS)
71
+ # Don't show for unsupported devices (IAP and MAS)
72
+ cfg = "" if cfg =~ /(Invalid input detected at '\^' marker|Parse error)/
60
73
  rstrip_cfg comment cfg
61
74
  end
62
75
 
63
76
  cmd 'show license passphrase' do |cfg|
64
- cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ # Don't show for unsupported devices (IAP and MAS)
77
+ # Don't show for unsupported devices (IAP and MAS)
78
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/
65
79
  rstrip_cfg comment cfg
66
80
  end
67
81
 
68
82
  cmd 'show running-config' do |cfg|
69
- out = []
70
- cfg.each_line do |line|
71
- next if line =~ /^controller config \d+$/
72
- next if line =~ /^Building Configuration/
73
-
74
- out << line.strip
75
- end
76
- out = out.join "\n"
77
- out << "\n"
83
+ cfg = cfg.reject_lines [
84
+ /^controller config \d+$/,
85
+ /^Building Configuration/
86
+ ]
87
+ rstrip_cfg cfg
78
88
  end
79
89
 
80
90
  cfg :telnet do
@@ -111,7 +121,7 @@ class AOSW < Oxidized::Model
111
121
  next if line =~ /Output \d Config/i
112
122
  next if line =~ /(Tachometers|Temperatures|Voltages)/
113
123
  next if line =~ /((Card|CPU) Temperature|Chassis Fan|VMON1[0-9])/
114
- next if line =~ /[0-9]+\s+(RPMS?|m?V|C)/i
124
+ next if line =~ /[0-9.]{1,6}\s+(RPMS?|m?V|C|W)/i
115
125
 
116
126
  out << line.strip
117
127
  end
@@ -1,10 +1,15 @@
1
1
  class Apc_aos < Oxidized::Model # rubocop:disable Naming/ClassAndModuleCamelCase
2
2
  using Refinements
3
3
 
4
+ comment '; '
5
+
4
6
  cmd 'config.ini' do |cfg|
5
- cfg.gsub! /^; Configuration file, generated on.*/, ''
7
+ logger.warn "Apc_aos is deprecated, use ApcAos instead."
8
+
9
+ cfg.gsub!(/^; Configuration file, generated on.*\n/, '')
10
+ cfg
6
11
  end
7
12
 
8
- cfg :ftp do
13
+ cfg :ftp, :scp do
9
14
  end
10
15
  end
@@ -0,0 +1,39 @@
1
+ class ApcAos < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Prompt can be short (apc>) or long (username@apc>)
5
+ prompt /^(:?\S+@)?apc>/
6
+ comment '; '
7
+
8
+ def clean(cfg)
9
+ cfg = cfg.cut_both(2, 1)
10
+ cfg.gsub("\r", "")
11
+ end
12
+
13
+ cmd 'about', input: :ssh do |cfg|
14
+ cfg = clean(cfg)
15
+ cfg = cfg.reject_lines [/^Management Uptime: /, /^Date: /, /^Time: /]
16
+ comment cfg
17
+ end
18
+
19
+ cmd 'upsabout', input: :ssh do |cfg|
20
+ cfg = clean(cfg)
21
+ comment cfg
22
+ end
23
+
24
+ cmd 'detstatus -ss', input: :ssh do |cfg|
25
+ cfg = clean(cfg)
26
+ comment cfg
27
+ end
28
+
29
+ cmd 'config.ini', input: %i[scp ftp] do |cfg|
30
+ cfg = cfg.reject_lines [/^; Configuration file, generated on /]
31
+ "; ========== config.ini ==========\n" + cfg
32
+ end
33
+
34
+ inputs [:ssh, %i[scp ftp]]
35
+
36
+ cfg :ssh do
37
+ pre_logout 'exit'
38
+ end
39
+ end
@@ -2,6 +2,10 @@
2
2
  # #show version
3
3
  # Switch ID Hardware Version Firmware Version
4
4
  # 0 SSE-G48-TG4 (P2-01) 1.0.16-9
5
+ # and
6
+ # # show version
7
+ # Switch ID Hardware Version Firmware Version
8
+ # 0 MBM-XEM-002 (B6-01) 2.1.3-25
5
9
 
6
10
  class AricentISS < Oxidized::Model
7
11
  using Refinements
@@ -13,6 +17,9 @@ class AricentISS < Oxidized::Model
13
17
  # 1.0.18-15 is known to include the corrected spelling
14
18
  post_login 'no cli pagination'
15
19
  post_login 'no cli pagignation'
20
+ # Starting firmware 2.0, pagination is done differently.
21
+ # This configuration is reset after the session ends.
22
+ post_login 'conf t; set cli pagination off; exit'
16
23
  pre_logout 'exit'
17
24
  end
18
25
 
@@ -30,7 +37,7 @@ class AricentISS < Oxidized::Model
30
37
  cmd 'show system information' do |cfg|
31
38
  cfg.sub! /^Device Up Time.*\n/, ''
32
39
  cfg.delete! "\r"
33
- comment(cfg).gsub(/ +$/, '')
40
+ comment(cfg).rstrip
34
41
  end
35
42
 
36
43
  cmd 'show running-config' do |cfg|
@@ -46,6 +53,6 @@ class AricentISS < Oxidized::Model
46
53
  end
47
54
 
48
55
  l
49
- end.join.gsub(/ +$/, '')
56
+ end.join.rstrip
50
57
  end
51
58
  end