oxidized 0.19.0 → 0.20.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/Dockerfile +17 -2
  4. data/Gemfile +0 -1
  5. data/Gemfile.lock +10 -9
  6. data/README.md +205 -10
  7. data/extra/auto-reload-config.runit +1 -1
  8. data/extra/oxidized.init +3 -3
  9. data/extra/update-ca-certificates.runit +7 -0
  10. data/lib/oxidized/config.rb +4 -2
  11. data/lib/oxidized/config/vars.rb +5 -1
  12. data/lib/oxidized/hook/exec.rb +1 -0
  13. data/lib/oxidized/hook/slackdiff.rb +34 -0
  14. data/lib/oxidized/input/ssh.rb +4 -1
  15. data/lib/oxidized/model/aireos.rb +1 -1
  16. data/lib/oxidized/model/airos.rb +9 -4
  17. data/lib/oxidized/model/alvarion.rb +3 -1
  18. data/lib/oxidized/model/aosw.rb +22 -6
  19. data/lib/oxidized/model/asa.rb +3 -2
  20. data/lib/oxidized/model/cisconga.rb +19 -0
  21. data/lib/oxidized/model/comware.rb +6 -0
  22. data/lib/oxidized/model/cumulus.rb +15 -3
  23. data/lib/oxidized/model/fabricos.rb +2 -1
  24. data/lib/oxidized/model/fiberdriver.rb +4 -0
  25. data/lib/oxidized/model/firewareos.rb +7 -1
  26. data/lib/oxidized/model/fortios.rb +15 -4
  27. data/lib/oxidized/model/ios.rb +83 -8
  28. data/lib/oxidized/model/ironware.rb +5 -6
  29. data/lib/oxidized/model/junos.rb +3 -0
  30. data/lib/oxidized/model/mlnxos.rb +5 -1
  31. data/lib/oxidized/model/netgear.rb +32 -0
  32. data/lib/oxidized/model/nxos.rb +14 -1
  33. data/lib/oxidized/model/oneos.rb +58 -0
  34. data/lib/oxidized/model/opengear.rb +2 -0
  35. data/lib/oxidized/model/pfsense.rb +3 -2
  36. data/lib/oxidized/model/powerconnect.rb +1 -0
  37. data/lib/oxidized/model/procurve.rb +8 -3
  38. data/lib/oxidized/model/quantaos.rb +1 -1
  39. data/lib/oxidized/model/routeros.rb +8 -0
  40. data/lib/oxidized/model/saos.rb +3 -1
  41. data/lib/oxidized/model/siklu.rb +19 -0
  42. data/lib/oxidized/model/timos.rb +16 -0
  43. data/lib/oxidized/model/tplink.rb +65 -0
  44. data/lib/oxidized/model/voltaire.rb +56 -0
  45. data/lib/oxidized/model/voss.rb +33 -0
  46. data/lib/oxidized/model/zhoneolt.rb +52 -0
  47. data/lib/oxidized/node.rb +39 -10
  48. data/lib/oxidized/nodes.rb +2 -1
  49. data/lib/oxidized/output/gitcrypt.rb +244 -0
  50. data/lib/oxidized/source/csv.rb +10 -1
  51. data/lib/oxidized/source/http.rb +24 -7
  52. data/lib/oxidized/version.rb +1 -1
  53. data/lib/oxidized/worker.rb +3 -2
  54. data/oxidized.gemspec +2 -1
  55. metadata +29 -4
@@ -2,7 +2,7 @@
2
2
 
3
3
  if [ -z "$CONFIG_RELOAD_INTERVAL" ]; then
4
4
  # Just stop and do nothing
5
- read
5
+ sleep infinity
6
6
  fi
7
7
 
8
8
  while true; do
@@ -14,12 +14,12 @@
14
14
 
15
15
  set -e
16
16
 
17
- PATH=/sbin:/bin:/usr/sbin:/usr/bin
18
- DAEMON=/home/sts/oxidized/bin/oxidized
17
+ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
18
+ DAEMON=$(which oxidized)
19
19
  NAME="oxidized"
20
20
  DESC="Oxidized - Network Device Configuration Backup Tool"
21
21
  ARGS=""
22
- USER="sts"
22
+ USER="oxidized"
23
23
 
24
24
  test -x $DAEMON || exit 0
25
25
 
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ if [ "$UPDATE_CA_CERTIFICATES" == "true" ]; then
4
+ update-ca-certificates
5
+ fi
6
+
7
+ sleep infinity
@@ -28,8 +28,10 @@ module Oxidized
28
28
  asetus.default.retries = 3
29
29
  asetus.default.prompt = /^([\w.@-]+[#>]\s?)$/
30
30
  asetus.default.rest = '127.0.0.1:8888' # or false to disable
31
- asetus.default.vars = {} # could be 'enable'=>'enablePW'
32
- asetus.default.groups = {} # group level configuration
31
+ asetus.default.next_adds_job = false # if true, /next adds job, so device is fetched immmeiately
32
+ asetus.default.vars = {} # could be 'enable'=>'enablePW'
33
+ asetus.default.groups = {} # group level configuration
34
+ asetus.default.models = {} # model level configuration
33
35
  asetus.default.pid = File.join(Oxidized::Config::Root, 'pid')
34
36
 
35
37
  asetus.default.input.default = 'ssh, telnet'
@@ -8,8 +8,12 @@ module Oxidized::Config::Vars
8
8
  r ||= Oxidized.config.groups[@node.group].vars[name.to_s]
9
9
  end
10
10
  end
11
+ if Oxidized.config.models.has_key?(@node.model.class.name.to_s.downcase)
12
+ if Oxidized.config.models[@node.model.class.name.to_s.downcase].vars.has_key?(name.to_s)
13
+ r ||= Oxidized.config.models[@node.model.class.name.to_s.downcase].vars[name.to_s]
14
+ end
15
+ end
11
16
  r ||= Oxidized.config.vars[name.to_s] if Oxidized.config.vars.has_key?(name.to_s)
12
17
  r
13
18
  end
14
19
  end
15
-
@@ -67,6 +67,7 @@ class Exec < Oxidized::Hook
67
67
  if ctx.node
68
68
  env.merge!(
69
69
  "OX_NODE_NAME" => ctx.node.name.to_s,
70
+ "OX_NODE_IP" => ctx.node.ip.to_s,
70
71
  "OX_NODE_FROM" => ctx.node.from.to_s,
71
72
  "OX_NODE_MSG" => ctx.node.msg.to_s,
72
73
  "OX_NODE_GROUP" => ctx.node.group.to_s,
@@ -0,0 +1,34 @@
1
+ require 'slack'
2
+
3
+ class SlackDiff < Oxidized::Hook
4
+ def validate_cfg!
5
+ raise KeyError, 'hook.token is required' unless cfg.has_key?('token')
6
+ raise KeyError, 'hook.channel is required' unless cfg.has_key?('channel')
7
+ end
8
+
9
+ def run_hook(ctx)
10
+ if ctx.node
11
+ if ctx.event.to_s == "post_store"
12
+ log "Connecting to slack"
13
+ Slack.configure do |config|
14
+ config.token = cfg.token
15
+ config.proxy = cfg.proxy if cfg.has_key?('proxy')
16
+ end
17
+ client = Slack::Client.new
18
+ client.auth_test
19
+ log "Connected"
20
+ gitoutput = ctx.node.output.new
21
+ diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil
22
+ title = "#{ctx.node.name.to_s} #{ctx.node.group.to_s} #{ctx.node.model.class.name.to_s.downcase}"
23
+ log "Posting diff as snippet to #{cfg.channel}"
24
+ client.files_upload(channels: cfg.channel, as_user: true,
25
+ content: diff[:patch].lines.to_a[4..-1].join,
26
+ filetype: "diff",
27
+ title: title,
28
+ filename: "change"
29
+ )
30
+ log "Finished"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -25,7 +25,10 @@ module Oxidized
25
25
  @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug?
26
26
  port = vars(:ssh_port) || 22
27
27
  if proxy_host = vars(:ssh_proxy)
28
- proxy = Net::SSH::Proxy::Command.new("ssh #{proxy_host} -W %h:%p")
28
+ proxy_command = "ssh "
29
+ proxy_command += "-o StrictHostKeyChecking=no " unless secure
30
+ proxy_command += "#{proxy_host} -W %h:%p"
31
+ proxy = Net::SSH::Proxy::Command.new(proxy_command)
29
32
  end
30
33
  ssh_opts = {
31
34
  :port => port.to_i,
@@ -44,7 +44,7 @@ class Aireos < Oxidized::Model
44
44
  out = []
45
45
  cfg.each_line do |line|
46
46
  next if line.match /^\s*$/
47
- next if line.match /rogue adhoc alert [\da-f]{2}:/
47
+ next if line.match /rogue (adhoc|client) (alert|Unknown) [\da-f]{2}:/
48
48
  line = line[1..-1] if line[0] == "\r"
49
49
  out << line.strip
50
50
  end
@@ -1,14 +1,19 @@
1
1
  class Airos < Oxidized::Model
2
2
  # Ubiquiti AirOS circa 5.x
3
-
3
+
4
4
  prompt /^[^#]+# /
5
-
5
+ comment '# '
6
+
6
7
  cmd 'cat /etc/board.info' do |cfg|
7
8
  cfg.split("\n").map { |line| "# #{line}" }.join("\n") + "\n"
8
9
  end
9
-
10
+
11
+ cmd 'cat /etc/version' do |cfg|
12
+ comment "airos version: #{cfg}"
13
+ end
14
+
10
15
  cmd 'sort /tmp/system.cfg'
11
-
16
+
12
17
  cmd :secret do |cfg|
13
18
  cfg.gsub! /^(users\.\d+\.password|snmp\.community)=.+/, "# \\1=<hidden>"
14
19
  cfg
@@ -8,6 +8,8 @@ class Alvarion < Oxidized::Model
8
8
  end
9
9
 
10
10
 
11
- cfg :tftp {}
11
+ cfg :tftp do
12
+
13
+ end
12
14
 
13
15
  end
@@ -1,45 +1,61 @@
1
1
  class AOSW < Oxidized::Model
2
2
 
3
- # AOSW Aruba Wireless
3
+ # AOSW Aruba Wireless, IAP, Instant Controller and Mobility Access Switches
4
4
  # Used in Alcatel OAW-4750 WLAN controller
5
5
  # Also Dell controllers
6
+
7
+ # HPE Aruba Switches should use a different model as the software is based on the HP Procurve line.
8
+
9
+ # Support for IAP & Instant Controller tested with 115, 205, 215 & 325 running 6.4.4.8-4.2.4.5_57965
10
+ # Support for Mobility Access Switches tested with S2500-48P & S2500-24P running 7.4.1.4_54199 and S2500-24P running 7.4.1.7_57823
11
+ # All IAPs connected to a Instant Controller will have the same config output. Only the controller needs to be monitored.
6
12
 
7
13
  comment '# '
8
- prompt /^\([^)]+\) [#>]/
14
+ prompt /^\(?.+\)?\s?[#>]/
9
15
 
10
16
  cmd :all do |cfg|
11
17
  cfg.each_line.to_a[1..-2].join
12
18
  end
13
19
 
14
20
  cmd :secret do |cfg|
21
+ cfg.gsub!(/secret (\S+)$/, 'secret <secret removed>')
22
+ cfg.gsub!(/enable secret (\S+)$/, 'enable secret <secret removed>')
15
23
  cfg.gsub!(/PRE-SHARE (\S+)$/, 'PRE-SHARE <secret removed>')
16
24
  cfg.gsub!(/ipsec (\S+)$/, 'ipsec <secret removed>')
17
25
  cfg.gsub!(/community (\S+)$/, 'community <secret removed>')
18
26
  cfg.gsub!(/ sha (\S+)/, ' sha <secret removed>')
19
27
  cfg.gsub!(/ des (\S+)/, ' des <secret removed>')
20
28
  cfg.gsub!(/mobility-manager (\S+) user (\S+) (\S+)/, 'mobility-manager \1 user \2 <secret removed>')
21
- cfg.gsub!(/mgmt-user (\S+) (\S+) (\S+)$/, 'mgmt-user \1 \2 <secret removed>')
29
+ 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
30
+ cfg.gsub!(/mgmt-user (\S+) (\S+)( (read\-only|guest\-mgmt))?$/, 'mgmt-user \1 <secret removed> \3') #IAP
31
+ #MAS format: mgmt-user <username> <accesslevel> <password hash>
32
+ #IAP format (root user): mgmt-user <username> <password hash>
33
+ #IAP format: mgmt-user <username> <password hash> <access level>
22
34
  cfg.gsub!(/key (\S+)$/, 'key <secret removed>')
23
- cfg.gsub!(/secret (\S+)$/, 'secret <secret removed>')
24
35
  cfg.gsub!(/wpa-passphrase (\S+)$/, 'wpa-passphrase <secret removed>')
25
36
  cfg.gsub!(/bkup-passwords (\S+)$/, 'bkup-passwords <secret removed>')
37
+ cfg.gsub!(/user (\S+) (\S+) (\S+)$/, 'user \1 <secret removed> \3')
38
+ cfg.gsub!(/virtual-controller-key (\S+)$/, 'virtual-controller-key <secret removed>')
26
39
  cfg
27
40
  end
28
41
 
29
42
  cmd 'show version' do |cfg|
30
- cfg = cfg.each_line.select { |line| not line.match /Switch uptime/i }
43
+ cfg = cfg.each_line.select { |line| not line.match /(Switch|AP) uptime/i }
31
44
  rstrip_cfg comment cfg.join
32
45
  end
33
46
 
34
47
  cmd 'show inventory' do |cfg|
48
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
35
49
  rstrip_cfg clean cfg
36
50
  end
37
51
 
38
52
  cmd 'show slots' do |cfg|
53
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
39
54
  rstrip_cfg comment cfg
40
55
  end
41
56
 
42
57
  cmd 'show license' do |cfg|
58
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
43
59
  rstrip_cfg comment cfg
44
60
  end
45
61
 
@@ -90,7 +106,7 @@ class AOSW < Oxidized::Model
90
106
  next if line.match /Output \d Config/i
91
107
  next if line.match /(Tachometers|Temperatures|Voltages)/
92
108
  next if line.match /((Card|CPU) Temperature|Chassis Fan|VMON1[0-9])/
93
- next if line.match /[0-9]+ (RPMS?|m?V|C)/i
109
+ next if line.match /[0-9]+\s+(RPMS?|m?V|C)/i
94
110
  out << line.strip
95
111
  end
96
112
  out = comment out.join "\n"
@@ -13,9 +13,10 @@ class ASA < Oxidized::Model
13
13
  cmd :secret do |cfg|
14
14
  cfg.gsub! /enable password (\S+) (.*)/, 'enable password <secret hidden> \2'
15
15
  cfg.gsub! /username (\S+) password (\S+) (.*)/, 'username \1 password <secret hidden> \3'
16
- cfg.gsub! /ikev2 pre-shared-key (\S+)/, 'ikev2 pre-shared-key <secret hidden>'
17
- cfg.gsub! /ikev2 (remote|local)-authentication pre-shared-key (\S+)/, 'ikev2 \1-authentication pre-shared-key <secret hidden>'
16
+ cfg.gsub! /(ikev[12] ((remote|local)-authentication )?pre-shared-key) (\S+)/, '\1 <secret hidden>'
18
17
  cfg.gsub! /^(aaa-server TACACS\+? \(\S+\) host.*\n\skey) \S+$/mi, '\1 <secret hidden>'
18
+ cfg.gsub! /ldap-login-password (\S+)/, 'ldap-login-password <secret hidden>'
19
+ cfg.gsub! /^snmp-server host (.*) community (\S+)/, 'snmp-server host \1 community <secret hidden>'
19
20
  cfg
20
21
  end
21
22
 
@@ -0,0 +1,19 @@
1
+ class CiscoNGA < Oxidized::Model
2
+
3
+ comment '# '
4
+ prompt /([\w.@-]+[#>]\s?)$/
5
+
6
+ cmd 'show version' do |cfg|
7
+ comment cfg
8
+ end
9
+
10
+ cmd 'show configuration' do |cfg|
11
+ cfg
12
+ end
13
+
14
+ cfg :ssh do
15
+ post_login 'terminal length 0'
16
+ pre_logout 'exit'
17
+ end
18
+
19
+ end
@@ -18,6 +18,12 @@ class Comware < Oxidized::Model
18
18
  cfg.each_line.to_a[1..-2].join
19
19
  end
20
20
 
21
+ cmd :secret do |cfg|
22
+ cfg.gsub! /^( snmp-agent community).*/, '\\1 <configuration removed>'
23
+ cfg.gsub! /^( password hash).*/, '\\1 <configuration removed>'
24
+ cfg
25
+ end
26
+
21
27
  cfg :telnet do
22
28
  username /^Username:$/
23
29
  password /^Password:$/
@@ -32,7 +32,10 @@ class Cumulus < Oxidized::Model
32
32
 
33
33
  cfg += add_comment 'IP Routes'
34
34
  cfg += cmd 'netstat -rn'
35
-
35
+
36
+ cfg += add_comment 'SNMP settings'
37
+ cfg += cmd 'cat /etc/snmp/snmpd.conf'
38
+
36
39
  cfg += add_comment 'QUAGGA DAEMONS'
37
40
  cfg += cmd 'cat /etc/quagga/daemons'
38
41
 
@@ -48,21 +51,30 @@ class Cumulus < Oxidized::Model
48
51
  cfg += add_comment 'QUAGGA OSPF6'
49
52
  cfg += cmd 'cat /etc/quagga/ospf6d.conf'
50
53
 
54
+ cfg += add_comment 'QUAGGA CONF'
55
+ cfg += cmd 'cat /etc/quagga/Quagga.conf'
56
+
51
57
  cfg += add_comment 'MOTD'
52
58
  cfg += cmd 'cat /etc/motd'
53
59
 
54
60
  cfg += add_comment 'PASSWD'
55
61
  cfg += cmd 'cat /etc/passwd'
56
62
 
57
- cfg += add_comment ' SWITCHD'
63
+ cfg += add_comment 'SWITCHD'
58
64
  cfg += cmd 'cat /etc/cumulus/switchd.conf'
59
65
 
66
+ cfg += add_comment 'PORTS'
67
+ cfg += cmd 'cat /etc/cumulus/ports.conf'
68
+
69
+ cfg += add_comment 'TRAFFIC'
70
+ cfg += cmd 'cat /etc/cumulus/datapath/traffic.conf'
71
+
60
72
  cfg += add_comment 'ACL'
61
73
  cfg += cmd 'iptables -L -n'
62
74
 
63
75
  cfg += add_comment 'VERSION'
64
76
  cfg += cmd 'cat /etc/cumulus/etc.replace/os-release'
65
-
77
+
66
78
  cfg += add_comment 'License'
67
79
  cfg += cmd 'cl-license'
68
80
 
@@ -7,10 +7,11 @@ class FabricOS < Oxidized::Model
7
7
  comment '# '
8
8
 
9
9
  cmd 'chassisShow' do |cfg|
10
- comment cfg
10
+ comment cfg.each_line.reject { |line| line.match /Time Awake:/ or line.match /Power Usage \(Watts\):/ or line.match /Time Alive:/ or line.match /Update:/ }.join
11
11
  end
12
12
 
13
13
  cmd 'configShow -all' do |cfg|
14
+ cfg = cfg.each_line.reject { |line| line.match /date = /}.join
14
15
  cfg
15
16
  end
16
17
 
@@ -11,6 +11,10 @@ class FiberDriver < Oxidized::Model
11
11
 
12
12
  cmd "show running-config" do |cfg|
13
13
  cfg.each_line.to_a[3..-1].join
14
+ cfg.gsub! /^Building configuration.*$/, ''
15
+ cfg.gsub! /^Current configuration:.*$$/, ''
16
+ cfg.gsub! /^! Configuration saved on .*$/, ''
17
+ cfg
14
18
  end
15
19
 
16
20
  cfg :ssh do
@@ -1,12 +1,18 @@
1
1
  class FirewareOS < Oxidized::Model
2
2
 
3
- prompt /^\[?\w*\]?\w*<?\w*>?#\s*$/
3
+ prompt /^([\w.@-]+[#>]\s?)$/
4
4
  comment '-- '
5
5
 
6
6
  cmd :all do |cfg|
7
7
  cfg.each_line.to_a[1..-2].join
8
8
  end
9
9
 
10
+ # Handle Logon Disclaimer added in XTM 11.9.3
11
+ expect /^I have read and accept the Logon Disclaimer message. \(yes or no\)\? $/ do |data, re|
12
+ send "yes\n"
13
+ data.sub re, ''
14
+ end
15
+
10
16
  cmd 'show sysinfo' do |cfg|
11
17
  # avoid commits due to uptime
12
18
  cfg = cfg.each_line.select { |line| not line.match /(.*time.*)|(.*memory.*)|(.*cpu.*)/ }
@@ -14,6 +14,12 @@ class FortiOS < Oxidized::Model
14
14
  new_cfg << cfg.each_line.to_a[1..-2].map { |line| line.gsub(/(conf_file_ver=)(.*)/, '\1<stripped>\3') }.join
15
15
  end
16
16
 
17
+ cmd :secret do |cfg|
18
+ cfg.gsub! /(set (?:passwd|password|psksecret|secret|key ENC)).*/, '\\1 <configuration removed>'
19
+ cfg.gsub! /(set private-key).*-+END ENCRYPTED PRIVATE KEY-*"$/m , '\\1 <configuration removed>'
20
+ cfg
21
+ end
22
+
17
23
  cmd 'get system status' do |cfg|
18
24
  @vdom_enabled = cfg.include? 'Virtual domain configuration: enable'
19
25
  cfg.gsub!(/(System time: )(.*)/, '\1<stripped>\3')
@@ -25,14 +31,18 @@ class FortiOS < Oxidized::Model
25
31
  cfg << cmd('config global') if @vdom_enabled
26
32
 
27
33
  cfg << cmd('get hardware status') do |cfg|
28
- comment cfg
34
+ comment cfg
29
35
  end
30
36
 
31
- cfg << cmd('diagnose autoupdate version') do |cfg|
32
- comment cfg
37
+ #default behaviour: include autoupdate output (backwards compatibility)
38
+ #do not include if variable "show_autoupdate" is set to false
39
+ if defined?(vars(:fortios_autoupdate)).nil? || vars(:fortios_autoupdate)
40
+ cfg << cmd('diagnose autoupdate version') do |cfg|
41
+ comment cfg.each_line.reject { |line| line.match /Last Update|Result/ }.join
42
+ end
33
43
  end
34
44
 
35
- cfg << cmd('end') if @vdom_enabled
45
+ cfg << cmd('end') if @vdom_enabled
36
46
 
37
47
  cfg << cmd('show')
38
48
  cfg.join "\n"
@@ -48,3 +58,4 @@ class FortiOS < Oxidized::Model
48
58
  end
49
59
 
50
60
  end
61
+
@@ -19,21 +19,96 @@ class IOS < Oxidized::Model
19
19
  cmd :all do |cfg|
20
20
  #cfg.gsub! /\cH+\s{8}/, '' # example how to handle pager
21
21
  #cfg.gsub! /\cH+/, '' # example how to handle pager
22
+ # get rid of errors for commands that don't work on some devices
23
+ cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
22
24
  cfg.each_line.to_a[1..-2].join
23
25
  end
24
26
 
25
27
  cmd :secret do |cfg|
26
28
  cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
27
- cfg.gsub! /username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
28
- cfg.gsub! /^username \S+ password \d \S+/, '<secret hidden>'
29
- cfg.gsub! /^enable password \d \S+/, '<secret hidden>'
30
- cfg.gsub! /wpa-psk ascii \d \S+/, '<secret hidden>'
31
- cfg.gsub! /^tacacs-server key \d \S+/, '<secret hidden>'
29
+ cfg.gsub! /^(username \S+ privilege \d+) (\S+).*/, '\\1 <secret hidden>'
30
+ cfg.gsub! /^(username \S+ password \d) (\S+)/, '\\1 <secret hidden>'
31
+ cfg.gsub! /^(username \S+ secret \d) (\S+)/, '\\1 <secret hidden>'
32
+ cfg.gsub! /^(enable (password|secret) \d) (\S+)/, '\\1 <secret hidden>'
33
+ cfg.gsub! /^(\s+(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
34
+ cfg.gsub! /^(.*wpa-psk ascii \d) (\S+)/, '\\1 <secret hidden>'
35
+ cfg.gsub! /^(.*key 7) (\d.+)/, '\\1 <secret hidden>'
36
+ cfg.gsub! /^(tacacs-server key \d) (\S+)/, '\\1 <secret hidden>'
37
+ cfg.gsub! /^(crypto isakmp key) (\S+) (.*)/, '\\1 <secret hidden> \\3'
32
38
  cfg
33
39
  end
34
40
 
35
41
  cmd 'show version' do |cfg|
36
- comment cfg.lines.first
42
+ comments = []
43
+ comments << cfg.lines.first
44
+ lines = cfg.lines
45
+ lines.each_with_index do |line,i|
46
+ slave = ''
47
+ slaveslot = ''
48
+
49
+ if line.match /^Slave in slot (\d+) is running/
50
+ slave = " Slave:";
51
+ slaveslot = ", slot #{$1}";
52
+ end
53
+
54
+ if line.match /^Compiled (.*)$/
55
+ comments << "Image:#{slave} Compiled: #{$1}"
56
+ end
57
+
58
+ if line.match /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
59
+ comments << "Image:#{slave} Software: #{$1}, #{$2}"
60
+ end
61
+
62
+ if line.match /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
63
+ comments << "ROM Bootstrap: #{$3}"
64
+ end
65
+
66
+ if line.match /^BOOTFLASH: .*(Version.*)$/
67
+ comments << "BOOTFLASH: #{$1}"
68
+ end
69
+
70
+ if line.match /^(\d+[kK]) bytes of (non-volatile|NVRAM)/
71
+ comments << "Memory: nvram #{$1}"
72
+ end
73
+
74
+ if line.match /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
75
+ comments << "Memory: flash #{$1}"
76
+ end
77
+
78
+ if line.match (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i)
79
+ comments << "Memory: pcmcia #{$2} #{$3}#{$4} #{$1}";
80
+ end
81
+
82
+ if line.match /(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
83
+ sproc = $1
84
+ cpu = $2
85
+ mem = $3
86
+ cpuxtra = ''
87
+ comments << "Chassis type:#{slave} #{sproc}";
88
+ comments << "Memory:#{slave} main #{mem}";
89
+ # check the next two lines for more CPU info
90
+ if cfg.lines[i+1].match /processor board id (\S+)/i
91
+ comments << "Processor ID: #{$1}";
92
+ end
93
+ if cfg.lines[i+2].match /(cpu at |processor: |#{cpu} processor,)/i
94
+ # change implementation to impl and prepend comma
95
+ cpuxtra = cfg.lines[i+2].gsub(/implementation/,'impl').gsub(/^/,', ').chomp;
96
+ end
97
+ comments << "CPU:#{slave} #{cpu}#{cpuxtra}#{slaveslot}";
98
+ end
99
+
100
+ if line.match /^System image file is "([^\"]*)"$/
101
+ comments << "Image: #{$1}"
102
+ end
103
+ end
104
+ comments << "\n"
105
+ comment comments.join "\n"
106
+ end
107
+
108
+ cmd 'show vtp status' do |cfg|
109
+ cfg.gsub! /^$\n/, ''
110
+ cfg.gsub! /^/, 'VTP: ' if (!cfg.empty?)
111
+ comment "#{cfg}\n"
37
112
  end
38
113
 
39
114
  cmd 'show inventory' do |cfg|
@@ -56,8 +131,6 @@ class IOS < Oxidized::Model
56
131
  end
57
132
 
58
133
  cfg :telnet, :ssh do
59
- post_login 'terminal length 0'
60
- post_login 'terminal width 0'
61
134
  # preferred way to handle additional passwords
62
135
  if vars :enable
63
136
  post_login do
@@ -65,6 +138,8 @@ class IOS < Oxidized::Model
65
138
  cmd vars(:enable)
66
139
  end
67
140
  end
141
+ post_login 'terminal length 0'
142
+ post_login 'terminal width 0'
68
143
  pre_logout 'exit'
69
144
  end
70
145