rubix 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,16 @@
1
1
  module Rubix
2
2
 
3
+ # A base class for all Zabbix models to subclass.
4
+ #
3
5
  # It might be worth using ActiveModel -- but maybe not. The goal is
4
6
  # to keep dependencies low while still retaining expressiveness.
5
7
  class Model
6
8
 
7
- attr_accessor :properties, :id
9
+ # @return [Hash]] the properties this model was initialized with
10
+ attr_accessor :properties
11
+
12
+ # @return [Fixnum, nil] the ID of this model
13
+ attr_accessor :id
8
14
 
9
15
  extend Logs
10
16
  include Logs
@@ -15,28 +21,40 @@ module Rubix
15
21
 
16
22
  # This is the name of the resource as used inside Rubix -- Host,
17
23
  # HostGroup, UserMacro, &c.
24
+ #
25
+ # @return [String]
18
26
  def self.resource_name
19
27
  self.to_s.split('::').last
20
28
  end
21
29
 
22
30
  # This is the name of *this* resource instance, using this
23
31
  # object's 'name' property if possible.
32
+ #
33
+ # @return [String]
24
34
  def resource_name
25
35
  "#{self.class.resource_name} #{respond_to?(:name) ? self.name : self.id}"
26
36
  end
27
37
 
28
38
  # This is the name of the resource as used by Zabbix -- host,
29
39
  # hostgroup, usermacro, &c.
40
+ #
41
+ # @return [String]
30
42
  def self.zabbix_name
31
43
  resource_name.downcase
32
44
  end
33
45
 
34
46
  # This is the name of the id field returned in Zabbix responses --
35
- # hostid, groupid, hostmacroid, &c.
47
+ # +hostid+, +groupid+, +hostmacroid+, &c.
48
+ #
49
+ # @return [String]
36
50
  def self.id_field
37
51
  "#{zabbix_name}id"
38
52
  end
39
53
 
54
+ # This is the name of the id field returned in Zabbix responses --
55
+ # +hostid+, +groupid+, +hostmacroid+, &c.
56
+ #
57
+ # @return [String]
40
58
  def id_field
41
59
  self.class.id_field
42
60
  end
@@ -45,43 +63,83 @@ module Rubix
45
63
  # == Initialization ==
46
64
  #
47
65
 
66
+ # Create a new model instance. This may represent a new or
67
+ # existing Zabbix resource.
68
+ #
69
+ # @param [Hash] properties
70
+ # @option properties [Fixnum] id the ID of the resource in Zabbix (typically blank for a new resource)
48
71
  def initialize properties={}
49
72
  @properties = properties
50
73
  @id = properties[:id]
51
74
  end
52
75
 
76
+ # Send a request to the Zabbix API. This is just a convenience
77
+ # method for <tt>Rubix::Connection#request</tt>.
78
+ #
79
+ # @param [String] method
80
+ # @param [Hash,Array] params
81
+ # @return [Rubix::Response]
53
82
  def request method, params
54
83
  self.class.request(method, params)
55
84
  end
56
85
 
86
+ # Send a request to the Zabbix API. This is just a convenience
87
+ # method for <tt>Rubix::Connection#request</tt>.
88
+ #
89
+ # @param [String] method
90
+ # @param [Hash,Array] params
91
+ # @return [Rubix::Response]
57
92
  def self.request method, params
58
93
  Rubix.connection && Rubix.connection.request(method, params)
59
94
  end
60
95
 
96
+ # Is this a new record? We can tell because the ID must be blank.
61
97
  #
62
- # == CRUD ==
63
- #
64
-
98
+ # @return [true, false]
65
99
  def new_record?
66
100
  @id.nil?
67
101
  end
68
102
 
103
+ # Save this record.
104
+ #
105
+ # Will create new records and update old ones.
106
+ #
107
+ # @return [true, false]
69
108
  def save
70
109
  new_record? ? create : update
71
110
  end
72
-
111
+
112
+ # Validate this record.
113
+ #
114
+ # Override this method in a subclass and have it raise a
115
+ # <tt>Rubix::ValidationError</tt> if validation fails.
116
+ #
117
+ # @return [true, false]
73
118
  def validate
74
119
  true
75
120
  end
76
121
 
122
+ #
123
+ # == Create ==
124
+ #
125
+
126
+ # Parameters for creating a new resource of this type.
127
+ #
128
+ # @return [Hash]
77
129
  def create_params
78
130
  {}
79
131
  end
80
132
 
133
+ # Send a request to create this resource.
134
+ #
135
+ # @return [Rubix::Response]
81
136
  def create_request
82
137
  request("#{self.class.zabbix_name}.create", create_params)
83
138
  end
84
139
 
140
+ # Create this resource.
141
+ #
142
+ # @return [true, false]
85
143
  def create
86
144
  return false unless validate
87
145
  response = create_request
@@ -95,14 +153,27 @@ module Rubix
95
153
  end
96
154
  end
97
155
 
156
+ #
157
+ # == Update ==
158
+ #
159
+
160
+ # Parameters for updating a resource of this type.
161
+ #
162
+ # @return [Hash]
98
163
  def update_params
99
164
  create_params.merge({id_field => id})
100
165
  end
101
166
 
167
+ # Send a request to update this resource.
168
+ #
169
+ # @return [Rubix::Response]
102
170
  def update_request
103
171
  request("#{self.class.zabbix_name}.update", update_params)
104
172
  end
105
173
 
174
+ # Update this resource.
175
+ #
176
+ # @return [true, false]
106
177
  def update
107
178
  return false unless validate
108
179
  return create if new_record?
@@ -121,18 +192,37 @@ module Rubix
121
192
  end
122
193
  end
123
194
 
195
+ # A hook that will be run before this resource is updated.
196
+ #
197
+ # Override this in a subclass to implement any desired
198
+ # before-update functionality. Must return +true+ or +false+.
199
+ #
200
+ # @return [true, false]
124
201
  def before_update
125
202
  true
126
203
  end
127
204
 
205
+ #
206
+ # == Destroy ==
207
+ #
208
+
209
+ # Parameters for destroying this resource.
210
+ #
211
+ # @return [Array<Fixnum>]
128
212
  def destroy_params
129
213
  [id]
130
214
  end
131
215
 
216
+ # Send a request to destroy this resource.
217
+ #
218
+ # @return [Rubix::Response]
132
219
  def destroy_request
133
220
  request("#{self.class.zabbix_name}.delete", destroy_params)
134
221
  end
135
-
222
+
223
+ # Destroy this resource.
224
+ #
225
+ # @return [true, false]
136
226
  def destroy
137
227
  return true if new_record?
138
228
  return false unless before_destroy
@@ -150,6 +240,12 @@ module Rubix
150
240
  end
151
241
  end
152
242
 
243
+ # A hook that will be run before this resource is destroyed.
244
+ #
245
+ # Override this in a subclass to implement any desired
246
+ # before-destroy functionality. Must return +true+ or +false+.
247
+ #
248
+ # @return [true, false]
153
249
  def before_destroy
154
250
  true
155
251
  end
@@ -158,18 +254,33 @@ module Rubix
158
254
  # == Index ==
159
255
  #
160
256
 
257
+ # Parameters for 'get'-type requests for this resource's type.
258
+ #
259
+ # @return [Hash]
161
260
  def self.get_params
162
261
  { :output => :extend }
163
262
  end
164
263
 
264
+ # Parameters to list all the objects of this resource's type.
265
+ #
266
+ # @param [Hash] options options for filtering the list of all resources.
267
+ # @return [Hash]
165
268
  def self.all_params options={}
166
269
  get_params.merge(options)
167
270
  end
168
271
 
272
+ # Send a request to list all objects of this resource's type.
273
+ #
274
+ # @param [Hash] options options for filtering the list of all resources.
275
+ # @return [Rubix::Response]
169
276
  def self.all_request options={}
170
277
  request("#{zabbix_name}.get", all_params(options))
171
278
  end
172
279
 
280
+ # List all objects of this resource's type.
281
+ #
282
+ # @param [Hash] options options for filtering the list of all resources.
283
+ # @return [Array<Rubix::Model>]
173
284
  def self.all options={}
174
285
  response = all_request(options)
175
286
  if response.has_data?
@@ -180,22 +291,39 @@ module Rubix
180
291
  end
181
292
  end
182
293
 
183
- def self.each &block
184
- all.each(&block)
294
+ # Execute block once for each element of the result set.
295
+ #
296
+ # @param [Hash] options options for filtering the list of all resources.
297
+ # @return [Array<Rubix::Model>]
298
+ def self.each options={}, &block
299
+ all(options).each(&block)
185
300
  end
186
301
 
187
302
  #
188
303
  # == Show ==
189
304
  #
190
305
 
306
+ # Parameters for finding a specific resource.
307
+ #
308
+ # @param [Hash] options specify properties about the object to find
309
+ # @return [Hash]
191
310
  def self.find_params options={}
192
311
  get_params.merge(options)
193
312
  end
194
313
 
314
+ # Send a find request for a specific resource.
315
+ #
316
+ # @param [Hash] options specify properties about the object to find
317
+ # @return [Rubix::Response]
195
318
  def self.find_request options={}
196
319
  request("#{zabbix_name}.get", find_params(options))
197
320
  end
198
321
 
322
+ # Find a resource using the given +options+ or return +nil+ if
323
+ # none is found.
324
+ #
325
+ # @param [Hash] options specify properties about the object to find
326
+ # @return [Rubix::Model, nil]
199
327
  def self.find options={}
200
328
  response = find_request(options)
201
329
  case
@@ -209,6 +337,12 @@ module Rubix
209
337
  end
210
338
  end
211
339
 
340
+ # Find a resource using the given +options+ or create one if none
341
+ # can be found. Will return +false+ if the object cannot be found
342
+ # and cannot be created.
343
+ #
344
+ # @param [Hash] options specify properties about the object to find
345
+ # @return [Rubix::Model, false]
212
346
  def self.find_or_create options={}
213
347
  response = find_request(options)
214
348
  case
@@ -2,10 +2,22 @@ require 'json'
2
2
 
3
3
  module Rubix
4
4
 
5
+ # A class used to wrap Net::HTTP::Response objects to make it easier
6
+ # to inspect them for various cases.
5
7
  class Response
6
8
 
7
- attr_reader :http_response, :code, :body
9
+ # @return [Net::HTTP::Response] the raw HTTP response from the Zabbix API
10
+ attr_reader :http_response
8
11
 
12
+ # @return [Fixnum] the raw HTTP response code
13
+ attr_reader :code
14
+
15
+ # @return [String] the raw HTTP response body
16
+ attr_reader :body
17
+
18
+ # Wrap a <tt>Net::HTTP::Response</tt>.
19
+ #
20
+ # @param [Net::HTTP::Response] http_response
9
21
  def initialize(http_response)
10
22
  @http_response = http_response
11
23
  @body = http_response.body
@@ -13,9 +25,12 @@ module Rubix
13
25
  end
14
26
 
15
27
  #
16
- # Parsing
28
+ # == Parsing ==
17
29
  #
18
-
30
+
31
+ # The parsed JSON body.
32
+ #
33
+ # @return [Hash]
19
34
  def parsed
20
35
  return @parsed if @parsed
21
36
  if non_200?
@@ -30,31 +45,64 @@ module Rubix
30
45
  end
31
46
 
32
47
  #
33
- # Error Handling
48
+ # == Error Handling ==
34
49
  #
35
50
 
51
+ # Was the response *not* a 200?
52
+ #
53
+ # @return [true,false]
36
54
  def non_200?
37
55
  code != 200
38
56
  end
39
-
57
+
58
+ # Was the response an error? This will return +true+ if
59
+ #
60
+ # - the response was not a 200
61
+ # - the response was a 200 and contains an +error+ key
62
+ #
63
+ # @return [true, false]
40
64
  def error?
41
65
  non_200? || (parsed.is_a?(Hash) && parsed['error'])
42
66
  end
43
67
 
68
+ # Was this response successful? Successful responses must
69
+ #
70
+ # - have a 200 response code
71
+ # - *not* have an +error+ key in the response
72
+ #
73
+ # @return [true, false]
74
+ def success?
75
+ !error?
76
+ end
77
+
78
+ # Was the response a *Zabbix* error, implying a 200 with an
79
+ # +error+ key.
80
+ #
81
+ # @return [true, false]
44
82
  def zabbix_error?
45
83
  code == 200 && error?
46
84
  end
47
85
 
86
+ # Returns the error code of a Zabbix error or +nil+ if this wasn't
87
+ # an error.
88
+ #
89
+ # @return [nil, Fixnum]
48
90
  def error_code
49
91
  return unless error?
50
92
  (non_200? ? code : parsed['error']['code'].to_i) rescue 0
51
93
  end
52
-
94
+
95
+ # Returns the Zabbix type of the error or +nil+ if this wasn't an error.
96
+ #
97
+ # @return [nil, String]
53
98
  def error_type
54
99
  return unless error?
55
100
  (non_200? ? "Non-200 Error" : parsed['error']['message']) rescue 'Unknown Error'
56
101
  end
57
102
 
103
+ # Return an error message or +nil+ if this wasn't an error.
104
+ #
105
+ # @return [String, nil]
58
106
  def error_message
59
107
  return unless error?
60
108
  begin
@@ -70,51 +118,75 @@ module Rubix
70
118
  end
71
119
  end
72
120
 
73
- def success?
74
- !error?
75
- end
76
-
77
121
  #
78
- # Inspecting contents
122
+ # == Inspecting contents ==
79
123
  #
80
124
 
125
+ # The contents of the +result+ key. Returns +nil+ if an error.
81
126
  def result
127
+ return if error?
82
128
  parsed['result']
83
129
  end
84
-
130
+
131
+ # Return the contents of +key+ *within* the +result+ key or +nil+
132
+ # if an error.
85
133
  def [] key
86
134
  return if error?
87
135
  result[key]
88
136
  end
89
137
 
138
+ # Return the +first+ element of the +result+ key or +nil+ if an
139
+ # error.
90
140
  def first
91
141
  return if error?
92
142
  result.first
93
143
  end
94
144
 
145
+ # Is the +result+ key empty?
146
+ #
147
+ # @return [true, false]
95
148
  def empty?
149
+ return true unless result
96
150
  result.empty?
97
151
  end
98
152
 
153
+ # Does this response "have data" in the sense that
154
+ #
155
+ # - it is a successful response (see <tt>Rubix::Response#success?</tt>)
156
+ # - it has a +result+ key which is not empty
99
157
  def has_data?
100
158
  success? && (!empty?)
101
159
  end
102
-
160
+
161
+ # Is the contents of the *first* element of the +result+ key a
162
+ # Hash?
163
+ #
164
+ # @return [true, false]
103
165
  def hash?
104
166
  return false if error?
105
167
  result.is_a?(Hash) && result.size > 0 && result.first.last
106
168
  end
107
169
 
170
+ # Is the contents of the *first* element of the +result+ key an
171
+ # Array?
172
+ #
173
+ # @return [true, false]
108
174
  def array?
109
175
  return false if error?
110
176
  result.is_a?(Array) && result.size > 0 && result.first
111
177
  end
112
178
 
179
+ # Is the contents of the +result+ key a String?
180
+ #
181
+ # @return [true, false]
113
182
  def string?
114
183
  return false if error?
115
184
  result.is_a?(String) && result.size > 0
116
185
  end
117
186
 
187
+ # Is the contents of the +result+ key either +true+ or +false+?
188
+ #
189
+ # @return [true, false]
118
190
  def boolean?
119
191
  return false if error?
120
192
  result == true || result == false