Created
September 30, 2015 13:39
-
-
Save nod0n/d01024a5b6aecab2b1c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'zabbixapi' | |
require 'json' | |
require 'yaml' | |
require 'nokogiri' | |
require 'fileutils' | |
class ZabbixSync < ZabbixApi | |
RULES = { | |
templates: {createMissing: true, updateExisting: true}, | |
applications: { | |
createMissing: true, | |
updateExisting: true, | |
deleteMissing: true | |
}, | |
items: { | |
createMissing: true, | |
updateExisting: true, | |
deleteMissing: true | |
}, | |
triggers: { | |
createMissing: true, | |
updateExisting: true, | |
deleteMissing: true | |
}, | |
graphs: { | |
createMissing: true, | |
updateExisting: true, | |
deleteMissing: true | |
}, | |
templateScreens: {createMissing: true, updateExisting: true}, | |
discoveryRules: { | |
createMissing: true, | |
updateExisting: true, | |
deleteMissing: true | |
}, | |
templateLinkage: {createMissing: true}, | |
groups: {createMissing: true} | |
} | |
TEMPLATES_DIR = '/srv/zabbixsync_data' | |
TEMPLATES_INDEX_FILE = "templates.yaml" | |
CONNECTION = { | |
url: "http://localhost/zabbix/api_jsonrpc.php", | |
user: "Admin", | |
password: "zabbix" | |
} | |
TEMPLATES_LIST_FILE = '/usr/local/etc/zabbix_sync.conf' | |
EXPORT_TYPE = 'xml' | |
attr_reader( | |
:connection, | |
:templates_index, | |
:templates_index_file, | |
:templates_dir, | |
:templates_list_file, | |
:templates_white_list, | |
:templates_black_list, | |
:rules, | |
:templates_data | |
) | |
def initialize(options = {}) | |
@export_format = EXPORT_TYPE | |
@imported_templates = [] | |
@connection = CONNECTION | |
@templates_index_file = TEMPLATES_INDEX_FILE | |
@templates_dir = TEMPLATES_DIR | |
@templates_list_file = TEMPLATES_LIST_FILE | |
@rules = RULES | |
set_connection options | |
set_templates_index options | |
set_templates options | |
set_templates_list options | |
set_rules options | |
super @connection | |
end | |
def has_field(hash, field, type = nil) | |
if hash.is_a?(Hash) and hash.key?(field) | |
if type.is_a?(NilClass) | |
true | |
else | |
hash[field].is_a?(type) and ! hash[field].empty? | |
end | |
else | |
false | |
end | |
end | |
def make_filename(name) | |
### filenames contain the number of a template ( <= @templates_index) | |
if @templates_index.key?(name) | |
"#{@templates_dir}/%06d" % @templates_index[name] | |
else | |
abort("template #{name} not found in templates index") | |
end | |
end | |
def load_connection(connection) | |
if has_field(connection, :file, String) | |
puts 'file:' | |
puts connection[:file] | |
puts | |
@connection = YAML.load(File.read connection[:file]) | |
puts 'connection:' | |
puts @connection | |
puts | |
end | |
end | |
def set_connection_field(connection, field, type = String) | |
if has_field(connection, field, type) | |
@connection[field] = connection[field] | |
end | |
end | |
def set_connection(options) | |
if has_field(options, :connection) | |
load_connection(options[:connection]) | |
set_connection_field(options[:connection], :url) | |
set_connection_field(options[:connection], :user) | |
set_connection_field(options[:connection], :password) | |
end | |
end | |
def set_templates_index(options) | |
if has_field(options, :templates_index) | |
index = options[:templates_index] | |
@templates_index_file = index[:file] if has_field(index, :file, String) | |
@templates_index = index[:index] if has_field(index, :index, Hash) | |
end | |
@templates_index = {} unless @templates_index | |
end | |
def set_templates(options) | |
if has_field(options, :templates) | |
templates = options[:templates] | |
if has_field(templates, :directory, String) | |
@templates_dir = templates[:directory] | |
end | |
if has_field(templates, :templates, Array) | |
@templates_data = templates[:templates] | |
end | |
end | |
@templates_data = [] unless @templates_data | |
end | |
def set_templates_list(options) | |
if has_field(options, :templates_list) | |
templates_names = options[:templates_list] | |
if has_field(templates_names, :file, String) | |
@templates_list_file = templates_names[:file] | |
end | |
if has_field(templates_names, :white_list, Array) | |
@templates_white_list = templates_names[:white_list] | |
end | |
if has_field(templates_names, :black_list, Array) | |
@templates_black_list = templates_names[:black_list] | |
end | |
end | |
@templates_list_file = '' unless @templates_list_file | |
@templates_white_list = [] unless @templates_white_list | |
@templates_black_list = [] unless @templates_black_list | |
end | |
def set_rules(options) | |
@rules = options[:rules] if has_field(options, :rules) | |
end | |
def list_templates(ids = templates.get_ids_by_host(filter: "")) | |
client.api_request( | |
method: "template.get", | |
params: {templateids: ids} | |
).map do |template| | |
template['host'] | |
end | |
end | |
def export_templates(templates_names = list_templates) | |
@templates_data = {} | |
templates_names.each do |name| | |
id = [templates.get_id(host: name)] | |
@templates_data[name] = configurations.export( | |
format: @export_format, | |
options: {templates: id} | |
) | |
end | |
@templates_data.length | |
end | |
def gen_templates_index(templates_names = list_templates) | |
@templates_index = {} | |
number = 0 | |
templates_names.each do |name| | |
@templates_index[name] = number | |
number += 1 | |
end | |
@templates_index | |
end | |
def write_templates_index( | |
templates_dir = @templates_dir, | |
templates_index_file = @templates_index_file, | |
templates_index = @templates_index | |
) | |
FileUtils.mkdir_p(templates_dir) | |
File.write( | |
"#{templates_dir}/#{templates_index_file}", | |
templates_index.to_yaml | |
) | |
end | |
def write_templates_data | |
FileUtils.mkdir_p(@templates_dir) | |
@templates_index.each do |name, number| | |
if @templates_data.key? name | |
doc = Nokogiri::XML.parse(@templates_data[name]) | |
File.write(make_filename(name), doc) | |
else | |
abort "Template name not found" | |
end | |
end | |
end | |
def read_templates_list(file = @templates_list_file) | |
if File.exists? file | |
content = YAML.load(File.read file) | |
if has_field(content, :blacklist, Array) | |
@templates_black_list += content[:blacklist] | |
end | |
if has_field(content, :whitelist, Array) | |
@templates_white_list += content[:whitelist] | |
end | |
else | |
abort("templates list file not found") | |
end | |
{ | |
'blacklist' => @templates_black_list, | |
'whitelist' => @templates_white_list | |
} | |
end | |
def read_templates_index(file = "#{@templates_dir}/#{@templates_index_file}") | |
if File.exists?(file) | |
content = YAML.load(File.read file) | |
@templates_index = content.merge(@templates_index) if content.is_a?(Hash) | |
else | |
abort("templates index file not found") | |
end | |
end | |
def import_template(name) | |
read_templates_index if @templates_index.empty? | |
if @imported_templates.include?(name) | |
abort("template alredy imported") | |
else | |
data = File.read(make_filename name) | |
configurations.import( | |
format: @export_format, | |
rules: @rules, | |
source: data | |
) | |
@imported_templates << name | |
end | |
{'imported templates' => @imported_templates} | |
end | |
def list_dependencies(name) | |
read_templates_index if @templates_index.empty? | |
file = File.new(make_filename name) | |
Nokogiri::XML(file) | |
.xpath("//zabbix_export//templates//template//templates//template//name") | |
.map(&:text) | |
end | |
def import_recursive(name) | |
list_dependencies(name).each do |dependency| | |
unless @imported_templates.include?(dependency) | |
import_recursive(dependency) | |
end | |
end | |
import_template(name) unless @imported_templates.include?(name) | |
end | |
def gen_import_list | |
read_templates_index if @templates_index.empty? | |
if @templates_white_list.empty? | |
if @templates_black_list.empty? | |
@templates_index.keys | |
else | |
@templates_index.keys - @templates_black_list | |
end | |
else | |
@templates_white_list & @templates_index.keys | |
end | |
end | |
def import_templates(templates = gen_import_list) | |
@imported_templates = [] | |
templates.each { |name| import_recursive(name) } | |
end | |
def import(options = {}) | |
unless options.empty? | |
set_templates_index options | |
set_templates options | |
set_templates_list options | |
set_rules options | |
end | |
read_templates_list | |
read_templates_index | |
import_templates | |
end | |
def export(options = {}) | |
unless options.empty? | |
set_templates_list options | |
end | |
gen_templates_index | |
write_templates_index | |
export_templates | |
write_templates_data | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment