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.
Files changed (37) hide show
  1. data/VERSION +1 -1
  2. data/bin/zabbix_api +45 -27
  3. data/lib/rubix.rb +17 -0
  4. data/lib/rubix/associations.rb +7 -1
  5. data/lib/rubix/associations/belongs_to_action.rb +31 -0
  6. data/lib/rubix/associations/belongs_to_media_type.rb +33 -0
  7. data/lib/rubix/associations/belongs_to_user.rb +33 -0
  8. data/lib/rubix/associations/belongs_to_user_group.rb +32 -0
  9. data/lib/rubix/associations/has_many_conditions.rb +23 -0
  10. data/lib/rubix/associations/has_many_user_groups.rb +32 -0
  11. data/lib/rubix/associations/has_many_users.rb +32 -0
  12. data/lib/rubix/models.rb +17 -10
  13. data/lib/rubix/models/action.rb +117 -0
  14. data/lib/rubix/models/application.rb +1 -3
  15. data/lib/rubix/models/condition.rb +99 -0
  16. data/lib/rubix/models/host.rb +9 -11
  17. data/lib/rubix/models/host_group.rb +1 -4
  18. data/lib/rubix/models/item.rb +12 -27
  19. data/lib/rubix/models/media_type.rb +19 -21
  20. data/lib/rubix/models/medium.rb +86 -0
  21. data/lib/rubix/models/model.rb +53 -1
  22. data/lib/rubix/models/operation.rb +134 -0
  23. data/lib/rubix/models/script.rb +49 -0
  24. data/lib/rubix/models/template.rb +2 -2
  25. data/lib/rubix/models/trigger.rb +8 -9
  26. data/lib/rubix/models/user.rb +145 -0
  27. data/lib/rubix/models/user_group.rb +94 -0
  28. data/lib/rubix/models/user_macro.rb +10 -20
  29. data/spec/requests/action_request_spec.rb +45 -0
  30. data/spec/requests/connection_request_spec.rb +3 -3
  31. data/spec/requests/media_type_request_spec.rb +8 -8
  32. data/spec/requests/script_request_spec.rb +54 -0
  33. data/spec/requests/user_group_request_spec.rb +97 -0
  34. data/spec/requests/user_request_spec.rb +84 -0
  35. data/spec/support/integration_helper.rb +105 -33
  36. data/spec/test.yml +0 -2
  37. metadata +22 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.5.0
@@ -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
- begin
23
- Settings.resolve!
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
- if Settings.rest.size < 2
31
- Settings.dump_help
32
- exit(1)
27
+ def connect
28
+ Rubix.connect(Settings[:url], Settings[:username], Settings[:password])
33
29
  end
34
30
 
35
- method = Settings.rest[0]
36
- json_params = Settings.rest[1]
37
-
38
- begin
39
- Rubix.connect(Settings[:url], Settings[:username], Settings[:password])
40
-
41
- params = JSON.parse(json_params)
42
- response = Rubix.connection.request(method, params)
43
-
44
- if Settings[:pretty]
45
- puts JSON.pretty_generate(response.parsed)
46
- else
47
- puts response.parsed.to_json
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
- rescue JSON::ParserError => e
51
- puts "Invalid JSON -- #{e.message}"
52
- exit(1)
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
- puts e.message
55
- exit(1)
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
@@ -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
@@ -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
+
@@ -1,12 +1,19 @@
1
1
  module Rubix
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'
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