oxidized 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|