rubix 0.4.3 → 0.5.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.
- data/VERSION +1 -1
- data/bin/zabbix_api +45 -27
- data/lib/rubix.rb +17 -0
- data/lib/rubix/associations.rb +7 -1
- data/lib/rubix/associations/belongs_to_action.rb +31 -0
- data/lib/rubix/associations/belongs_to_media_type.rb +33 -0
- data/lib/rubix/associations/belongs_to_user.rb +33 -0
- data/lib/rubix/associations/belongs_to_user_group.rb +32 -0
- data/lib/rubix/associations/has_many_conditions.rb +23 -0
- data/lib/rubix/associations/has_many_user_groups.rb +32 -0
- data/lib/rubix/associations/has_many_users.rb +32 -0
- data/lib/rubix/models.rb +17 -10
- data/lib/rubix/models/action.rb +117 -0
- data/lib/rubix/models/application.rb +1 -3
- data/lib/rubix/models/condition.rb +99 -0
- data/lib/rubix/models/host.rb +9 -11
- data/lib/rubix/models/host_group.rb +1 -4
- data/lib/rubix/models/item.rb +12 -27
- data/lib/rubix/models/media_type.rb +19 -21
- data/lib/rubix/models/medium.rb +86 -0
- data/lib/rubix/models/model.rb +53 -1
- data/lib/rubix/models/operation.rb +134 -0
- data/lib/rubix/models/script.rb +49 -0
- data/lib/rubix/models/template.rb +2 -2
- data/lib/rubix/models/trigger.rb +8 -9
- data/lib/rubix/models/user.rb +145 -0
- data/lib/rubix/models/user_group.rb +94 -0
- data/lib/rubix/models/user_macro.rb +10 -20
- data/spec/requests/action_request_spec.rb +45 -0
- data/spec/requests/connection_request_spec.rb +3 -3
- data/spec/requests/media_type_request_spec.rb +8 -8
- data/spec/requests/script_request_spec.rb +54 -0
- data/spec/requests/user_group_request_spec.rb +97 -0
- data/spec/requests/user_request_spec.rb +84 -0
- data/spec/support/integration_helper.rb +105 -33
- data/spec/test.yml +0 -2
- metadata +22 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/bin/zabbix_api
CHANGED
@@ -16,41 +16,59 @@ Settings.define :password, :description => "Password for the Zabbix AP
|
|
16
16
|
Settings.define :server_error_sleep, :description => "Seconds to sleep after a 50x error from the server", :required => true, :type => Integer, :default => 1
|
17
17
|
|
18
18
|
def Settings.usage
|
19
|
-
%Q{usage: #{raw_script_name} [...--param=val...] METHOD PARAMS}
|
19
|
+
%Q{usage: #{raw_script_name} [...--param=val...] [--shell || METHOD PARAMS]}
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
rescue RuntimeError => e
|
25
|
-
puts e.message
|
26
|
-
Settings.dump_help
|
22
|
+
def bail msg=nil
|
23
|
+
$stderr.puts msg if msg
|
27
24
|
exit(1)
|
28
25
|
end
|
29
26
|
|
30
|
-
|
31
|
-
Settings
|
32
|
-
exit(1)
|
27
|
+
def connect
|
28
|
+
Rubix.connect(Settings[:url], Settings[:username], Settings[:password])
|
33
29
|
end
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
31
|
+
def perform_query
|
32
|
+
begin
|
33
|
+
method = Settings.rest[0]
|
34
|
+
params = JSON.parse(Settings.rest[1])
|
35
|
+
response = Rubix.connection.request(method, params)
|
36
|
+
|
37
|
+
if Settings[:pretty]
|
38
|
+
puts JSON.pretty_generate(response.parsed)
|
39
|
+
else
|
40
|
+
puts response.parsed.to_json
|
41
|
+
end
|
42
|
+
exit(0)
|
43
|
+
rescue JSON::ParserError => e
|
44
|
+
bail("Invalid JSON -- #{e.message}")
|
45
|
+
rescue Rubix::Error => e
|
46
|
+
bail($e.message)
|
48
47
|
end
|
48
|
+
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
def drop_into_a_shell
|
51
|
+
require 'irb'
|
52
|
+
ARGV.clear
|
53
|
+
include Rubix
|
54
|
+
IRB.start
|
55
|
+
end
|
56
|
+
|
57
|
+
begin
|
58
|
+
Settings.resolve!
|
59
|
+
rescue RuntimeError => e
|
60
|
+
Settings.dump_help
|
61
|
+
bail(e.message)
|
62
|
+
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
connect
|
53
66
|
rescue Rubix::Error => e
|
54
|
-
|
55
|
-
|
67
|
+
bail("Could not connect to Zabbix API: #{e.message}")
|
68
|
+
end
|
69
|
+
|
70
|
+
if Settings.rest.size < 2
|
71
|
+
drop_into_a_shell
|
72
|
+
else
|
73
|
+
perform_query
|
56
74
|
end
|
data/lib/rubix.rb
CHANGED
@@ -42,6 +42,20 @@ module Rubix
|
|
42
42
|
@connection = connection
|
43
43
|
end
|
44
44
|
|
45
|
+
# Is Rubix presently connected to a Zabbix server?
|
46
|
+
#
|
47
|
+
# @return [true, false]
|
48
|
+
def self.connected?
|
49
|
+
(!! connection)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Is Rubix presently connected and authorized with a Zabbix server?
|
53
|
+
#
|
54
|
+
# @return [true, false]
|
55
|
+
def self.authorized?
|
56
|
+
connection && connection.authorized?
|
57
|
+
end
|
58
|
+
|
45
59
|
# Return the current connection to a Zabbix API. Useful for
|
46
60
|
# directly sending queries.
|
47
61
|
#
|
@@ -71,5 +85,8 @@ module Rubix
|
|
71
85
|
# from being saved by the Zabbix API (i.e. - no host group for a
|
72
86
|
# host).
|
73
87
|
ValidationError = Class.new(Error)
|
88
|
+
|
89
|
+
# Given an incorrect argument.
|
90
|
+
ArgumentError = Class.new(Error)
|
74
91
|
|
75
92
|
end
|
data/lib/rubix/associations.rb
CHANGED
@@ -7,11 +7,17 @@ module Rubix
|
|
7
7
|
autoload :HasManyUserMacros, 'rubix/associations/has_many_user_macros'
|
8
8
|
autoload :HasManyApplications, 'rubix/associations/has_many_applications'
|
9
9
|
autoload :HasManyItems, 'rubix/associations/has_many_items'
|
10
|
+
autoload :HasManyUsers, 'rubix/associations/has_many_users'
|
11
|
+
autoload :HasManyUserGroups, 'rubix/associations/has_many_user_groups'
|
12
|
+
autoload :HasManyConditions, 'rubix/associations/has_many_conditions'
|
10
13
|
|
11
14
|
autoload :BelongsToHost, 'rubix/associations/belongs_to_host'
|
12
15
|
autoload :BelongsToTemplate, 'rubix/associations/belongs_to_template'
|
13
16
|
autoload :BelongsToItem, 'rubix/associations/belongs_to_item'
|
14
|
-
|
17
|
+
autoload :BelongsToAction, 'rubix/associations/belongs_to_action'
|
18
|
+
autoload :BelongsToUser, 'rubix/associations/belongs_to_user'
|
19
|
+
autoload :BelongsToUserGroup, 'rubix/associations/belongs_to_user_group'
|
20
|
+
autoload :BelongsToMediaType, 'rubix/associations/belongs_to_media_type'
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
module BelongsToAction
|
5
|
+
|
6
|
+
def action= a
|
7
|
+
return unless a
|
8
|
+
@action = a
|
9
|
+
@action_id = a.id
|
10
|
+
end
|
11
|
+
|
12
|
+
def action
|
13
|
+
@action
|
14
|
+
end
|
15
|
+
|
16
|
+
def action_id= aid
|
17
|
+
return unless aid
|
18
|
+
@action_id = aid
|
19
|
+
end
|
20
|
+
|
21
|
+
def action_id
|
22
|
+
return @action_id if @action_id
|
23
|
+
return unless @action
|
24
|
+
@action_id = @action.id
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
module BelongsToMediaType
|
5
|
+
|
6
|
+
def media_type= mt
|
7
|
+
return unless mt
|
8
|
+
@media_type = mt
|
9
|
+
@media_type_id = mt.id
|
10
|
+
end
|
11
|
+
|
12
|
+
def media_type
|
13
|
+
return @media_type if @media_type
|
14
|
+
return unless @media_type_id
|
15
|
+
@media_type = MediaType.find(:id => @media_type_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def media_type_id= mtid
|
19
|
+
return unless mtid
|
20
|
+
@media_type_id = mtid
|
21
|
+
end
|
22
|
+
|
23
|
+
def media_type_id
|
24
|
+
return @media_type_id if @media_type_id
|
25
|
+
return unless @media_type
|
26
|
+
@media_type_id = @media_type.id
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
module BelongsToUser
|
5
|
+
|
6
|
+
def user= u
|
7
|
+
return unless u
|
8
|
+
@user = u
|
9
|
+
@user_id = u.id
|
10
|
+
end
|
11
|
+
|
12
|
+
def user
|
13
|
+
return @user if @user
|
14
|
+
return unless @user_id
|
15
|
+
@user = User.find(:id => @user_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def user_id= uid
|
19
|
+
return unless uid
|
20
|
+
@user_id = uid
|
21
|
+
end
|
22
|
+
|
23
|
+
def user_id
|
24
|
+
return @user_id if @user_id
|
25
|
+
return unless @user
|
26
|
+
@user_id = @user.id
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
module BelongsToUserGroup
|
4
|
+
|
5
|
+
def user_group= ug
|
6
|
+
return unless ug
|
7
|
+
@user_group = ug
|
8
|
+
@user_group_id = ug.id
|
9
|
+
end
|
10
|
+
|
11
|
+
def user_group
|
12
|
+
return @user_group if @user_group
|
13
|
+
return unless @user_group_id
|
14
|
+
@user_group = UserGroup.find(:id => @user_group_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def user_group_id= ugid
|
18
|
+
return unless ugid
|
19
|
+
@user_group_id = ugid
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_group_id
|
23
|
+
return @user_group_id if @user_group_id
|
24
|
+
return unless @user_group
|
25
|
+
@user_group_id = @user_group.id
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
module HasManyConditions
|
4
|
+
|
5
|
+
def self.included klass
|
6
|
+
klass.send(:zabbix_attr, :condition_operator, :default => :and_or, :required => true)
|
7
|
+
end
|
8
|
+
|
9
|
+
def conditions
|
10
|
+
@conditions ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def conditions= cs
|
14
|
+
@conditions = cs.map do |c|
|
15
|
+
c.kind_of?(Condition) ? c : Condition.new(c)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
module HasManyUserGroups
|
4
|
+
|
5
|
+
def user_groups= ugs
|
6
|
+
return unless ugs
|
7
|
+
@user_groups = ugs
|
8
|
+
@user_group_ids = ugs.map(&:id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def user_groups
|
12
|
+
return @user_groups if @user_groups
|
13
|
+
return unless @user_group_ids
|
14
|
+
@user_groups = @user_group_ids.map { |ugid| UserGroup.find(:id => ugid) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def user_group_ids= ugids
|
18
|
+
return unless ugids
|
19
|
+
@user_group_ids = ugids
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_group_ids
|
23
|
+
return @user_group_ids if @user_group_ids
|
24
|
+
return unless @user_groups
|
25
|
+
@user_group_ids = @user_groups.map(&:id)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rubix
|
2
|
+
module Associations
|
3
|
+
module HasManyUsers
|
4
|
+
|
5
|
+
def users= us
|
6
|
+
return unless us
|
7
|
+
@users = us
|
8
|
+
@user_ids = us.map(&:id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def users
|
12
|
+
return @users if @users
|
13
|
+
return unless @user_ids
|
14
|
+
@users = @user_ids.map { |uid| User.find(:id => uid) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def user_ids= uids
|
18
|
+
return unless uids
|
19
|
+
@user_ids = uids
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_ids
|
23
|
+
return @user_ids if @user_ids
|
24
|
+
return unless @users
|
25
|
+
@user_ids = @users.map(&:id)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
data/lib/rubix/models.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
module Rubix
|
2
|
-
autoload :Model,
|
3
|
-
autoload :HostGroup,
|
4
|
-
autoload :Template,
|
5
|
-
autoload :Host,
|
6
|
-
autoload :Item,
|
7
|
-
autoload :Application,
|
8
|
-
autoload :UserMacro,
|
9
|
-
autoload :Trigger,
|
10
|
-
autoload :TimeSeries,
|
11
|
-
autoload :MediaType,
|
2
|
+
autoload :Model, 'rubix/models/model'
|
3
|
+
autoload :HostGroup, 'rubix/models/host_group'
|
4
|
+
autoload :Template, 'rubix/models/template'
|
5
|
+
autoload :Host, 'rubix/models/host'
|
6
|
+
autoload :Item, 'rubix/models/item'
|
7
|
+
autoload :Application, 'rubix/models/application'
|
8
|
+
autoload :UserMacro, 'rubix/models/user_macro'
|
9
|
+
autoload :Trigger, 'rubix/models/trigger'
|
10
|
+
autoload :TimeSeries, 'rubix/models/time_series'
|
11
|
+
autoload :MediaType, 'rubix/models/media_type'
|
12
|
+
autoload :Script, 'rubix/models/script'
|
13
|
+
autoload :Action, 'rubix/models/action'
|
14
|
+
autoload :Condition, 'rubix/models/condition'
|
15
|
+
autoload :Operation, 'rubix/models/operation'
|
16
|
+
autoload :User, 'rubix/models/user'
|
17
|
+
autoload :UserGroup, 'rubix/models/user_group'
|
18
|
+
autoload :Medium, 'rubix/models/medium'
|
12
19
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Rubix
|
2
|
+
|
3
|
+
class Action < Model
|
4
|
+
|
5
|
+
# Numeric codes for the event source. Default will be 'triggers'.
|
6
|
+
EVENT_SOURCE_CODES = {
|
7
|
+
:triggers => 0,
|
8
|
+
:discovery => 1,
|
9
|
+
:auto_registration => 2
|
10
|
+
}.freeze
|
11
|
+
EVENT_SOURCE_NAMES = EVENT_SOURCE_CODES.invert.freeze
|
12
|
+
|
13
|
+
# The default subject for messages.
|
14
|
+
MESSAGE_SUBJECT = "{TRIGGER.NAME}: {TRIGGER.STATUS}"
|
15
|
+
|
16
|
+
# The default body for messages.
|
17
|
+
MESSAGE_BODY = "{TRIGGER.NAME}: {TRIGGER.STATUS}\nLast value: {ITEM.LASTVALUE}\n\n{TRIGGER.URL}"
|
18
|
+
|
19
|
+
#
|
20
|
+
# == Properties & Finding ==
|
21
|
+
#
|
22
|
+
|
23
|
+
zabbix_attr :name, :required => true
|
24
|
+
zabbix_attr :event_source, :default => :triggers, :required => true
|
25
|
+
zabbix_attr :escalation_time, :default => 0
|
26
|
+
zabbix_attr :enabled, :default => true
|
27
|
+
zabbix_attr :message_subject, :default => MESSAGE_SUBJECT
|
28
|
+
zabbix_attr :message_body, :default => MESSAGE_BODY
|
29
|
+
zabbix_attr :send_recovery_message, :default => false
|
30
|
+
zabbix_attr :recovery_message_subject, :default => MESSAGE_SUBJECT
|
31
|
+
zabbix_attr :recovery_message_body, :default => MESSAGE_BODY
|
32
|
+
|
33
|
+
def initialize properties={}
|
34
|
+
super(properties)
|
35
|
+
|
36
|
+
self.operations = (properties[:operations] || [])
|
37
|
+
self.conditions = (properties[:conditions] || [])
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# == Associations ==
|
42
|
+
#
|
43
|
+
|
44
|
+
include Associations::HasManyConditions
|
45
|
+
|
46
|
+
def operations
|
47
|
+
@operations ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
def operations= os
|
51
|
+
@operations = os.map do |o|
|
52
|
+
o.kind_of?(Operation) ? o : Operation.new(o)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# == Validations ==
|
58
|
+
#
|
59
|
+
def validate
|
60
|
+
super()
|
61
|
+
raise ValidationError.new("An action must have at least one operation defined.") if operations.empty?
|
62
|
+
operations.each do |operation|
|
63
|
+
return false unless operation.validate
|
64
|
+
end
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# == Requests ==
|
70
|
+
#
|
71
|
+
|
72
|
+
def create_params
|
73
|
+
{
|
74
|
+
:name => name,
|
75
|
+
:eventsource => self.class::EVENT_SOURCE_CODES[event_source],
|
76
|
+
:evaltype => Condition::JOIN_CODES[condition_operator],
|
77
|
+
:status => (enabled ? 0 : 1),
|
78
|
+
:esc_period => escalation_time,
|
79
|
+
:def_shortdata => message_subject,
|
80
|
+
:def_longdata => message_body,
|
81
|
+
:recovery_msg => (send_recovery_message ? 1 : 0),
|
82
|
+
:r_shortdata => recovery_message_subject,
|
83
|
+
:r_longdata => recovery_message_body
|
84
|
+
}.tap do |cp|
|
85
|
+
cp[:conditions] = conditions.map(&:to_hash) unless conditions.empty?
|
86
|
+
cp[:operations] = operations.map(&:to_hash) unless operations.empty?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.find_params options={}
|
91
|
+
get_params.merge(:filter => {id_field => options[:id], :name => options[:name]})
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.get_params
|
95
|
+
super().merge({:select_conditions => :refer, :select_operations => :refer})
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.build action
|
99
|
+
new({
|
100
|
+
:id => action[id_field].to_i,
|
101
|
+
:name => action['name'],
|
102
|
+
:event_source => self::EVENT_SOURCE_NAMES[action['eventsource'].to_i],
|
103
|
+
:condition_operator => Condition::JOIN_NAMES[action['evaltype'].to_i],
|
104
|
+
:enabled => (action['status'].to_i == 0),
|
105
|
+
:escalation_time => action['esc_period'].to_i,
|
106
|
+
:message_subject => action['def_shortdata'],
|
107
|
+
:message_body => action['def_longdata'],
|
108
|
+
:send_recovery_message => (action['recovery_msg'].to_i == 1),
|
109
|
+
:recovery_message_subject => action['r_shortdata'],
|
110
|
+
:recovery_message_body => action['r_longdata'],
|
111
|
+
:conditions => (action['conditions'] || []).map { |c| Condition.build(c) },
|
112
|
+
:operations => (action['operations'] || []).map { |o| Operation.build(o) }
|
113
|
+
})
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|