oxidized 0.23.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82b0526060e394b00d65a0910bc943c6ab0e7d297e10af5bba036b98d69a592c
4
- data.tar.gz: d3ff1a990a0cd666313e3027a59148e7e1e3dc5cef403205a136a74510655718
3
+ metadata.gz: c00743626e287a15848821ba168ad2cbb824e5df3a325cbaa890b955ea3dafa1
4
+ data.tar.gz: e83a4ba0e11cf259ec0c81850812f736bbe519428d36297c6b8741e0a68e9036
5
5
  SHA512:
6
- metadata.gz: 9ba909c41f9e35f02ba8c8429aaad7997c1837871d7d7c16097330c8f96a2d642106597a4289bdefb839540f17d080a7e3bfbd669c289f0bce693c24e4a58219
7
- data.tar.gz: ffc0b7476888718ab44ee1372e247107c33092396478d0fcb91a7af7e3361f3de45f072184abd70f25f42d3a4ed658bf1d666c43d57c0a77dcf8e669ec7ab335
6
+ metadata.gz: f38ea9bb12acf38a4a4f5477c87c478f9f761497a9d138e776793cca9d64b25010ae319d3c580fcafea772c1f5dc14a2d34b4cbb5b2ecc8d7001b45df0d24089
7
+ data.tar.gz: 22393220362199339fbad22f7db8b2c4981e229a48a8d8762e7fe6e56bcb33e722664747b4600bc3c9185b1f367b40db803800efdd513c5f167a2e3c2afd92d3
@@ -30,6 +30,9 @@ Style/FormatStringToken:
30
30
  Style/RescueModifier:
31
31
  Enabled: false
32
32
 
33
+ Style/MultilineBlockChain:
34
+ Enabled: false
35
+
33
36
  # Do not attempt to police vendored code, and exclude special cases
34
37
  AllCops:
35
38
  Exclude:
@@ -1,9 +1,22 @@
1
1
  # Changelog
2
2
 
3
- ## Master
3
+ ## 024.0
4
4
 
5
- * BUGFIX: model edgecos does not trigger falsepositives due to uptime and memory utilization
5
+ * FEATURE: add frr support to cumulus model (@User4574 / @bobthebutcher)
6
+ * FEATURE: honour MAX_STAT in mtime, to store last N mtime
7
+ * FEATURE: configurable stats history size
8
+ * FEATURE: model callback enhancements for customizing existing models (@ytti)
9
+ * BUGFIX: models ciscosmb, dlink
10
+
11
+
12
+ ## 0.23.0
13
+
14
+ * FEATURE: support arbitrary user/password/prompt detection in telnet, same behaviour as ssh
15
+ * FEATURE: manager refactor, support local loading of input, output, source, not just model and hook
16
+ * FEATURE: store modification time in node stats
17
+ * BUGFIX: model edgecos does not trigger false positives due to uptime and memory utilization (@sq9mev)
6
18
  * BUGFIX: Use SECRET-DATA hints for hiding secrets in JunOS (@Zmegolaz)
19
+ * BUGFIX: comware (@adamboutcher)
7
20
 
8
21
  ## 0.22.0
9
22
 
@@ -20,6 +33,7 @@
20
33
  * FEATURE: cambium model
21
34
  * FEATURE: ssh key passphrase (@wk)
22
35
  * FEATURE: cisco spark hook (@rgnv)
36
+ * FEATURE: added support for setting ssh auth methods (@laf)
23
37
  * BUGFIX: models procurve, br6910, vyos, fortios, edgeos, vyatta, junos, powerconnect, supermicro, fortios, firewareos, aricentiss, dnos, nxos, hpbladesystem, netgear, xos, boss, opengear, pfsense, asyncos
24
38
 
25
39
  ## 0.21.0
data/README.md CHANGED
@@ -79,30 +79,32 @@ Check out the [Oxidized TREX 2014 presentation](http://youtu.be/kBQ_CTUuqeU#t=3h
79
79
  Install all required packages and gems.
80
80
 
81
81
  ```shell
82
- apt-get install ruby ruby-dev libsqlite3-dev libssl-dev pkg-config cmake libssh2-1-dev libicu-dev
82
+ apt-get install ruby ruby-dev libsqlite3-dev libssl-dev pkg-config cmake libssh2-1-dev libicu-dev zlib1g-dev
83
83
  gem install oxidized
84
84
  gem install oxidized-script oxidized-web # if you don't install oxidized-web, make sure you remove "rest" from your config
85
85
  ```
86
86
 
87
87
  ### CentOS, Oracle Linux, Red Hat Linux
88
88
 
89
- On CentOS 6 / RHEL 6, install Ruby 2.0 or greater (for Ruby 2.1.2 installation instructions see [Installing Ruby 2.1.2 using RVM](#installing-ruby-212-using-rvm)), then install Oxidized dependencies
89
+ On CentOS 6 / RHEL 6, begin by installing Ruby 2.0 or greater. For Ruby 2.1.2 installation instructions see [Installing Ruby 2.1.2 using RVM](#installing-ruby-212-using-rvm).
90
+
91
+ If you've installed Ruby 2.0 or greater via a 3rd party package rather than the RVM instructions, additional dependencies will be required:
90
92
 
91
93
  ```shell
92
- yum install cmake sqlite-devel openssl-devel libssh2-devel libicu-devel
94
+ yum install make cmake which sqlite-devel openssl-devel libssh2-devel ruby gcc ruby-devel libicu-devel gcc-c++
93
95
  ```
94
96
 
95
97
  RHEL 7 / CentOS 7 will work out of the box with the following package list:
96
98
 
97
99
  ```shell
98
- yum install cmake sqlite-devel openssl-devel libssh2-devel ruby gcc ruby-devel libicu-devel gcc-c++
100
+ yum install make cmake which sqlite-devel openssl-devel libssh2-devel ruby gcc ruby-devel libicu-devel gcc-c++
99
101
  ```
100
102
 
101
103
  Now let's install oxidized via Rubygems:
102
104
 
103
105
  ```shell
104
106
  gem install oxidized
105
- gem install oxidized-script oxidized-web
107
+ gem install oxidized-script oxidized-web # if you don't install oxidized-web, make sure you remove "rest" from your config
106
108
  ```
107
109
 
108
110
  ### FreeBSD
@@ -218,7 +220,7 @@ Install Ruby 2.1.2 build dependencies
218
220
  ```shell
219
221
  yum install curl gcc-c++ patch readline readline-devel zlib zlib-devel
220
222
  yum install libyaml-devel libffi-devel openssl-devel make cmake
221
- yum install bzip2 autoconf automake libtool bison iconv-devel libssh2-devel
223
+ yum install bzip2 autoconf automake libtool bison iconv-devel libssh2-devel libicu-devel
222
224
  ```
223
225
 
224
226
  Install RVM
@@ -66,9 +66,9 @@ vars:
66
66
 
67
67
  By default, Oxidized registers the following auth methods: `none`, `publickey` and `password`. However you can configure this globally, by groups, models or nodes.
68
68
 
69
- ```
69
+ ```yaml
70
70
  vars:
71
- auth_methods: none, publickey, password, keyboard-interactive
71
+ auth_methods: [ "none", "publickey", "password", "keyboard-interactive" ]
72
72
  ```
73
73
 
74
74
  ## SSH Proxy Command
@@ -76,3 +76,27 @@ end
76
76
  ```
77
77
 
78
78
  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.
79
+
80
+ ## Monkey-patching blocks in existing models
81
+
82
+ 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.
83
+
84
+ When defining a monkey-patched block, two boolean arguments can be passed as part of the block definition:
85
+
86
+ * `clear: true`, which resets the existing block, allowing the user to completely override its contents.
87
+ * `prepend: true`, which ensures that the contents of the block are prepended, rather than appended (the default) to an existing block.
88
+
89
+ This functionality is supported for `cfg`, `cmd`, `pre`, `post`, and `expect` blocks.
90
+
91
+ Examples:
92
+
93
+ ```ruby
94
+ cmd :secret clear: true do
95
+ ... "(new code for secret removal which replaces the existing :secret definition in the model)" ...
96
+ end
97
+ ```
98
+
99
+ ```ruby
100
+ cmd :ssh do prepend: true do
101
+ ... "(code that should run first, before any code in the existing :ssh definition in the model)" ...
102
+ end
@@ -130,11 +130,11 @@ Fields sent in the message:
130
130
  * `model`: Model name (e.g. `eos`)
131
131
  * `node`: Device hostname
132
132
 
133
-
134
133
  The AWS SNS hook requires the following configuration keys:
135
134
 
136
135
  * `region`: AWS Region name
137
136
  * `topic_arn`: ASN Topic reference
137
+
138
138
  ### awssns hook configuration example
139
139
 
140
140
  ```yaml
@@ -0,0 +1,40 @@
1
+ # Cumulus Linux
2
+
3
+ ## Routing Daemon
4
+
5
+ With the release of Cumulus Linux 3.4.0 the platform moved the routing daemon to a fork of `Quagga` named `FRRouting`. See the below link for the release notes.
6
+
7
+ [https://support.cumulusnetworks.com/hc/en-us/articles/115011217808-Cumulus-Linux-3-4-0-Release-Notes](https://support.cumulusnetworks.com/hc/en-us/articles/115011217808-Cumulus-Linux-3-4-0-Release-Notes)
8
+
9
+ A variable has been added to enable users running Cumulus Linux > 3.4.0 to target the new `frr` routing daemon.
10
+
11
+ ### Example usage
12
+
13
+ ```yaml
14
+ vars:
15
+ cumulus_routing_daemon: frr
16
+ ```
17
+
18
+ Alternatively map a column for the `cumulus_routing_daemon` variable.
19
+
20
+ ```yaml
21
+ source:
22
+ csv:
23
+ map:
24
+ name: 0
25
+ ip: 1
26
+ model: 2
27
+ group: 3
28
+ vars_map:
29
+ cumulus_routing_daemon: 4
30
+ ```
31
+
32
+ And set the `cumulus_routing_daemon` variable in the `router.db` file.
33
+
34
+ ```text
35
+ cumulus1:192.168.121.134:cumulus:cumulus:frr
36
+ ```
37
+
38
+ The default variable is `quagga` so existing installations continue to operate without interruption.
39
+
40
+ Back to [Model-Notes](README.md)
@@ -1,9 +1,13 @@
1
1
  Arista EOS Configuration
2
2
  ========================
3
3
 
4
- By default EOS requires keyboard-interactive to be added to your Oxidized config. You can avoid having to do this by configuring the following on the EOS device:
4
+ By default, EOS requires the `keyboard-interactive` SSH authentication method for a successful SSH login. To add support for this method to your Oxidized configuration, see the [SSH Auth Methods](../Configuration.md#ssh-auth-methods) directive.
5
5
 
6
- ```
6
+ It is also possible to modify the EOS configuration to accept the `password` method which Oxidized presents by default. To do so, the following configuration statement can be used:
7
+
8
+ ```text
7
9
  management ssh
8
10
  authentication mode password
9
11
  ```
12
+
13
+ Back to [Model-Notes](README.md)
@@ -2,8 +2,10 @@ Netgear Configuration
2
2
  =====================
3
3
 
4
4
  There are several models available with CLI management via telnet (port 60000), but they all behave like one of the following:
5
- - older models:
6
- ```
5
+
6
+ ### Older models:
7
+
8
+ ```text
7
9
  Connected to 192.168.3.201.
8
10
 
9
11
  (GS748Tv4)
@@ -17,8 +19,9 @@ Password:
17
19
  (GS748Tv4) #show running-config
18
20
  ```
19
21
 
20
- - newer models:
21
- ```
22
+ ### Newer models:
23
+
24
+ ```text
22
25
  Connected to 172.0.3.203.
23
26
 
24
27
  User:admin
@@ -31,17 +34,21 @@ Password:********
31
34
  ```
32
35
 
33
36
  The main differences are:
34
- - the prompt for username is different (looks quite strange for older models)
35
- - enable password
36
- - the older model prompts for enable password and it expects empty string
37
- - the newer model does not prompt for enable password at all
37
+
38
+ * the prompt for username is different (looks quite strange for older models)
39
+ * enable password
40
+ * the older model prompts for enable password and it expects empty string
41
+ * the newer model does not prompt for enable password at all
38
42
 
39
43
  Configuration for older/newer models: make sure you have defined variable 'enable':
40
- - `'true'` for newer models
41
- - `''` empty string: for older models
44
+
45
+ * `'true'` for newer models
46
+ * `''` empty string: for older models
42
47
 
43
48
  One possible configuration:
44
- - oxidized config
49
+
50
+ ### oxidized config
51
+
45
52
  ```yaml
46
53
  source:
47
54
  default: csv
@@ -57,8 +64,10 @@ source:
57
64
  enable: 4
58
65
  telnet_port: 5
59
66
  ```
60
- - router.db
61
- ```
67
+
68
+ ### router.db
69
+
70
+ ```text
62
71
  switchOldFW:netgear:admin:adminpw::60000
63
72
  switchNewFW:netgear:admin:adminpw:true:60000
64
73
  ```
@@ -11,6 +11,7 @@ Vendor | Model |Updated
11
11
  AireOS|[AireOS](AireOS.md)|29 Nov 2017
12
12
  Arbor Networks|[ArbOS](ArbOS.md)|27 Feb 2018
13
13
  Arista|[EOS](EOS.md)|05 Feb 2018
14
+ Cumulus|[Cumulus](Cumulus.md)|11 Jun 2018
14
15
  Huawei|[VRP](VRP-Huawei.md)|17 Nov 2017
15
16
  Juniper|[MX/QFX/EX/SRX/J Series](JunOS.md)|18 Jan 2018
16
17
  Netgear|[Netgear](Netgear.md)|11 Apr 2018
@@ -20,7 +20,6 @@ input:
20
20
  passive: false
21
21
  ```
22
22
 
23
-
24
23
  ## SSH/TelNet
25
24
 
26
25
  Below is the table from the XGS4600 CLI Reference Guide (Version 3.79~4.50 Edition 1, 07/2017)
@@ -33,7 +32,6 @@ Privilege Level | Types of commands at this privilege level
33
32
  13|Configure features except for login accounts, SNMP user accounts, the authentication method sequence and authorization settings, multiple logins, administrator and enable passwords, and configuration information display.
34
33
  14|Configure login accounts, SNMP user accounts, the authentication method sequence and authorization settings, multiple logins, and administrator and enable passwords, and display configuration information.
35
34
 
36
-
37
35
  Oxidized can now retrieve your configuration!
38
36
 
39
37
  Back to [Model-Notes](README.md)
@@ -133,6 +133,7 @@ Please note that user list is only updated once at creation.
133
133
  The HTTP output will POST a config to the specified HTTP URL. Basic username/password authentication is supported.
134
134
 
135
135
  Example HTTP output configuration:
136
+
136
137
  ```yaml
137
138
  output:
138
139
  default: http
@@ -61,7 +61,6 @@ pinentry-mode loopback
61
61
 
62
62
  **NOTE** - Many database engines have reserved keywords that may conflict with Oxidized configuration field names (such as 'name', 'group', etc). Pay attention to any names that are used and observed proper quoting methods to avoid errors or unpredictable results.
63
63
 
64
-
65
64
  ## Source: MYSQL
66
65
 
67
66
  `sudo apt-get install libmysqlclient-dev`
@@ -77,7 +77,7 @@
77
77
  * D-Link
78
78
  * [D-Link](/lib/oxidized/model/dlink.rb)
79
79
  * EdgeCore
80
- * [ES3528M](/lib/oxidized/model/edgecos.rb)
80
+ * [ES3528M](/lib/oxidized/model/edgecos.rb)
81
81
  * Ericsson/Redback
82
82
  * [IPOS (former SEOS)](/lib/oxidized/model/ipos.rb)
83
83
  * Extreme Networks
@@ -35,6 +35,7 @@ module Oxidized
35
35
  asetus.default.models = {} # model level configuration
36
36
  asetus.default.pid = File.join(Oxidized::Config::Root, 'pid')
37
37
 
38
+ asetus.default.stats.history_size = 10
38
39
  asetus.default.input.default = 'ssh, telnet'
39
40
  asetus.default.input.debug = false # or String for session log file
40
41
  asetus.default.input.ssh.secure = false # complain about changed certs
@@ -25,16 +25,19 @@ module Oxidized
25
25
  rescue Timeout::Error
26
26
  raise PromptUndetect, ['unable to detect prompt:', @node.prompt].join(' ')
27
27
  end
28
+ connected?
28
29
  end
29
30
 
30
31
  def connected?
31
32
  @telnet and not @telnet.sock.closed?
32
33
  end
33
34
 
34
- def cmd cmd, expect = @node.prompt
35
- Oxidized.logger.debug "Telnet: #{cmd} @#{@node.name}"
36
- args = { 'String' => cmd }
37
- args.merge!({ 'Match' => expect, 'Timeout' => @timeout }) if expect
35
+ def cmd cmd_str, expect = @node.prompt
36
+ return send(cmd_str + "\n") unless expect
37
+ Oxidized.logger.debug "Telnet: #{cmd_str} @#{@node.name}"
38
+ args = { 'String' => cmd_str,
39
+ 'Match' => expect,
40
+ 'Timeout' => @timeout }
38
41
  @telnet.cmd args
39
42
  end
40
43
 
@@ -49,7 +52,7 @@ module Oxidized
49
52
  private
50
53
 
51
54
  def expect re
52
- @telnet.waitfor 'Match' => re, 'Timeout' => @timeout
55
+ @telnet.oxidized_expect expect: re, timeout: @timeout
53
56
  end
54
57
 
55
58
  def disconnect
@@ -66,75 +69,36 @@ module Oxidized
66
69
  end
67
70
 
68
71
  class Net::Telnet
69
- ## FIXME: we just need 'line = model.expects line' to handle pager
70
72
  ## how to do this, without redefining the whole damn thing
71
73
  ## FIXME: we also need output (not sure I'm going to support this)
72
74
  attr_reader :output
73
- def waitfor(options) # :yield: recvdata
74
- time_out = @options["Timeout"]
75
- waittime = @options["Waittime"]
76
- fail_eof = @options["FailEOF"]
75
+ def oxidized_expect(options) # :yield: recvdata
77
76
  model = @options["Model"]
78
77
  @log = @options["Log"]
79
78
 
80
- if options.kind_of?(Hash)
81
- prompt = if options.has_key?("Match")
82
- options["Match"]
83
- elsif options.has_key?("Prompt")
84
- options["Prompt"]
85
- elsif options.has_key?("String")
86
- Regexp.new(Regexp.quote(options["String"]))
87
- end
88
- time_out = options["Timeout"] if options.has_key?("Timeout")
89
- waittime = options["Waittime"] if options.has_key?("Waittime")
90
- fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
91
- else
92
- prompt = options
93
- end
94
-
95
- if time_out == false
96
- time_out = nil
97
- end
79
+ expects = [options[:expect]].flatten
80
+ time_out = options[:timeout] || @options["Timeout"] || Oxidized.config.timeout?
98
81
 
99
- line = ''
100
- buf = ''
101
- rest = ''
102
- until prompt === line and not IO::select([@sock], nil, nil, waittime)
103
- unless IO::select([@sock], nil, nil, time_out)
104
- raise Timeout::Error, "timed out while waiting for more data"
105
- end
106
- begin
82
+ Timeout::timeout(time_out) do
83
+ line = ""
84
+ rest = ""
85
+ buf = ""
86
+ loop do
107
87
  c = @sock.readpartial(1024 * 1024)
108
88
  @output = c
109
- @dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
110
- if @options["Telnetmode"]
111
- c = rest + c
112
- if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
113
- Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
114
- buf = preprocess(c[0...c.rindex(/#{IAC}#{SB}/no)])
115
- rest = c[c.rindex(/#{IAC}#{SB}/no)..-1]
116
- elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
117
- c.rindex(/\r\z/no)
118
- buf = preprocess(c[0...pt])
119
- rest = c[pt..-1]
120
- else
121
- buf = preprocess(c)
122
- rest = ''
123
- end
89
+ c = rest + c
90
+
91
+ if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
92
+ Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
93
+ buf = preprocess(c[0...c.rindex(/#{IAC}#{SB}/no)])
94
+ rest = c[c.rindex(/#{IAC}#{SB}/no)..-1]
95
+ elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
96
+ c.rindex(/\r\z/no)
97
+ buf = preprocess(c[0...pt])
98
+ rest = c[pt..-1]
124
99
  else
125
- # Not Telnetmode.
126
- #
127
- # We cannot use preprocess() on this data, because that
128
- # method makes some Telnetmode-specific assumptions.
129
- buf = rest + c
100
+ buf = preprocess(c)
130
101
  rest = ''
131
- unless @options["Binmode"]
132
- if pt = buf.rindex(/\r\z/no)
133
- buf = buf[0...pt]
134
- rest = buf[pt..-1]
135
- end
136
- buf.gsub!(/#{EOL}/no, "\n")
137
- end
138
102
  end
139
103
  if Oxidized.config.input.debug?
140
104
  @log.print buf
@@ -142,17 +106,9 @@ class Net::Telnet
142
106
  end
143
107
  line += buf
144
108
  line = model.expects line
145
- line = yield line if block_given?
146
- yield buf if block_given?
147
- rescue EOFError # End of file reached
148
- raise if fail_eof
149
- if line == ''
150
- line = nil
151
- yield nil if block_given?
152
- end
153
- break
109
+ match = expects.find { |re| line.match re }
110
+ return match if match
154
111
  end
155
112
  end
156
- line
157
113
  end
158
114
  end
@@ -16,7 +16,6 @@ class CiscoSMB < Oxidized::Model
16
16
  cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
17
17
  cfg.gsub! /username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
18
18
  cfg.gsub! /^(encrypted radius-server key).*/, '\\1 <configuration removed>'
19
- cfg.gsub! /System Up Time.*/, ''
20
19
  cfg
21
20
  end
22
21
 
@@ -25,6 +24,7 @@ class CiscoSMB < Oxidized::Model
25
24
  end
26
25
 
27
26
  cmd 'show system' do |cfg|
27
+ cfg.gsub! /System Up Time.*/, ''
28
28
  comment cfg
29
29
  end
30
30
 
@@ -13,6 +13,11 @@ class Cumulus < Oxidized::Model
13
13
 
14
14
  # show the persistent configuration
15
15
  pre do
16
+ # Set FRR or Quagga in config
17
+ routing_daemon = vars(:cumulus_routing_daemon) ? vars(:cumulus_routing_daemon).downcase : 'quagga'
18
+ routing_conf_file = routing_daemon == 'frr' ? 'frr.conf' : 'Quagga.conf'
19
+ routing_daemon_shout = routing_daemon.upcase
20
+
16
21
  cfg = add_comment 'THE HOSTNAME'
17
22
  cfg += cmd 'cat /etc/hostname'
18
23
 
@@ -34,23 +39,23 @@ class Cumulus < Oxidized::Model
34
39
  cfg += add_comment 'SNMP settings'
35
40
  cfg += cmd 'cat /etc/snmp/snmpd.conf'
36
41
 
37
- cfg += add_comment 'QUAGGA DAEMONS'
38
- cfg += cmd 'cat /etc/quagga/daemons'
42
+ cfg += add_comment "#{routing_daemon_shout} DAEMONS"
43
+ cfg += cmd "cat /etc/#{routing_daemon}/daemons"
39
44
 
40
- cfg += add_comment 'QUAGGA ZEBRA'
41
- cfg += cmd 'cat /etc/quagga/zebra.conf'
45
+ cfg += add_comment "#{routing_daemon_shout} ZEBRA"
46
+ cfg += cmd "cat /etc/#{routing_daemon}/zebra.conf"
42
47
 
43
- cfg += add_comment 'QUAGGA BGP'
44
- cfg += cmd 'cat /etc/quagga/bgpd.conf'
48
+ cfg += add_comment "#{routing_daemon_shout} BGP"
49
+ cfg += cmd "cat /etc/#{routing_daemon}/bgpd.conf"
45
50
 
46
- cfg += add_comment 'QUAGGA OSPF'
47
- cfg += cmd 'cat /etc/quagga/ospfd.conf'
51
+ cfg += add_comment "#{routing_daemon_shout} OSPF"
52
+ cfg += cmd "cat /etc/#{routing_daemon}/ospfd.conf"
48
53
 
49
- cfg += add_comment 'QUAGGA OSPF6'
50
- cfg += cmd 'cat /etc/quagga/ospf6d.conf'
54
+ cfg += add_comment "#{routing_daemon_shout} OSPF6"
55
+ cfg += cmd "cat /etc/#{routing_daemon}/ospf6d.conf"
51
56
 
52
- cfg += add_comment 'QUAGGA CONF'
53
- cfg += cmd 'cat /etc/quagga/Quagga.conf'
57
+ cfg += add_comment "#{routing_daemon_shout} CONF"
58
+ cfg += cmd "cat /etc/#{routing_daemon}/#{routing_conf_file}"
54
59
 
55
60
  cfg += add_comment 'MOTD'
56
61
  cfg += cmd 'cat /etc/motd'
@@ -26,8 +26,8 @@ class Dlink < Oxidized::Model
26
26
  cmd 'show config current'
27
27
 
28
28
  cfg :telnet do
29
- username /\r*username:/
30
- password /\r*password:/
29
+ username /\r*[Uu]ser[Nn]ame:/
30
+ password /\r*[Pp]ass[Ww]ord:/
31
31
  end
32
32
 
33
33
  cfg :telnet, :ssh do
@@ -24,9 +24,9 @@ module Oxidized
24
24
  @prompt or @prompt = _prompt
25
25
  end
26
26
 
27
- def cfg *methods, &block
27
+ def cfg *methods, **args, &block
28
28
  [methods].flatten.each do |method|
29
- @cfg[method.to_s] << block
29
+ process_args_block(@cfg[method.to_s], args, block)
30
30
  end
31
31
  end
32
32
 
@@ -34,11 +34,11 @@ module Oxidized
34
34
  @cfg
35
35
  end
36
36
 
37
- def cmd _cmd = nil, &block
37
+ def cmd _cmd = nil, **args, &block
38
38
  if _cmd.class == Symbol
39
- @cmd[_cmd] << block
39
+ process_args_block(@cmd[_cmd], args, block)
40
40
  else
41
- @cmd[:cmd] << [_cmd, block]
41
+ process_args_block(@cmd[:cmd], args, [_cmd, block])
42
42
  end
43
43
  Oxidized.logger.debug "lib/oxidized/model/model.rb Added #{_cmd} to the commands list"
44
44
  end
@@ -47,8 +47,8 @@ module Oxidized
47
47
  @cmd
48
48
  end
49
49
 
50
- def expect re, &block
51
- @expect << [re, block]
50
+ def expect re, **args, &block
51
+ process_args_block(@expect, args, [re, block])
52
52
  end
53
53
 
54
54
  def expects
@@ -62,8 +62,8 @@ module Oxidized
62
62
  # @since 0.0.39
63
63
  # @yield expects block which should return [String]
64
64
  # @return [void]
65
- def pre &block
66
- @procs[:pre] << block
65
+ def pre **args, &block
66
+ process_args_block(@procs[:pre], args, block)
67
67
  end
68
68
 
69
69
  # calls the block at the end of the model, adding the output of the block
@@ -73,8 +73,8 @@ module Oxidized
73
73
  # @since 0.0.39
74
74
  # @yield expects block which should return [String]
75
75
  # @return [void]
76
- def post &block
77
- @procs[:post] << block
76
+ def post **args, &block
77
+ process_args_block(@procs[:post], args, block)
78
78
  end
79
79
 
80
80
  # @author Saku Ytti <saku@ytti.fi>
@@ -83,6 +83,17 @@ module Oxidized
83
83
  def procs
84
84
  @procs
85
85
  end
86
+
87
+ private
88
+
89
+ def process_args_block(target, args, block)
90
+ if args[:clear]
91
+ target.replace([block])
92
+ else
93
+ method = args[:prepend] ? :unshift : :push
94
+ target.send(method, block)
95
+ end
96
+ end
86
97
  end
87
98
 
88
99
  attr_accessor :input, :node
@@ -1,7 +1,7 @@
1
1
  module Oxidized
2
2
  class Node
3
3
  class Stats
4
- attr_accessor :mtime
4
+ attr_reader :mtimes
5
5
  MAX_STAT = 10
6
6
 
7
7
  # @param [Job] job job whose information add to stats
@@ -13,7 +13,7 @@ module Oxidized
13
13
  :time => job.time,
14
14
  }
15
15
  @stats[job.status] ||= []
16
- @stats[job.status].shift if @stats[job.status].size > MAX_STAT
16
+ @stats[job.status].shift if @stats[job.status].size > @history_size
17
17
  @stats[job.status].push stat
18
18
  @stats[:counter][job.status] += 1
19
19
  end
@@ -36,15 +36,21 @@ module Oxidized
36
36
  @stats[:counter].reduce(0) { |m, h| h[0] == :success ? m : m + h[1] }
37
37
  end
38
38
 
39
+ def mtime
40
+ mtimes.last
41
+ end
42
+
39
43
  def update_mtime
40
- @mtime = Time.now.utc
44
+ @mtimes.push Time.now.utc
45
+ @mtimes.shift
41
46
  end
42
47
 
43
48
  private
44
49
 
45
50
  def initialize
46
- @mtime = "unknown"
47
- @stats = {}
51
+ @history_size = Oxidized.config.stats.history_size? || MAX_STAT
52
+ @mtimes = Array.new(@history_size, "unknown")
53
+ @stats = {}
48
54
  @stats[:counter] = Hash.new 0
49
55
  end
50
56
  end
@@ -39,21 +39,20 @@ module Oxidized
39
39
 
40
40
  response = http.request(request)
41
41
  data = JSON.parse(response.body)
42
+ data = string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
42
43
  data.each do |node|
43
44
  next if node.empty?
44
45
  # map node parameters
45
46
  keys = {}
46
47
  @cfg.map.each do |key, want_position|
47
- want_positions = want_position.split('.')
48
- keys[key.to_sym] = node_var_interpolate node.dig(*want_positions)
48
+ keys[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
49
49
  end
50
50
  keys[:model] = map_model keys[:model] if keys.has_key? :model
51
51
 
52
52
  # map node specific vars
53
53
  vars = {}
54
54
  @cfg.vars_map.each do |key, want_position|
55
- want_positions = want_position.split('.')
56
- vars[key.to_sym] = node_var_interpolate node.dig(*want_positions)
55
+ vars[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
57
56
  end
58
57
  keys[:vars] = vars unless vars.empty?
59
58
 
@@ -61,20 +60,17 @@ module Oxidized
61
60
  end
62
61
  nodes
63
62
  end
64
- end
65
- end
66
63
 
67
- if RUBY_VERSION < '2.3'
68
- class Hash
69
- def dig(key, *rest)
70
- value = self[key]
71
- if value.nil? || rest.empty?
72
- value
73
- elsif value.respond_to?(:dig)
74
- value.dig(*rest)
75
- else # foo.bar.baz (bar exist but is not hash)
76
- return nil
64
+ private
65
+
66
+ def string_navigate object, wants
67
+ wants.split(".").map do |want|
68
+ head, match, _tail = want.partition(/\[\d+\]/)
69
+ match.empty? ? head : [head, match[1..-2].to_i]
70
+ end.flatten.each do |want|
71
+ object = object[want] if object.respond_to? :each
77
72
  end
73
+ object
78
74
  end
79
75
  end
80
76
  end
@@ -1,6 +1,6 @@
1
1
  module Oxidized
2
- VERSION = '0.23.0'
3
- VERSION_FULL = '0.23.0'
2
+ VERSION = '0.24.0'
3
+ VERSION_FULL = '0.24.0'
4
4
  def self.version_set
5
5
  version_full = %x(git describe --tags).chop rescue ""
6
6
  version = %x(git describe --tags --abbrev=0).chop rescue ""
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxidized
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Saku Ytti
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-06-11 00:00:00.000000000 Z
13
+ date: 2018-06-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: asetus
@@ -231,6 +231,7 @@ files:
231
231
  - docs/Model-Notes/AireOS.md
232
232
  - docs/Model-Notes/ArbOS.md
233
233
  - docs/Model-Notes/Comware.md
234
+ - docs/Model-Notes/Cumulus.md
234
235
  - docs/Model-Notes/EOS.md
235
236
  - docs/Model-Notes/JunOS.md
236
237
  - docs/Model-Notes/Netgear.md