rubix 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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