rubix 0.0.8 → 0.0.9

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.
@@ -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