zapix3 0.1.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.
@@ -0,0 +1,77 @@
1
+ require_relative 'base'
2
+ class Hosts < Base
3
+
4
+ def get_id(name)
5
+ if(exists?(name))
6
+ client.host_get({'filter' => {'host' => name}}).first['hostid']
7
+ else
8
+ raise NonExistingHost, "Host #{name} does not exist !"
9
+ end
10
+ end
11
+
12
+ def create(options={})
13
+ client.host_create(options) unless exists?(options["host"])
14
+ end
15
+
16
+ def create_or_update(options={})
17
+ raise EmptyHostname, 'Host name cannot be empty !' if options['host'].nil?
18
+ if exists?(options['host'])
19
+ id = get_id(options['host'])
20
+ options.merge!('hostid' => id)
21
+ client.host_update(options)
22
+ else
23
+ create(options)
24
+ end
25
+ end
26
+
27
+ def unlink_and_clear_templates(options={})
28
+ template_ids = options['template_ids'].map { |id| {'templateid' => id}}
29
+ client.host_update({'hostid' => options['host_id'], 'templates_clear' => template_ids})
30
+ end
31
+
32
+ def update_templates(options={})
33
+ template_ids = options['template_ids'].map { |id| {'templateid' => id}}
34
+ client.host_update({'hostid' => options['host_id'], 'templates' => template_ids})
35
+ end
36
+
37
+ def update_macros(options={})
38
+ client.host_update('hostid' => options['host_id'], 'macros' => options['macros'])
39
+ end
40
+
41
+ def exists?(name)
42
+ result = client.host_get({'filter' => {'host' => name}})
43
+ if (result == nil || result.empty?)
44
+ false
45
+ else
46
+ true
47
+ end
48
+ end
49
+
50
+ def get_all
51
+ host_names_and_ids = client.host_get({'output' => ['name']})
52
+
53
+ # the fucking api ALWAYS returns the ids and that's
54
+ # why we need to extract the names separately
55
+
56
+ extract_host_names(host_names_and_ids)
57
+ end
58
+
59
+ def delete(name)
60
+ if exists?(name)
61
+ client.host_delete([get_id(name)])
62
+ else
63
+ raise NonExistingHost, "Host #{name} cannot be deleted because it does not exist !"
64
+ end
65
+ end
66
+
67
+ class NonExistingHost < StandardError; end
68
+ class EmptyHostname < StandardError; end
69
+
70
+ private
71
+
72
+ def extract_host_names(hosts_and_ids)
73
+ hosts_and_ids.map do |current_host|
74
+ current_host['name']
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'base'
2
+
3
+ class Scenarios < Base
4
+ def create(options)
5
+ client.httptest_create(options) unless exists?(options)
6
+ end
7
+
8
+ def get_id(options)
9
+ client.httptest_get({
10
+ 'filter' => {'name' => options['name'], 'hostid' => options['hostid']}}).first['httptestid']
11
+ end
12
+
13
+ def delete(options)
14
+ client.httptest_delete(options)
15
+ end
16
+
17
+ def exists?(options)
18
+ result = client.httptest_get({
19
+ 'countOutput' => true,
20
+ 'filter' => {'name' => options['name'],
21
+ 'hostid' => options['hostid']}})
22
+
23
+ result.to_i >= 1 ? true : false
24
+ end
25
+
26
+ def get_all
27
+ scenarios = client.httptest_get({'output' => 'extend'})
28
+ names = extract_names(scenarios)
29
+ end
30
+
31
+ def extract_names(scenarios)
32
+ scenarios.map {|scenario| scenario['name']}
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'base'
2
+ class Templates < Base
3
+
4
+ def exists?(name)
5
+ result = client.template_get({'filter' => {'name' => name}})
6
+ if (result == nil || result.empty?)
7
+ false
8
+ else
9
+ true
10
+ end
11
+ end
12
+
13
+ def create(options)
14
+ client.template_create(options) unless exists?(options['host'])
15
+ end
16
+
17
+ def get_id(name)
18
+ if(exists?(name))
19
+ client.template_get({'filter' => {'name' => name}}).first['templateid']
20
+ else
21
+ raise NonExistingTemplate, "Template #{name} does not exist !"
22
+ end
23
+ end
24
+
25
+ def get_templates_for_host(id)
26
+ client.template_get({'hostids' => [id]}).map { |result_set| result_set['templateid'] }
27
+ end
28
+
29
+ class NonExistingTemplate < StandardError; end
30
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'base'
2
+ class Triggers < Base
3
+
4
+ def create(options)
5
+ client.trigger_create(options)
6
+ end
7
+
8
+ def delete(*trigger_ids)
9
+ client.trigger_delete(trigger_ids)
10
+ end
11
+
12
+ def get_id(options)
13
+ result = client.trigger_get({'output' => 'extend',
14
+ 'expandExpression' => true})
15
+ id = extract_id(result, options['expression'])
16
+ unless id.nil?
17
+ id
18
+ else
19
+ raise NonExistingTrigger, "Trigger with expression #{options['expression']} not found."
20
+ end
21
+ end
22
+
23
+ class NonExistingTrigger < StandardError; end
24
+
25
+ private
26
+
27
+ def extract_id(triggers, expression)
28
+ result = nil
29
+ triggers.each do |trigger|
30
+ if trigger['expression'] == expression
31
+ result = trigger['triggerid']
32
+ break
33
+ end
34
+ end
35
+ result
36
+ end
37
+
38
+ end
39
+
40
+
@@ -0,0 +1,35 @@
1
+ require_relative 'base'
2
+
3
+ class Usergroups < Base
4
+
5
+ def create(options)
6
+ client.usergroup_create(options) unless exists?(options)
7
+ end
8
+
9
+ def exists?(options)
10
+ #client.usergroup_exists(options)
11
+ result = client.usergroup_get({'filter' => {'name' => options['name']}})
12
+ if result.empty? || result == nil
13
+ false
14
+ else
15
+ true
16
+ end
17
+ end
18
+
19
+ def get_id(options)
20
+ if(exists?(options))
21
+ result = client.usergroup_get({
22
+ 'filter' => {'name' => options['name']}})
23
+ result.first['usrgrpid']
24
+ else
25
+ raise NonExistingUsergroup, "Usergroup #{options['name']} does not exist !"
26
+ end
27
+ end
28
+
29
+ def delete(*group_ids)
30
+ client.usergroup_delete(group_ids)
31
+ end
32
+
33
+ class NonExistingUsergroup < StandardError; end
34
+
35
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'base'
2
+
3
+ class Users < Base
4
+ def create(options)
5
+ client.user_create(options) unless exists?(options)
6
+ end
7
+
8
+ def exists?(options)
9
+ result = client.user_get({'filter' => {'alias' => options['alias']}})
10
+ result.empty? ? false : true
11
+ end
12
+
13
+ def get_id(options)
14
+ if(exists?(options))
15
+ client.user_get({'filter' => {'alias' => options['alias']}}).first['userid']
16
+ else
17
+ raise NonExistingUser, "User #{options['alias']} does not exist !"
18
+ end
19
+ end
20
+
21
+ def delete(user_ids)
22
+ client.user_delete(user_ids)
23
+ end
24
+
25
+ class NonExistingUser < StandardError; end
26
+ end
27
+
28
+
@@ -0,0 +1,3 @@
1
+ module Zapix
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,47 @@
1
+ class Host
2
+
3
+ attr_accessor :group_ids, :template_ids, :interfaces, :macros
4
+
5
+ def initialize()
6
+ @group_ids = Array.new
7
+ @template_ids = Array.new
8
+ @interfaces = Array.new
9
+ @macros = Array.new
10
+ @properties = Hash.new
11
+ end
12
+
13
+ def add_name(name)
14
+ @properties.merge!('host' => name)
15
+ end
16
+
17
+ def add_group_ids(*ids)
18
+ ids.each do |id|
19
+ group_ids << {'groupid' => id}
20
+ end
21
+ @properties.merge!('groups' => group_ids)
22
+ end
23
+
24
+ def add_interfaces(*ifaces)
25
+ interfaces.concat(ifaces)
26
+ @properties.merge!('interfaces' => interfaces)
27
+ end
28
+
29
+ def add_template_ids(*ids)
30
+ ids.each do |id|
31
+ template_ids << {'templateid' => id}
32
+ end
33
+ @properties.merge!('templates' => template_ids)
34
+ end
35
+
36
+ def add_macros(*host_macros)
37
+ macros.concat(host_macros)
38
+ @properties.merge!('macros' => host_macros)
39
+ end
40
+
41
+ def to_hash
42
+ @properties
43
+ end
44
+
45
+ end
46
+
47
+
@@ -0,0 +1,42 @@
1
+ require 'active_record'
2
+
3
+ class Interface
4
+ include ActiveModel::Validations
5
+
6
+ attr_reader :type, :main, :useip, :ip, :dns, :port
7
+ validates_presence_of :type, :main, :useip, :ip, :dns, :port
8
+
9
+ # for more info see
10
+ # https://www.zabbix.com/documentation/2.0/manual/appendix/api/hostinterface/definitions#host_interface
11
+ # we assume ip and dns shall always be set
12
+
13
+ validates_inclusion_of :type, :in => 1..4
14
+ validates_inclusion_of :main, :in => 0..1
15
+ validates_inclusion_of :useip, :in => 0..1
16
+
17
+ def initialize(attributes)
18
+ @type = attributes['type'] ||= 1
19
+ @main = attributes['main'] ||= 1
20
+ @useip = attributes['useip'] ||= 1
21
+ @ip = attributes['ip'] = attributes['ip']
22
+ @dns = attributes['dns'] = attributes['dns']
23
+ @port = attributes['port'] = attributes['port'] ||= 10050
24
+ @result = {
25
+ 'type' => type,
26
+ 'main' => main,
27
+ 'useip' => useip,
28
+ 'ip' => ip,
29
+ 'dns' => dns,
30
+ 'port' => port
31
+ }
32
+ end
33
+
34
+ def read_attribute_for_validation(key)
35
+ send(key)
36
+ end
37
+
38
+ def to_hash
39
+ @result
40
+ end
41
+
42
+ end
@@ -0,0 +1,58 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ class ZabbixRPCClient
6
+
7
+ attr_reader :uri, :debug
8
+
9
+ def initialize(options)
10
+ @uri = URI.parse(options[:service_url])
11
+ @username = options[:username]
12
+ @password = options[:password]
13
+ @debug = options[:debug]
14
+ @auth_token = authenticate
15
+ end
16
+
17
+ def method_missing(name, *args)
18
+ method_name = map_name(name)
19
+
20
+ post_body = {
21
+ 'method' => method_name,
22
+ 'params' => args.first,
23
+ 'id' => id,
24
+ 'jsonrpc' => '2.0',
25
+ 'auth' => @auth_token
26
+ }.to_json
27
+
28
+ resp = JSON.parse( http_post_request(post_body) )
29
+ raise JSONRPCError, resp['error'] if resp['error']
30
+ puts "[DEBUG] Get answer: #{resp}" if debug
31
+ resp["result"]
32
+ end
33
+
34
+ def http_post_request(post_body)
35
+ http = Net::HTTP.new(uri.host, uri.port)
36
+ http.use_ssl = true
37
+ request = Net::HTTP::Post.new(uri.request_uri)
38
+ request.content_type = 'application/json'
39
+ request.body = post_body
40
+ puts "[DEBUG] Send request: #{request.body}" if debug
41
+ http.request(request).body
42
+ end
43
+
44
+ def authenticate
45
+ p user_login({'user' => @username, 'password' => @password})
46
+ user_login({'user' => @username, 'password' => @password})
47
+ end
48
+
49
+ def id
50
+ rand(100000)
51
+ end
52
+
53
+ def map_name(name)
54
+ name.to_s.sub('_', '.')
55
+ end
56
+
57
+ class JSONRPCError < RuntimeError; end
58
+ end
data/lib/zapix.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'zapix/version'
2
+ require_relative 'zapix/zabbix_rpc_client'
3
+
4
+ class ZabbixAPI
5
+ attr_reader :client
6
+
7
+ def self.connect(options = {})
8
+ new(options)
9
+ end
10
+
11
+ def initialize(options = {})
12
+ @client = ZabbixRPCClient.new(options)
13
+ Dir["#{File.dirname(__FILE__)}/zapix/zabbix_classes/*.rb"].each { |f| load(f) }
14
+ Dir["#{File.dirname(__FILE__)}/zapix/proxies/*.rb"].each { |f| load(f) }
15
+ end
16
+
17
+ def hostgroups
18
+ @hostgroups ||= HostGroups.new(client)
19
+ end
20
+
21
+ def hosts
22
+ @hosts ||= Hosts.new(client)
23
+ end
24
+
25
+ def templates
26
+ @templates ||= Templates.new(client)
27
+ end
28
+
29
+ def applications
30
+ @applications ||= Applications.new(client)
31
+ end
32
+
33
+ def scenarios
34
+ @scenarios ||= Scenarios.new(client)
35
+ end
36
+
37
+ def triggers
38
+ @triggers ||= Triggers.new(client)
39
+ end
40
+
41
+ def hostinterfaces
42
+ @hostinterfaces ||= Hostinterfaces.new(client)
43
+ end
44
+
45
+ def actions
46
+ @actions ||= Actions.new(client)
47
+ end
48
+
49
+ def usergroups
50
+ @usergroups ||= Usergroups.new(client)
51
+ end
52
+
53
+ def users
54
+ @users ||= Users.new(client)
55
+ end
56
+
57
+ end
@@ -0,0 +1,19 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'zapix'
8
+ RSpec.configure do |config|
9
+
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ end