oxidized 0.24.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +4 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +26 -2
- data/Dockerfile +8 -32
- data/README.md +17 -5
- data/bin/oxidized +1 -1
- data/docs/Configuration.md +41 -3
- data/docs/Hooks.md +26 -0
- data/docs/Model-Notes/AireOS.md +1 -2
- data/docs/Model-Notes/ArbOS.md +1 -2
- data/docs/Model-Notes/Comware.md +1 -2
- data/docs/Model-Notes/EOS.md +1 -2
- data/docs/Model-Notes/JunOS.md +1 -2
- data/docs/Model-Notes/Netgear.md +5 -6
- data/docs/Model-Notes/Nokia.md +9 -0
- data/docs/Model-Notes/README.md +3 -2
- data/docs/Model-Notes/VRP-Huawei.md +1 -2
- data/docs/Model-Notes/Viptela.md +12 -0
- data/docs/Model-Notes/XGS4600-Zyxel.md +1 -2
- data/docs/Ruby-API.md +54 -2
- data/docs/Supported-OS-Types.md +12 -0
- data/extra/oxidized.service +7 -0
- data/lib/oxidized/cli.rb +7 -0
- data/lib/oxidized/config.rb +3 -0
- data/lib/oxidized/core.rb +1 -0
- data/lib/oxidized/hook/ciscosparkdiff.rb +11 -17
- data/lib/oxidized/hook/slackdiff.rb +5 -11
- data/lib/oxidized/hook/xmppdiff.rb +1 -0
- data/lib/oxidized/input/ssh.rb +43 -27
- data/lib/oxidized/input/telnet.rb +1 -0
- data/lib/oxidized/model/acos.rb +2 -2
- data/lib/oxidized/model/acsw.rb +6 -6
- data/lib/oxidized/model/adtran.rb +22 -0
- data/lib/oxidized/model/aen.rb +2 -2
- data/lib/oxidized/model/aireos.rb +3 -2
- data/lib/oxidized/model/alteonos.rb +2 -2
- data/lib/oxidized/model/aos.rb +1 -1
- data/lib/oxidized/model/aos7.rb +1 -1
- data/lib/oxidized/model/aosw.rb +5 -3
- data/lib/oxidized/model/apc_aos.rb +1 -1
- data/lib/oxidized/model/arbos.rb +2 -2
- data/lib/oxidized/model/asa.rb +8 -2
- data/lib/oxidized/model/awplus.rb +1 -1
- data/lib/oxidized/model/axos.rb +16 -0
- data/lib/oxidized/model/c4cmts.rb +3 -5
- data/lib/oxidized/model/casa.rb +1 -1
- data/lib/oxidized/model/catos.rb +1 -1
- data/lib/oxidized/model/ciscosma.rb +1 -1
- data/lib/oxidized/model/ciscosmb.rb +10 -4
- data/lib/oxidized/model/comtrol.rb +41 -0
- data/lib/oxidized/model/comware.rb +1 -1
- data/lib/oxidized/model/coriantgroove.rb +4 -6
- data/lib/oxidized/model/cumulus.rb +14 -1
- data/lib/oxidized/model/datacom.rb +1 -2
- data/lib/oxidized/model/dcnos.rb +1 -1
- data/lib/oxidized/model/dellx.rb +76 -0
- data/lib/oxidized/model/dlink.rb +2 -2
- data/lib/oxidized/model/dnos.rb +3 -1
- data/lib/oxidized/model/eciapollo.rb +34 -0
- data/lib/oxidized/model/edgecos.rb +1 -0
- data/lib/oxidized/model/edgeos.rb +6 -1
- data/lib/oxidized/model/eos.rb +3 -2
- data/lib/oxidized/model/fiberdriver.rb +1 -1
- data/lib/oxidized/model/firebrick.rb +31 -0
- data/lib/oxidized/model/firewareos.rb +1 -1
- data/lib/oxidized/model/fortios.rb +5 -4
- data/lib/oxidized/model/ftos.rb +4 -1
- data/lib/oxidized/model/fujitsupy.rb +3 -3
- data/lib/oxidized/model/gaiaos.rb +1 -1
- data/lib/oxidized/model/gcombnps.rb +3 -1
- data/lib/oxidized/model/hatteras.rb +1 -1
- data/lib/oxidized/model/hirschmann.rb +2 -2
- data/lib/oxidized/model/hpebladesystem.rb +1 -1
- data/lib/oxidized/model/ios.rb +21 -13
- data/lib/oxidized/model/ipos.rb +3 -3
- data/lib/oxidized/model/ironware.rb +3 -3
- data/lib/oxidized/model/isam.rb +1 -1
- data/lib/oxidized/model/junos.rb +1 -1
- data/lib/oxidized/model/masteros.rb +2 -3
- data/lib/oxidized/model/mlnxos.rb +5 -5
- data/lib/oxidized/model/model.rb +3 -0
- data/lib/oxidized/model/ndms.rb +1 -2
- data/lib/oxidized/model/netgear.rb +7 -9
- data/lib/oxidized/model/netonix.rb +1 -1
- data/lib/oxidized/model/netscaler.rb +6 -1
- data/lib/oxidized/model/nos.rb +2 -2
- data/lib/oxidized/model/oneos.rb +1 -1
- data/lib/oxidized/model/openbsd.rb +8 -22
- data/lib/oxidized/model/openwrt.rb +1 -0
- data/lib/oxidized/model/opnsense.rb +1 -1
- data/lib/oxidized/model/panos.rb +9 -9
- data/lib/oxidized/model/pfsense.rb +2 -1
- data/lib/oxidized/model/planet.rb +1 -1
- data/lib/oxidized/model/powerconnect.rb +7 -4
- data/lib/oxidized/model/procurve.rb +7 -5
- data/lib/oxidized/model/routeros.rb +1 -1
- data/lib/oxidized/model/saos.rb +1 -1
- data/lib/oxidized/model/screenos.rb +3 -3
- data/lib/oxidized/model/sros.rb +2 -2
- data/lib/oxidized/model/stoneos.rb +1 -1
- data/lib/oxidized/model/tmos.rb +2 -0
- data/lib/oxidized/model/tplink.rb +4 -0
- data/lib/oxidized/model/viptela.rb +29 -0
- data/lib/oxidized/model/voltaire.rb +5 -5
- data/lib/oxidized/model/voss.rb +4 -4
- data/lib/oxidized/model/vrp.rb +1 -1
- data/lib/oxidized/model/vyatta.rb +1 -1
- data/lib/oxidized/model/weos.rb +1 -1
- data/lib/oxidized/model/xos.rb +9 -2
- data/lib/oxidized/node.rb +20 -31
- data/lib/oxidized/nodes.rb +3 -0
- data/lib/oxidized/output/git.rb +17 -20
- data/lib/oxidized/output/gitcrypt.rb +2 -1
- data/lib/oxidized/output/http.rb +19 -12
- data/lib/oxidized/source/csv.rb +15 -8
- data/lib/oxidized/source/http.rb +26 -22
- data/lib/oxidized/string.rb +9 -4
- data/lib/oxidized/version.rb +2 -2
- data/lib/oxidized/worker.rb +44 -36
- data/oxidized.gemspec +1 -4
- metadata +26 -16
data/lib/oxidized/model/voss.rb
CHANGED
@@ -14,10 +14,10 @@ class Voss < Oxidized::Model
|
|
14
14
|
# Get sys-info and remove information that changes such has temperature and power
|
15
15
|
cmd 'show sys-info' do |cfg|
|
16
16
|
cfg.gsub! /(^((.*)SysUpTime(.*))$)/, 'removed SysUpTime'
|
17
|
-
cfg.gsub! /^((.*)Temperature Info
|
18
|
-
cfg.gsub! /(^((.*)AmbientTemperature(.*)
|
19
|
-
cfg.gsub! /(^((.*)Temperature(.*)
|
20
|
-
cfg.gsub! /(^((.*)Total Power Usage(.*)
|
17
|
+
cfg.gsub! /^((.*)Temperature Info :(.*\r?\n){4})/, 'removed Temperature Info and 3 more lines'
|
18
|
+
cfg.gsub! /(^((.*)AmbientTemperature(.*):(.*))$)/, 'removed AmbientTemperature'
|
19
|
+
cfg.gsub! /(^((.*)Temperature(.*):(.*))$)/, 'removed Temperature'
|
20
|
+
cfg.gsub! /(^((.*)Total Power Usage(.*):(.*))$)/, 'removed Total Power Usage'
|
21
21
|
comment "#{cfg}\n"
|
22
22
|
end
|
23
23
|
|
data/lib/oxidized/model/vrp.rb
CHANGED
data/lib/oxidized/model/weos.rb
CHANGED
data/lib/oxidized/model/xos.rb
CHANGED
@@ -27,7 +27,7 @@ class XOS < Oxidized::Model
|
|
27
27
|
end
|
28
28
|
|
29
29
|
cmd 'show configuration' do |cfg|
|
30
|
-
cfg = cfg.each_line.reject { |line| line.match /^#(\s[\w]+\s)(Configuration generated)/ }.join
|
30
|
+
cfg = cfg.each_line.reject { |line| line.match /^#(\s[\w -]+\s)(Configuration generated)/ }.join
|
31
31
|
cfg
|
32
32
|
end
|
33
33
|
|
@@ -41,7 +41,14 @@ class XOS < Oxidized::Model
|
|
41
41
|
end
|
42
42
|
|
43
43
|
cfg :telnet, :ssh do
|
44
|
-
post_login
|
44
|
+
post_login do
|
45
|
+
data = cmd 'disable clipaging session'
|
46
|
+
match = data.match /^disable clipaging session\n\*?[\w .-]+(:\d+)? # $/m
|
47
|
+
next if match
|
48
|
+
|
49
|
+
cmd 'disable clipaging'
|
50
|
+
end
|
51
|
+
|
45
52
|
pre_logout do
|
46
53
|
send "exit\n"
|
47
54
|
send "n\n"
|
data/lib/oxidized/node.rb
CHANGED
@@ -39,6 +39,7 @@ module Oxidized
|
|
39
39
|
# don't try input if model is missing config block, we may need strong config to class_name map
|
40
40
|
cfg_name = input.to_s.split('::').last.downcase
|
41
41
|
next unless @model.cfg[cfg_name] and not @model.cfg[cfg_name].empty?
|
42
|
+
|
42
43
|
@model.input = input = input.new
|
43
44
|
if config = run_input(input)
|
44
45
|
Oxidized.logger.debug "lib/oxidized/node.rb: #{input.class.name} ran for #{name} successfully"
|
@@ -74,14 +75,17 @@ module Oxidized
|
|
74
75
|
Oxidized.logger.send(level, '%s raised %s%s with msg "%s"' % [self.ip, err.class, resc, err.message])
|
75
76
|
return false
|
76
77
|
rescue => err
|
77
|
-
|
78
|
-
|
78
|
+
crashdir = Oxidized.config.crash.directory
|
79
|
+
crashfile = Oxidized.config.crash.hostnames? ? self.name : self.ip.to_s
|
80
|
+
FileUtils.mkdir_p(crashdir) unless File.directory?(crashdir)
|
81
|
+
|
82
|
+
open File.join(crashdir, crashfile), 'w' do |fh|
|
79
83
|
fh.puts Time.now.utc
|
80
84
|
fh.puts err.message + ' [' + err.class.to_s + ']'
|
81
85
|
fh.puts '-' * 50
|
82
86
|
fh.puts err.backtrace
|
83
87
|
end
|
84
|
-
Oxidized.logger.error '%s raised %s with msg "%s", %s saved' % [self.ip, err.class, err.message,
|
88
|
+
Oxidized.logger.error '%s raised %s with msg "%s", %s saved' % [self.ip, err.class, err.message, crashfile]
|
85
89
|
return false
|
86
90
|
end
|
87
91
|
end
|
@@ -173,32 +177,18 @@ module Oxidized
|
|
173
177
|
end
|
174
178
|
|
175
179
|
def resolve_repo opt
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
File.join(File.dirname(remote_repo), @group + '.git')
|
184
|
-
end
|
185
|
-
else
|
186
|
-
remote_repo[@group]
|
187
|
-
end
|
188
|
-
elsif is_gitcrypt? opt
|
189
|
-
remote_repo = Oxidized.config.output.gitcrypt.repo
|
190
|
-
|
191
|
-
if remote_repo.is_a?(::String)
|
192
|
-
if Oxidized.config.output.gitcrypt.single_repo? || @group.nil?
|
193
|
-
remote_repo
|
194
|
-
else
|
195
|
-
File.join(File.dirname(remote_repo), @group + '.git')
|
196
|
-
end
|
180
|
+
type = git_type opt
|
181
|
+
return nil unless type
|
182
|
+
|
183
|
+
remote_repo = Oxidized.config.output.send(type).repo
|
184
|
+
if remote_repo.is_a?(::String)
|
185
|
+
if Oxidized.config.output.send(type).single_repo? || @group.nil?
|
186
|
+
remote_repo
|
197
187
|
else
|
198
|
-
remote_repo
|
188
|
+
File.join(File.dirname(remote_repo), @group + '.git')
|
199
189
|
end
|
200
190
|
else
|
201
|
-
|
191
|
+
remote_repo[@group]
|
202
192
|
end
|
203
193
|
end
|
204
194
|
|
@@ -237,12 +227,11 @@ module Oxidized
|
|
237
227
|
value
|
238
228
|
end
|
239
229
|
|
240
|
-
def
|
241
|
-
|
242
|
-
|
230
|
+
def git_type opt
|
231
|
+
type = opt[:output] || Oxidized.config.output.default
|
232
|
+
return nil unless type[0..2] == "git"
|
243
233
|
|
244
|
-
|
245
|
-
(opt[:output] || Oxidized.config.output.default) == 'gitcrypt'
|
234
|
+
type
|
246
235
|
end
|
247
236
|
end
|
248
237
|
end
|
data/lib/oxidized/nodes.rb
CHANGED
@@ -16,6 +16,7 @@ module Oxidized
|
|
16
16
|
nodes.each do |node|
|
17
17
|
# we want to load specific node(s), not all of them
|
18
18
|
next unless node_want? node_want, node
|
19
|
+
|
19
20
|
begin
|
20
21
|
_node = Node.new node
|
21
22
|
new.push _node
|
@@ -32,6 +33,7 @@ module Oxidized
|
|
32
33
|
|
33
34
|
def node_want? node_want, node
|
34
35
|
return true unless node_want
|
36
|
+
|
35
37
|
node_want_ip = (IPAddr.new(node_want) rescue false)
|
36
38
|
name_is_ip = (IPAddr.new(node[:name]) rescue false)
|
37
39
|
if name_is_ip and node_want_ip == node[:name]
|
@@ -173,6 +175,7 @@ module Oxidized
|
|
173
175
|
node = find { |n| n.name == node_name }
|
174
176
|
output = node.output.new
|
175
177
|
raise Oxidized::NotSupported unless output.respond_to? :fetch
|
178
|
+
|
176
179
|
yield node, output
|
177
180
|
end
|
178
181
|
end
|
data/lib/oxidized/output/git.rb
CHANGED
@@ -167,7 +167,7 @@ module Oxidized
|
|
167
167
|
|
168
168
|
begin
|
169
169
|
repo = Rugged::Repository.new repo
|
170
|
-
update_repo repo, file, data
|
170
|
+
update_repo repo, file, data
|
171
171
|
rescue Rugged::OSError, Rugged::RepositoryError => open_error
|
172
172
|
begin
|
173
173
|
Rugged::Repository.init_at repo, :bare
|
@@ -178,27 +178,24 @@ module Oxidized
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
-
def update_repo repo, file, data
|
181
|
+
def update_repo repo, file, data
|
182
|
+
oid_old = repo.blob_at(repo.head.target_id, file) rescue nil
|
183
|
+
return false if oid_old and oid_old.content == data
|
184
|
+
|
182
185
|
oid = repo.write data, :blob
|
183
186
|
index = repo.index
|
184
|
-
index.
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
:parents => repo.empty? ? [] : [repo.head.target].compact,
|
197
|
-
:update_ref => 'HEAD',)
|
198
|
-
|
199
|
-
index.write
|
200
|
-
true
|
201
|
-
end
|
187
|
+
index.add path: file, oid: oid, mode: 0100644
|
188
|
+
|
189
|
+
repo.config['user.name'] = @user
|
190
|
+
repo.config['user.email'] = @email
|
191
|
+
@commitref = Rugged::Commit.create(repo,
|
192
|
+
tree: index.write_tree(repo),
|
193
|
+
message: @msg,
|
194
|
+
parents: repo.empty? ? [] : [repo.head.target].compact,
|
195
|
+
update_ref: 'HEAD')
|
196
|
+
|
197
|
+
index.write
|
198
|
+
true
|
202
199
|
end
|
203
200
|
end
|
204
201
|
end
|
@@ -4,7 +4,7 @@ module Oxidized
|
|
4
4
|
begin
|
5
5
|
require 'git'
|
6
6
|
rescue LoadError
|
7
|
-
raise OxidizedError, 'git not found: sudo gem install
|
7
|
+
raise OxidizedError, 'git not found: sudo gem install git'
|
8
8
|
end
|
9
9
|
|
10
10
|
attr_reader :commitref
|
@@ -99,6 +99,7 @@ module Oxidized
|
|
99
99
|
else
|
100
100
|
File.read path
|
101
101
|
end
|
102
|
+
|
102
103
|
lock repo
|
103
104
|
rescue
|
104
105
|
'node not found'
|
data/lib/oxidized/output/http.rb
CHANGED
@@ -14,28 +14,19 @@ module Oxidized
|
|
14
14
|
raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
17
18
|
require "net/http"
|
18
19
|
require "uri"
|
19
20
|
require "json"
|
21
|
+
|
20
22
|
def store node, outputs, opt = {}
|
21
23
|
@commitref = nil
|
22
|
-
json = JSON.pretty_generate(
|
23
|
-
{
|
24
|
-
'msg' => opt[:msg],
|
25
|
-
'user' => opt[:user],
|
26
|
-
'email' => opt[:email],
|
27
|
-
'group' => opt[:group],
|
28
|
-
'node' => node,
|
29
|
-
'config' => outputs.to_cfg,
|
30
|
-
# actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
|
31
|
-
}
|
32
|
-
)
|
33
24
|
uri = URI.parse @cfg.url
|
34
25
|
http = Net::HTTP.new uri.host, uri.port
|
35
26
|
# http.use_ssl = true if uri.scheme = 'https'
|
36
27
|
req = Net::HTTP::Post.new(uri.request_uri, initheader = { 'Content-Type' => 'application/json' })
|
37
28
|
req.basic_auth @cfg.user, @cfg.password
|
38
|
-
req.body =
|
29
|
+
req.body = generate_json(node, outputs, opt)
|
39
30
|
response = http.request req
|
40
31
|
|
41
32
|
case response.code.to_i
|
@@ -50,5 +41,21 @@ module Oxidized
|
|
50
41
|
Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
|
51
42
|
end
|
52
43
|
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def generate_json node, outputs, opt
|
48
|
+
JSON.pretty_generate(
|
49
|
+
{
|
50
|
+
'msg' => opt[:msg],
|
51
|
+
'user' => opt[:user],
|
52
|
+
'email' => opt[:email],
|
53
|
+
'group' => opt[:group],
|
54
|
+
'node' => node,
|
55
|
+
'config' => outputs.to_cfg,
|
56
|
+
# actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
|
57
|
+
}
|
58
|
+
)
|
59
|
+
end
|
53
60
|
end
|
54
61
|
end
|
data/lib/oxidized/source/csv.rb
CHANGED
@@ -20,17 +20,12 @@ module Oxidized
|
|
20
20
|
|
21
21
|
def load _node_want = nil
|
22
22
|
nodes = []
|
23
|
-
|
24
|
-
file = if @cfg.gpg?
|
25
|
-
crypto = GPGME::Crypto.new password: @cfg.gpg_password
|
26
|
-
file = crypto.decrypt(File.open(file)).to_s
|
27
|
-
else
|
28
|
-
open(file)
|
29
|
-
end
|
30
|
-
file.each_line do |line|
|
23
|
+
open_file.each_line do |line|
|
31
24
|
next if line.match(/^\s*#/)
|
25
|
+
|
32
26
|
data = line.chomp.split(@cfg.delimiter, -1)
|
33
27
|
next if data.empty?
|
28
|
+
|
34
29
|
# map node parameters
|
35
30
|
keys = {}
|
36
31
|
@cfg.map.each do |key, position|
|
@@ -49,5 +44,17 @@ module Oxidized
|
|
49
44
|
end
|
50
45
|
nodes
|
51
46
|
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def open_file
|
51
|
+
file = File.expand_path(@cfg.file)
|
52
|
+
if @cfg.gpg?
|
53
|
+
crypto = GPGME::Crypto.new password: @cfg.gpg_password
|
54
|
+
crypto.decrypt(File.open(file)).to_s
|
55
|
+
else
|
56
|
+
open(file)
|
57
|
+
end
|
58
|
+
end
|
52
59
|
end
|
53
60
|
end
|
data/lib/oxidized/source/http.rb
CHANGED
@@ -12,36 +12,17 @@ module Oxidized
|
|
12
12
|
end
|
13
13
|
|
14
14
|
require "net/http"
|
15
|
+
require "net/https"
|
15
16
|
require "uri"
|
16
17
|
require "json"
|
17
18
|
|
18
19
|
def load node_want = nil
|
19
20
|
nodes = []
|
20
|
-
|
21
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
22
|
-
http.use_ssl = true if uri.scheme == 'https'
|
23
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
|
24
|
-
|
25
|
-
# map headers
|
26
|
-
headers = {}
|
27
|
-
@cfg.headers.each do |header, value|
|
28
|
-
headers[header] = value
|
29
|
-
end
|
30
|
-
|
31
|
-
req_uri = uri.request_uri
|
32
|
-
if node_want
|
33
|
-
req_uri = "#{req_uri}/#{node_want}"
|
34
|
-
end
|
35
|
-
request = Net::HTTP::Get.new(req_uri, headers)
|
36
|
-
if (@cfg.user? && @cfg.pass?)
|
37
|
-
request.basic_auth(@cfg.user, @cfg.pass)
|
38
|
-
end
|
39
|
-
|
40
|
-
response = http.request(request)
|
41
|
-
data = JSON.parse(response.body)
|
21
|
+
data = JSON.parse(read_http(node_want))
|
42
22
|
data = string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
|
43
23
|
data.each do |node|
|
44
24
|
next if node.empty?
|
25
|
+
|
45
26
|
# map node parameters
|
46
27
|
keys = {}
|
47
28
|
@cfg.map.each do |key, want_position|
|
@@ -72,5 +53,28 @@ module Oxidized
|
|
72
53
|
end
|
73
54
|
object
|
74
55
|
end
|
56
|
+
|
57
|
+
def read_http node_want
|
58
|
+
uri = URI.parse(@cfg.url)
|
59
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
60
|
+
http.use_ssl = true if uri.scheme == 'https'
|
61
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
|
62
|
+
|
63
|
+
# map headers
|
64
|
+
headers = {}
|
65
|
+
@cfg.headers.each do |header, value|
|
66
|
+
headers[header] = value
|
67
|
+
end
|
68
|
+
|
69
|
+
req_uri = uri.request_uri
|
70
|
+
if node_want
|
71
|
+
req_uri = "#{req_uri}/#{node_want}"
|
72
|
+
end
|
73
|
+
request = Net::HTTP::Get.new(req_uri, headers)
|
74
|
+
if (@cfg.user? && @cfg.pass?)
|
75
|
+
request.basic_auth(@cfg.user, @cfg.pass)
|
76
|
+
end
|
77
|
+
http.request(request).body
|
78
|
+
end
|
75
79
|
end
|
76
80
|
end
|
data/lib/oxidized/string.rb
CHANGED
@@ -4,13 +4,18 @@ module Oxidized
|
|
4
4
|
attr_accessor :type, :cmd, :name
|
5
5
|
|
6
6
|
# @return [Oxidized::String] copy of self with last line removed
|
7
|
-
def cut_tail
|
8
|
-
Oxidized::String.new each_line.to_a[0..-
|
7
|
+
def cut_tail lines = 1
|
8
|
+
Oxidized::String.new each_line.to_a[0..-1 - lines].join
|
9
9
|
end
|
10
10
|
|
11
11
|
# @return [Oxidized::String] copy of self with first line removed
|
12
|
-
def cut_head
|
13
|
-
Oxidized::String.new each_line.to_a[
|
12
|
+
def cut_head lines = 1
|
13
|
+
Oxidized::String.new each_line.to_a[lines..-1].join
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Oxidized::String] copy of self with first and last lines removed
|
17
|
+
def cut_both head = 1, tail = 1
|
18
|
+
Oxidized::String.new each_line.to_a[head..-1 - tail].join
|
14
19
|
end
|
15
20
|
|
16
21
|
# sets @cmd and @name unless @name is already set
|
data/lib/oxidized/version.rb
CHANGED
data/lib/oxidized/worker.rb
CHANGED
@@ -28,8 +28,9 @@ module Oxidized
|
|
28
28
|
# shift nodes and get the next node
|
29
29
|
node = @nodes.get
|
30
30
|
node.running? ? next : node.running = true
|
31
|
+
|
31
32
|
@jobs.push Job.new node
|
32
|
-
Oxidized.logger.debug "lib/oxidized/worker.rb: Added #{node.name} to the job queue"
|
33
|
+
Oxidized.logger.debug "lib/oxidized/worker.rb: Added #{node.group}/#{node.name} to the job queue"
|
33
34
|
end
|
34
35
|
|
35
36
|
run_done_hook if is_cycle_finished?
|
@@ -42,49 +43,56 @@ module Oxidized
|
|
42
43
|
node.stats.add job
|
43
44
|
@jobs.duration job.time
|
44
45
|
node.running = false
|
45
|
-
|
46
46
|
if job.status == :success
|
47
|
-
|
48
|
-
Oxidized.Hooks.handle :node_success, :node => node,
|
49
|
-
:job => job
|
50
|
-
msg = "update #{node.name}"
|
51
|
-
msg += " from #{node.from}" if node.from
|
52
|
-
msg += " with message '#{node.msg}'" if node.msg
|
53
|
-
output = node.output.new
|
54
|
-
if output.store node.name, job.config,
|
55
|
-
:msg => msg, :email => node.email, :user => node.user, :group => node.group
|
56
|
-
node.modified
|
57
|
-
Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
|
58
|
-
Oxidized.Hooks.handle :post_store, :node => node,
|
59
|
-
:job => job,
|
60
|
-
:commitref => output.commitref
|
61
|
-
end
|
62
|
-
node.reset
|
47
|
+
process_success node, job
|
63
48
|
else
|
64
|
-
|
65
|
-
if node.retry < Oxidized.config.retries
|
66
|
-
node.retry += 1
|
67
|
-
msg += ", retry attempt #{node.retry}"
|
68
|
-
@nodes.next node.name
|
69
|
-
else
|
70
|
-
# Only increment the @jobs_done when we give up retries for a node (or success).
|
71
|
-
# As it would otherwise cause @jobs_done to be incremented with generic retries.
|
72
|
-
# This would cause :nodes_done hook to desync from running at the end of the nodelist and
|
73
|
-
# be fired when the @jobs_done > @nodes.count (could be mid-cycle on the next cycle).
|
74
|
-
@jobs_done += 1
|
75
|
-
msg += ", retries exhausted, giving up"
|
76
|
-
node.retry = 0
|
77
|
-
Oxidized.Hooks.handle :node_fail, :node => node,
|
78
|
-
:job => job
|
79
|
-
end
|
80
|
-
Oxidized.logger.warn msg
|
49
|
+
process_failure node, job
|
81
50
|
end
|
82
51
|
rescue NodeNotFound
|
83
|
-
Oxidized.logger.warn "#{node.name} not found, removed while collecting?"
|
52
|
+
Oxidized.logger.warn "#{node.group}/#{node.name} not found, removed while collecting?"
|
84
53
|
end
|
85
54
|
|
86
55
|
private
|
87
56
|
|
57
|
+
def process_success node, job
|
58
|
+
@jobs_done += 1 # needed for :nodes_done hook
|
59
|
+
Oxidized.Hooks.handle :node_success, node: node,
|
60
|
+
job: job
|
61
|
+
msg = "update #{node.group}/#{node.name}"
|
62
|
+
msg += " from #{node.from}" if node.from
|
63
|
+
msg += " with message '#{node.msg}'" if node.msg
|
64
|
+
output = node.output.new
|
65
|
+
if output.store node.name, job.config,
|
66
|
+
msg: msg, email: node.email, user: node.user, group: node.group
|
67
|
+
node.modified
|
68
|
+
Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
|
69
|
+
Oxidized.Hooks.handle :post_store, node: node,
|
70
|
+
job: job,
|
71
|
+
commitref: output.commitref
|
72
|
+
end
|
73
|
+
node.reset
|
74
|
+
end
|
75
|
+
|
76
|
+
def process_failure node, job
|
77
|
+
msg = "#{node.group}/#{node.name} status #{job.status}"
|
78
|
+
if node.retry < Oxidized.config.retries
|
79
|
+
node.retry += 1
|
80
|
+
msg += ", retry attempt #{node.retry}"
|
81
|
+
@nodes.next node.name
|
82
|
+
else
|
83
|
+
# Only increment the @jobs_done when we give up retries for a node (or success).
|
84
|
+
# As it would otherwise cause @jobs_done to be incremented with generic retries.
|
85
|
+
# This would cause :nodes_done hook to desync from running at the end of the nodelist and
|
86
|
+
# be fired when the @jobs_done > @nodes.count (could be mid-cycle on the next cycle).
|
87
|
+
@jobs_done += 1
|
88
|
+
msg += ", retries exhausted, giving up"
|
89
|
+
node.retry = 0
|
90
|
+
Oxidized.Hooks.handle :node_fail, :node => node,
|
91
|
+
:job => job
|
92
|
+
end
|
93
|
+
Oxidized.logger.warn msg
|
94
|
+
end
|
95
|
+
|
88
96
|
def is_cycle_finished?
|
89
97
|
if @jobs_done > @nodes.count
|
90
98
|
true
|