oxidized 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +3 -4
- data/Rakefile +1 -1
- data/extra/nagios_check_failing_nodes.rb +25 -0
- data/lib/oxidized/core.rb +1 -0
- data/lib/oxidized/input/input.rb +2 -0
- data/lib/oxidized/input/ssh.rb +5 -1
- data/lib/oxidized/input/telnet.rb +5 -1
- data/lib/oxidized/jobs.rb +27 -5
- data/lib/oxidized/model/eos.rb +12 -3
- data/lib/oxidized/model/ironware.rb +1 -1
- data/lib/oxidized/model/model.rb +4 -5
- data/lib/oxidized/model/xos.rb +1 -1
- data/lib/oxidized/node.rb +2 -1
- data/lib/oxidized/nodes.rb +2 -2
- data/lib/oxidized/output/git.rb +7 -2
- data/lib/oxidized/worker.rb +6 -0
- data/oxidized.gemspec +2 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8b4c0fb1595706703f57f1d8235cb0521186931
|
4
|
+
data.tar.gz: ec43f93a8c891a3818d36daf7376650da1b4cc59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31482aac75b5c83ea25f2e8d3c92ab86f09813caca3e68612a2a719bda2c142bacdf95e29094abf87b0c5f3fa49cfb8fc4a61cd6c4a968cc6f2e60e276282197
|
7
|
+
data.tar.gz: 7a41f80ef435e574734ec761b32c5f86849d4cea2425cdc40694809e59a7087b3618ab174f92d37ef6ab86567d9cda029649c123829b84f5160600db90b9c0da
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# 0.4.0
|
2
|
+
- FEATURE: allow setting IP address in addition to name in source (SQL/CSV)
|
3
|
+
- FEATURE: approximate how long it takes to get node from larger view than 1
|
4
|
+
- FEATURE: unconditionally start new job if too long has passed since previous start
|
5
|
+
- FEATURE: add enable to Arista EOS model
|
6
|
+
- FEATURE: add rugged dependency in gemspec
|
7
|
+
- FEATURE: log prompt detection failures
|
8
|
+
- BUGFIX: xos while using telnet (by @fhibler)
|
9
|
+
- BUGFIX: ironware logout on some models (by @fhibler)
|
10
|
+
- BUGFIX: allow node to be removed while it is being collected
|
11
|
+
- BUGFIX: if model returns non string value, return empty string
|
12
|
+
- BUGFIX: better prompt for Arista EOS model (by @rodecker)
|
13
|
+
- BUGFIX: improved configuration handling for Arista EOS model (by @rodecker)
|
14
|
+
|
1
15
|
# 0.3.0
|
2
16
|
- FEATURE: *FIXME* bunch of stuff I did for richih, docs needed
|
3
17
|
- FEATURE: ComWare model (by erJasp)
|
data/README.md
CHANGED
@@ -71,7 +71,6 @@ Install all required packages and gems.
|
|
71
71
|
|
72
72
|
```shell
|
73
73
|
apt-get install ruby ruby-dev libsqlite3-dev libssl-dev pkg-config cmake
|
74
|
-
gem install rugged
|
75
74
|
gem install oxidized
|
76
75
|
gem install oxidized-script oxidized-web # if you don't install oxidized-web, make sure you remove "rest" from your config
|
77
76
|
```
|
@@ -193,7 +192,7 @@ source:
|
|
193
192
|
model: 1
|
194
193
|
username: 2
|
195
194
|
password: 3
|
196
|
-
|
195
|
+
vars_map:
|
197
196
|
enable: 4
|
198
197
|
```
|
199
198
|
|
@@ -213,7 +212,7 @@ source:
|
|
213
212
|
model: model
|
214
213
|
username: username
|
215
214
|
password: password
|
216
|
-
|
215
|
+
vars_map:
|
217
216
|
enable: enable
|
218
217
|
```
|
219
218
|
|
@@ -279,7 +278,7 @@ source:
|
|
279
278
|
model: 1
|
280
279
|
username: 2
|
281
280
|
password: 3
|
282
|
-
|
281
|
+
vars_map:
|
283
282
|
enable: 4
|
284
283
|
model_map:
|
285
284
|
cisco: ios
|
data/Rakefile
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
## contrib via https://github.com/ytti/oxidized/issues/67
|
4
|
+
|
5
|
+
require 'open-uri'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
critical = false
|
9
|
+
critical_nodes = []
|
10
|
+
|
11
|
+
json = JSON.load(open("http://localhost:8888/nodes.json"))
|
12
|
+
json.each do |node|
|
13
|
+
if node['last']['status'] != 'success'
|
14
|
+
critical_nodes << node['name']
|
15
|
+
critical = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if critical
|
20
|
+
puts 'Unable to backup: ' + critical_nodes.join(' ')
|
21
|
+
exit 2
|
22
|
+
else
|
23
|
+
puts 'Backup of all nodes completed successfully.'
|
24
|
+
exit 0
|
25
|
+
end
|
data/lib/oxidized/core.rb
CHANGED
data/lib/oxidized/input/input.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Oxidized
|
2
|
+
class PromptUndetect < OxidizedError; end
|
2
3
|
class Input
|
3
4
|
include Oxidized::Config::Vars
|
4
5
|
|
@@ -8,6 +9,7 @@ module Oxidized
|
|
8
9
|
],
|
9
10
|
:warn => [
|
10
11
|
IOError,
|
12
|
+
PromptUndetect,
|
11
13
|
Timeout::Error,
|
12
14
|
Errno::ECONNRESET,
|
13
15
|
Errno::EHOSTUNREACH,
|
data/lib/oxidized/input/ssh.rb
CHANGED
@@ -26,7 +26,11 @@ module Oxidized
|
|
26
26
|
:paranoid => secure
|
27
27
|
unless @exec
|
28
28
|
shell_open @ssh
|
29
|
-
|
29
|
+
begin
|
30
|
+
@username ? shell_login : expect(@node.prompt)
|
31
|
+
rescue Timeout::Error
|
32
|
+
raise PromptUndetect, [ @output, 'not matching configured prompt', @node.prompt ].join(' ')
|
33
|
+
end
|
30
34
|
end
|
31
35
|
connected?
|
32
36
|
end
|
@@ -20,7 +20,11 @@ module Oxidized
|
|
20
20
|
@telnet.puts @node.auth[:username]
|
21
21
|
expect password
|
22
22
|
@telnet.puts @node.auth[:password]
|
23
|
-
|
23
|
+
begin
|
24
|
+
expect @node.prompt
|
25
|
+
rescue Timeout::Error
|
26
|
+
raise PromptUndetect, [ 'unable to detect prompt:', @node.prompt ].join(' ')
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def connected?
|
data/lib/oxidized/jobs.rb
CHANGED
@@ -1,24 +1,46 @@
|
|
1
1
|
module Oxidized
|
2
2
|
class Jobs < Array
|
3
|
-
|
3
|
+
AVERAGE_DURATION = 5 # initially presume nodes take 5s to complete
|
4
|
+
MAX_INTER_JOB_GAP = 300 # add job if more than X from last job started
|
5
|
+
attr_accessor :interval, :max, :want
|
6
|
+
|
4
7
|
def initialize max, interval, nodes
|
5
8
|
@max = max
|
6
|
-
#@interval = interval * 60
|
7
9
|
@interval = interval
|
8
10
|
@nodes = nodes
|
9
|
-
@
|
10
|
-
|
11
|
+
@last = Time.now.utc
|
12
|
+
@durations = Array.new @nodes.size, AVERAGE_DURATION
|
13
|
+
duration AVERAGE_DURATION
|
11
14
|
super()
|
12
15
|
end
|
16
|
+
|
17
|
+
def push arg
|
18
|
+
@last = Time.now.utc
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
13
22
|
def duration last
|
14
|
-
@
|
23
|
+
@durations.push(last).shift
|
24
|
+
@duration = @durations.inject(:+).to_f / @nodes.size #rolling average
|
15
25
|
new_count
|
16
26
|
end
|
27
|
+
|
17
28
|
def new_count
|
18
29
|
@want = ((@nodes.size * @duration) / @interval).to_i
|
19
30
|
@want = 1 if @want < 1
|
20
31
|
@want = @nodes.size if @want > @nodes.size
|
21
32
|
@want = @max if @want > @max
|
22
33
|
end
|
34
|
+
|
35
|
+
def work
|
36
|
+
# if a) we want less or same amount of threads as we now running
|
37
|
+
# and b) we want less threads running than the total amount of nodes
|
38
|
+
# and c) there is more than MAX_INTER_JOB_GAP since last one was started
|
39
|
+
# then we want one more thread (rationale is to fix hanging thread causing HOLB)
|
40
|
+
if @want <= size and @want < @nodes.size
|
41
|
+
@want +=1 if (Time.now.utc - @last) > MAX_INTER_JOB_GAP
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
23
45
|
end
|
24
46
|
end
|
data/lib/oxidized/model/eos.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
class EOS < Oxidized::Model
|
2
2
|
|
3
3
|
# Arista EOS model #
|
4
|
-
# need to add telnet support here .. #
|
5
4
|
|
6
|
-
prompt
|
5
|
+
prompt /^.+[#>]\s?$/
|
7
6
|
|
8
7
|
comment '! '
|
9
8
|
|
10
9
|
cmd :all do |cfg|
|
11
|
-
cfg.each_line.to_a[
|
10
|
+
cfg.each_line.to_a[1..-2].join
|
12
11
|
end
|
13
12
|
|
14
13
|
cmd :secret do |cfg|
|
@@ -26,7 +25,17 @@ class EOS < Oxidized::Model
|
|
26
25
|
end
|
27
26
|
|
28
27
|
cfg :telnet, :ssh do
|
28
|
+
if vars :enable
|
29
|
+
post_login do
|
30
|
+
send "enable\n"
|
31
|
+
expect /[pP]assword:\s?$/
|
32
|
+
send vars(:enable) + "\n"
|
33
|
+
expect /^.+[#>]\s?$/
|
34
|
+
end
|
35
|
+
post_login 'terminal length 0'
|
36
|
+
end
|
29
37
|
pre_logout 'exit'
|
30
38
|
end
|
31
39
|
|
32
40
|
end
|
41
|
+
|
data/lib/oxidized/model/model.rb
CHANGED
@@ -133,10 +133,10 @@ module Oxidized
|
|
133
133
|
outputs << out
|
134
134
|
end
|
135
135
|
procs[:pre].each do |pre_proc|
|
136
|
-
outputs.unshift
|
136
|
+
outputs.unshift process_cmd_output(instance_eval(&pre_proc), '')
|
137
137
|
end
|
138
138
|
procs[:post].each do |post_proc|
|
139
|
-
outputs <<
|
139
|
+
outputs << process_cmd_output(instance_eval(&post_proc), '')
|
140
140
|
end
|
141
141
|
outputs
|
142
142
|
end
|
@@ -152,9 +152,8 @@ module Oxidized
|
|
152
152
|
private
|
153
153
|
|
154
154
|
def process_cmd_output output, name
|
155
|
-
|
156
|
-
|
157
|
-
end
|
155
|
+
output = Oxidized::String.new output if ::String === output
|
156
|
+
output = Oxidized::String.new '' unless Oxidized::String === output
|
158
157
|
output.set_cmd(name)
|
159
158
|
output
|
160
159
|
end
|
data/lib/oxidized/model/xos.rb
CHANGED
data/lib/oxidized/node.rb
CHANGED
@@ -10,7 +10,8 @@ module Oxidized
|
|
10
10
|
alias :running? :running
|
11
11
|
def initialize opt
|
12
12
|
@name = opt[:name]
|
13
|
-
@ip =
|
13
|
+
@ip = IPAddr.new(opt[:ip]).to_s rescue nil
|
14
|
+
@ip ||= Resolv.new.getaddress @name
|
14
15
|
@group = opt[:group]
|
15
16
|
@input = resolve_input opt
|
16
17
|
@output = resolve_output opt
|
data/lib/oxidized/nodes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Oxidized
|
2
|
-
require 'oxidized/node'
|
3
2
|
require 'ipaddr'
|
3
|
+
require 'oxidized/node'
|
4
4
|
class Oxidized::NotSupported < OxidizedError; end
|
5
5
|
class Oxidized::NodeNotFound < OxidizedError; end
|
6
6
|
class Nodes < Array
|
@@ -23,8 +23,8 @@ module Oxidized
|
|
23
23
|
Log.error "node %s is not resolvable, raised %s with message '%s'" % [node, err.class, err.message]
|
24
24
|
end
|
25
25
|
end
|
26
|
-
Log.info "Loaded #{size} nodes"
|
27
26
|
size == 0 ? replace(new) : update_nodes(new)
|
27
|
+
Log.info "Loaded #{size} nodes"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/lib/oxidized/output/git.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Oxidized
|
2
2
|
class Git < Output
|
3
|
+
class GitError < OxidizedError; end
|
3
4
|
begin
|
4
5
|
gem 'rugged', '~> 0.21.0'
|
5
6
|
require 'rugged'
|
@@ -71,8 +72,12 @@ class Git < Output
|
|
71
72
|
end
|
72
73
|
repo = Rugged::Repository.new repo
|
73
74
|
update_repo repo, file, data, @msg, @user, @email
|
74
|
-
rescue Rugged::OSError, Rugged::RepositoryError
|
75
|
-
|
75
|
+
rescue Rugged::OSError, Rugged::RepositoryError => open_error
|
76
|
+
begin
|
77
|
+
Rugged::Repository.init_at repo, :bare
|
78
|
+
rescue => create_error
|
79
|
+
raise GitError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
|
80
|
+
end
|
76
81
|
retry
|
77
82
|
end
|
78
83
|
|
data/lib/oxidized/worker.rb
CHANGED
@@ -7,10 +7,12 @@ module Oxidized
|
|
7
7
|
@jobs = Jobs.new CFG.threads, CFG.interval, @nodes
|
8
8
|
Thread.abort_on_exception = true
|
9
9
|
end
|
10
|
+
|
10
11
|
def work
|
11
12
|
ended = []
|
12
13
|
@jobs.delete_if { |job| ended << job if not job.alive? }
|
13
14
|
ended.each { |job| process job }
|
15
|
+
@jobs.work
|
14
16
|
while @jobs.size < @jobs.want
|
15
17
|
Log.debug "Jobs #{@jobs.size}, Want: #{@jobs.want}"
|
16
18
|
# ask for next node in queue non destructive way
|
@@ -24,6 +26,7 @@ module Oxidized
|
|
24
26
|
@jobs.push Job.new node
|
25
27
|
end
|
26
28
|
end
|
29
|
+
|
27
30
|
def process job
|
28
31
|
node = job.node
|
29
32
|
node.last = job
|
@@ -49,6 +52,9 @@ module Oxidized
|
|
49
52
|
end
|
50
53
|
Log.warn msg
|
51
54
|
end
|
55
|
+
rescue NodeNotFound
|
56
|
+
Log.warn "#{node.name} not found, removed while collecting?"
|
52
57
|
end
|
58
|
+
|
53
59
|
end
|
54
60
|
end
|
data/oxidized.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'oxidized'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.4.0'
|
4
4
|
s.licenses = %w( Apache-2.0 )
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = [ 'Saku Ytti', 'Samer Abdel-Hafez' ]
|
@@ -17,4 +17,5 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_runtime_dependency 'asetus', '~> 0.1'
|
18
18
|
s.add_runtime_dependency 'slop', '~> 3.5'
|
19
19
|
s.add_runtime_dependency 'net-ssh', '~> 2.8'
|
20
|
+
s.add_runtime_dependency 'rugged', '~> 0.21.4'
|
20
21
|
end
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Saku Ytti
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asetus
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '2.8'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rugged
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.21.4
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.21.4
|
56
70
|
description: software to fetch configuration from network devices and store them
|
57
71
|
email:
|
58
72
|
- saku@ytti.fi
|
@@ -68,6 +82,7 @@ files:
|
|
68
82
|
- Rakefile
|
69
83
|
- TODO.md
|
70
84
|
- bin/oxidized
|
85
|
+
- extra/nagios_check_failing_nodes.rb
|
71
86
|
- extra/oxidized.init
|
72
87
|
- extra/rest_client.rb
|
73
88
|
- extra/syslog.rb
|