-
Notifications
You must be signed in to change notification settings - Fork 5
/
zbx2git.rb
141 lines (116 loc) · 4.37 KB
/
zbx2git.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env ruby
#
# DESCRIPTION:
# Exports your Zabbix configuration and uses Git to store any changes made from the previous runs
#
#
# LICENSE:
# Copyright 2016 Sebastian YEPES <[email protected]>
# Released under the Apache License, see LICENSE for details.
#
require 'logger'
require 'json'
require 'parallel'
require 'fileutils'
require "zabbixapi"
require 'git'
require 'openssl'
PATH_CURRENT = Dir.pwd()
def secs2human(secs)
[[60, :seconds], [60, :minutes], [24, :hours], [1000, :days]].map{|count, name|
if secs > 0
secs, n = secs.divmod(count)
"#{n.to_i} #{name}"
end
}.compact.reverse.join(' ')
end
def exportConfig(logger, inst, zbx, cfg)
begin
ts_s = Time.now.to_i
path = "#{PATH_CURRENT}/repository/#{inst}/#{cfg[:type]}"
logger.info "Start Exporting: #{cfg[:type]} (#{inst})"
results = zbx.query(
:method => cfg[:method],
:params => {:output => cfg[:output], :sortorder => cfg[:sortorder]}
)
# Clean previously exported files
FileUtils.rm_f(Dir.glob("#{path}/*"))
for result in results do
begin
# File name normalization
file = "#{result["name"].gsub(/[^a-zA-Z0-9\-_\s\.\(\)]/,'')}.json"
logger.debug "#{path}/#{file}"
json = JSON.parse(zbx.query(
:method => "configuration.export",
:params => {
:options => {
cfg[:type] => [ result[cfg[:id]] ],
},
:format => 'json'
}
))
# Clear export date to prevent unnecessary git changes
json["zabbix_export"]["date"] = ""
json_pretty = JSON.pretty_generate(json)
FileUtils.mkdir_p(path) unless File.exists?(path)
File.open("#{path}/#{file}","w"){|f| f.puts json_pretty}
rescue Exception => e
logger.error "Exporting: #{cfg[:type]} (#{inst}) : #{e.message}"
logger.debug "Trace: #{e.backtrace.inspect}"
end
end
begin
if !File.exists?("#{path}/.git")
g = Git.init(path, :log => logger)
g.add(:all=>true)
m = g.commit_all('initial')
logger.debug "Git (Init): #{m}" if m != nil
File.open("#{path}/.git/description","w"){|f| f.puts "#{inst} - #{cfg[:type]}"}
else
g = Git.open(path, :log => $logger)
g.add(:all=>true)
any_change = ["changed","added","deleted"].map{|x| x if !g.status.send(x.to_sym).empty?}.compact.delete_if(&:empty?)
if !any_change.empty?
logger.warn "Detected changes: (#{any_change.join(', ')}) in #{cfg[:type]} (#{inst})"
end
m = g.commit_all("#{any_change.join(', ')}") if !any_change.empty?
logger.debug "Git (#{any_change.join(', ')}): #{m}" if m != nil
end
rescue Exception => e
logger.error "Saving changes to git: #{cfg[:type]} (#{inst}) : #{e.message}"
end
logger.info "Finished Exporting: #{cfg[:type]} (#{inst}) in #{secs2human(Time.now.to_i - ts_s)}"
rescue Exception => e
logger.error "Exporting: #{cfg[:type]} (#{inst}) : #{e.message}"
logger.debug "Trace: #{e.backtrace.inspect}"
end
end
FileUtils.mkdir_p("#{PATH_CURRENT}/logs") unless File.exists?("#{PATH_CURRENT}/logs")
log = Logger.new("#{PATH_CURRENT}/logs/zbx2git.log", 'monthly')
log.level = Logger::INFO
begin
cfg = JSON.parse(File.read('zbx2git.json'), :symbolize_names => true)
rescue Exception => e
log.error "Error Loading config file: zbx2git.json : #{e.message}"
log.debug "Trace: #{e.backtrace.inspect}"
exit 1
end
log.info "Start Collecting of instances: #{cfg[:zabbix_cfg].map{|i| i[:inst] }.join(', ')}"
ts_s = Time.now.to_i
Parallel.each(cfg[:zabbix_cfg], in_processes: 8) { |zab_cfg|
logger = Logger.new("#{PATH_CURRENT}/logs/zbx2git_#{zab_cfg[:inst]}.log", 'monthly')
logger.level = Logger::INFO
begin
ts_s = Time.now.to_i
logger.info "Start Collecting: #{zab_cfg[:inst]} - #{zab_cfg[:url]}"
zbx = ZabbixApi.connect(:url => zab_cfg[:url], :user => zab_cfg[:user], :password => zab_cfg[:password], :timeout => 15)
for exp_cfg in cfg[:export_cfg] do
exportConfig(logger, zab_cfg[:inst], zbx, exp_cfg)
end
logger.info "Finished Collecting: #{zab_cfg[:inst]} in #{secs2human(Time.now.to_i - ts_s)}"
rescue Exception => e
logger.error "Connecting to Zabbix: #{zab_cfg[:inst]} : #{e.message}"
logger.debug "Trace: #{e.backtrace.inspect}"
end
}
log.info "Completed in #{secs2human(Time.now.to_i - ts_s)}"