oxidized 0.24.0 → 0.25.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/.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
|