zenoss_client 0.1.0 → 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 (40) hide show
  1. data/README.textile +67 -0
  2. data/VERSION +1 -1
  3. data/lib/{events/zevent.rb → ext/ipaddr.rb} +11 -8
  4. data/lib/zenoss.rb +13 -89
  5. data/lib/zenoss/connection.rb +62 -0
  6. data/lib/{model/events/event_class.rb → zenoss/events.rb} +2 -0
  7. data/lib/{model/rrd_view.rb → zenoss/events/event.rb} +25 -19
  8. data/lib/zenoss/events/zevent.rb +25 -0
  9. data/lib/zenoss/exceptions.rb +25 -0
  10. data/lib/zenoss/jsonapi.rb +84 -0
  11. data/lib/zenoss/jsonapi/device_router.rb +93 -0
  12. data/lib/{events/event.rb → zenoss/jsonapi/events_router.rb} +24 -12
  13. data/lib/{model/events/mysql_event_manager.rb → zenoss/jsonapi/report_router.rb} +10 -12
  14. data/lib/{model → zenoss}/model.rb +6 -10
  15. data/lib/{model → zenoss/model}/devices.rb +4 -4
  16. data/lib/{model → zenoss/model}/devices/device.rb +20 -21
  17. data/lib/{model → zenoss/model}/devices/device_class.rb +0 -0
  18. data/lib/{model → zenoss/model}/devices/device_hw.rb +0 -0
  19. data/lib/{model → zenoss/model}/devices/operating_system.rb +0 -0
  20. data/lib/{model → zenoss/model}/event_view.rb +0 -0
  21. data/lib/{model → zenoss/model}/manufacturers/manufacturers.rb +0 -0
  22. data/lib/{model → zenoss/model}/processes/os_process_organizer.rb +0 -0
  23. data/lib/{model → zenoss/model}/rrd/rrd_data_point.rb +10 -7
  24. data/lib/zenoss/model/rrd_view.rb +93 -0
  25. data/lib/{model → zenoss/model}/services.rb +5 -5
  26. data/lib/{model → zenoss/model}/services/ip_service.rb +0 -0
  27. data/lib/{model → zenoss/model}/services/service.rb +0 -0
  28. data/lib/{model → zenoss/model}/services/service_class.rb +0 -0
  29. data/lib/{model → zenoss/model}/services/service_organizer.rb +0 -0
  30. data/lib/{model → zenoss/model}/services/win_service.rb +0 -0
  31. data/lib/{model → zenoss/model}/systems.rb +1 -1
  32. data/lib/{model → zenoss/model}/systems/system.rb +0 -0
  33. data/lib/{model → zenoss/model}/z_device_loader.rb +0 -0
  34. data/lib/{model → zenoss/model}/zenpack/zenpack_manager.rb +0 -0
  35. data/lib/zenoss/restapi.rb +80 -0
  36. data/lib/zenoss_client.rb +3 -0
  37. data/zenoss_client.gemspec +34 -0
  38. metadata +69 -51
  39. data/README.rdoc +0 -58
  40. data/lib/model/events/event_manager_base.rb +0 -66
@@ -0,0 +1,93 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dwanek@nd.gov>
3
+ #
4
+ #
5
+ # This file is part of zenoss_client.
6
+ #
7
+ # zenoss_client is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # zenoss_client is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with zenoss_client. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ module Zenoss
21
+ module JSONAPI
22
+ module DeviceRouter
23
+
24
+ # @param [String] uid The organizer path to fetch devices from. This can be a
25
+ # devclass, group, system, or location.
26
+ # @param [Hash] opts optional arguments to pass to getDevices
27
+ # @option opts [Fixnum] :start Offset to return the results from; used in pagination (default: 0)
28
+ # @option opts [Fixnum] :limit Number of items to return; used in pagination (default: 50)
29
+ # @option opts [String] :sort_key Key on which to sort the return results (default: 'name')
30
+ # @option opts [String] :sort_ord Sort order; can be either 'ASC' or 'DESC' (default: 'ASC')
31
+ # @option opts [Hash] :params Key-value pair of filters for this search. Can be one of the following: (default: {})
32
+ # @option :params [String] :name
33
+ # @option :params [String] :ipAddress
34
+ # @option :params [String] :deviceClass the device class not including the 'Devices' part, for instance '/Server/Linux'
35
+ # @option :params [String] :productionState
36
+ def get_devices(uid = '/zport/dmd/Devices', opts = {})
37
+ uid = "/zport/dmd#{uid}" unless uid.start_with?('/zport/dmd')
38
+ data = { :uid => uid }
39
+ data[:start] = opts[:start] if opts.has_key? :start
40
+ data[:limit] = opts[:limit] if opts.has_key? :limit
41
+ data[:sort] = opts[:sort_key] if opts.has_key? :sort_key
42
+ data[:dir] = opts[:sort_ord] if opts.has_key? :sort_ord
43
+ data[:params] = opts[:params] if opts.has_key? :params
44
+ resp = json_request('DeviceRouter', 'getDevices', [data])
45
+
46
+ devs = []
47
+ resp['devices'].each do |dev|
48
+ devs << Model::Device.new(self, dev)
49
+ end
50
+ devs
51
+ end
52
+
53
+ def get_templates(device_id)
54
+ resp = json_request('DeviceRouter', 'getTemplates', [{:id => device_id}])
55
+ end
56
+
57
+ def get_info(device_id, keys = nil)
58
+ data = {}
59
+ data[:uid] = device_id
60
+ data[:keys] = keys if keys
61
+ resp = json_request('DeviceRouter', 'getInfo', [data])
62
+ end
63
+
64
+ # =============== Non-API Helper methods ===============
65
+
66
+ # This method will allow you to search for devices by name. If you put a partial name
67
+ # it will return all matching entries. For example:
68
+ # find_devices_by_name 'mydev' will return all devices that start with mydev
69
+ # @param [String] name the name of the device to search for
70
+ # @param [Hash] opts options to help limit device search
71
+ # @option opts [String] :deviceClass the device class to limit the search to
72
+ # @option opts [String] :productionState the production state to limit the search to
73
+ # @return [Array] an array of devices found or an empty array if nothing is matched
74
+ def find_devices_by_name(name, opts={})
75
+ opts[:name] = name
76
+ get_devices('/zport/dmd/Devices', :params => opts)
77
+ end
78
+
79
+ # This method will find a device for the given IP Address or all matching devices
80
+ # given a partial IP.
81
+ # @param [String] ip the ip address of the device to search for
82
+ # @param [Hash] opts options to help limit device search
83
+ # @option opts [String] :deviceClass the device class to limit the search to
84
+ # @option opts [String] :productionState the production state to limit the search to
85
+ # @return [Array] an array of devices found or an empty array if nothing is matched
86
+ def find_devices_by_ip(ip, opts={})
87
+ opts[:ipAddress] = ip
88
+ get_devices('/zport/dmd/Devices', :params => opts)
89
+ end
90
+
91
+ end # DeviceRouter
92
+ end # JSONAPI
93
+ end # Zenoss
@@ -17,19 +17,31 @@
17
17
  # You should have received a copy of the GNU General Public License along
18
18
  # with zenoss_client. If not, see <http://www.gnu.org/licenses/>.
19
19
  #############################################################################
20
-
21
20
  module Zenoss
22
- module Event
23
- class Event
24
- include Zenoss
25
- def initialize(event_hash)
26
- event_hash.each_pair do |key,value|
27
- instance_variable_set("@#{key}",value)
28
- self.class.send(:define_method, key, proc { instance_variable_get("@#{key}")})
21
+ module JSONAPI
22
+ module EventsRouter
23
+
24
+ def get_events(device=nil, component=nil, event_class=nil, limit=100)
25
+ data = {
26
+ :start => 0,
27
+ :limit => 100,
28
+ :dir => 'DESC',
29
+ :sort => 'severity',
30
+ :params => { :severity => [5,4,3,2,1], :eventState => [0,1]},
31
+ }
32
+ data[:params][:device] = device if device
33
+ data[:params][:component] = component if component
34
+ data[:params][:eventClass] = event_class if event_class
35
+
36
+ resp = json_request('EventsRouter', 'query', [data])
37
+
38
+ events = []
39
+ resp['events'].each do |ev|
40
+ events << Events::ZEvent.new(self, ev)
29
41
  end
42
+ events
30
43
  end
31
- end # Event
32
- end # Event
33
- end # Zenoss
34
44
 
35
- require 'events/zevent'
45
+ end # EventsRouter
46
+ end # JSONAPI
47
+ end # Zenoss
@@ -18,19 +18,17 @@
18
18
  # with zenoss_client. If not, see <http://www.gnu.org/licenses/>.
19
19
  #############################################################################
20
20
  module Zenoss
21
- module Model
22
- module Events
23
- class MySqlEventManager < EventManagerBase
24
- include Zenoss::Model
21
+ module JSONAPI
22
+ module ReportRouter
25
23
 
26
- def initialize(manager_base)
27
- super(manager_base)
28
- end
24
+ def get_report_types
25
+ resp = json_request('ReportRouter', 'getReportTypes')
26
+ end
29
27
 
28
+ def get_report_tree(id = '/zport/dmd/Reports')
29
+ resp = json_request('ReportRouter', 'getTree', [{:id => id}])
30
+ end
30
31
 
31
- # ------------------ REST Calls ------------------ #
32
-
33
- end # MySqlEventManager
34
- end # Events
35
- end # Model
32
+ end # ReportRouter
33
+ end # JSONAPI
36
34
  end # Zenoss
@@ -45,23 +45,19 @@ module Zenoss
45
45
  end # Model
46
46
  end # Zenoss
47
47
 
48
- require 'model/event_view'
49
- require 'model/rrd_view'
48
+ require 'zenoss/model/event_view'
49
+ require 'zenoss/model/rrd_view'
50
50
 
51
51
  # Device Loader interface. You can use it directly or use the
52
52
  # utility methods in DeviceClass to create devices beneath
53
53
  # that class
54
- require 'model/z_device_loader'
54
+ require 'zenoss/model/z_device_loader'
55
55
 
56
56
  # Device Related ( /zport/dmd/Devices )
57
- require 'model/devices'
58
-
59
- # Event Related
60
- require 'model/events/event_manager_base'
61
- require 'model/events/mysql_event_manager'
57
+ require 'zenoss/model/devices'
62
58
 
63
59
  # Service Related ( /zport/dmd/Services )
64
- require 'model/services'
60
+ require 'zenoss/model/services'
65
61
 
66
62
  # Systems Related ( /zport/dmd/Systems )
67
- require 'model/systems'
63
+ require 'zenoss/model/systems'
@@ -47,7 +47,7 @@ end # Zenoss
47
47
 
48
48
 
49
49
  # Load the main Device related files
50
- require 'model/devices/device_class'
51
- require 'model/devices/device'
52
- require 'model/devices/device_hw'
53
- require 'model/devices/operating_system'
50
+ require 'zenoss/model/devices/device_class'
51
+ require 'zenoss/model/devices/device'
52
+ require 'zenoss/model/devices/device_hw'
53
+ require 'zenoss/model/devices/operating_system'
@@ -19,38 +19,33 @@
19
19
  #############################################################################
20
20
  module Zenoss
21
21
  module Model
22
- class Device
22
+ class Device < OpenStruct
23
23
  include Zenoss::Model
24
24
  include Zenoss::Model::EventView
25
25
  include Zenoss::Model::RRDView
26
26
  include Zenoss::Model::DeviceResultInt
27
27
 
28
- attr_reader :path, :device, :os, :hw
29
-
30
- def initialize(device_path)
31
- device_path.sub(/^\/zport\/dmd\/(.*)\/([^\/]+)$/) do |m|
32
- @path = $1
33
- @device = $2
34
- end
35
-
36
- @os = OperatingSystem.new(self)
37
- @hw = DeviceHW.new(self)
38
-
39
- # Initialize common things from Model
40
- model_init
28
+ # Initialize this object from a Hash returned via getDevices from the JSON api
29
+ # @param[Zenoss] zenoss the current instance we are connecting with
30
+ # @param[Hash] zhash a hash of values used to create this Device instance
31
+ def initialize(zenoss,zhash)
32
+ @zenoss = zenoss
33
+ super zhash
34
+ self.ipAddress = IPAddr.new(IPAddr.inet_ntoa(self.ipAddress)) if self.ipAddress
41
35
  end
42
36
 
37
+ # -------------------- JSON API Calls ------------------- #
43
38
 
44
- # ------------------ Custom REST Calls ------------------ #
45
- # These are not part of the official Zenoss API
46
-
39
+ # Get events for this device
47
40
  def get_events
48
- get_event_manager.get_event_list(nil,"device='#{@device}'")
41
+ @zenoss.get_events(self.name)
49
42
  end
50
43
 
44
+ def get_info(keys = nil)
45
+ @zenoss.get_info(self.uid, keys)
46
+ end
51
47
 
52
-
53
- # ------------------ REST Calls ------------------ #
48
+ # ------------------ Legacy REST Calls ------------------ #
54
49
 
55
50
  # Move this Device to the given DeviceClass.
56
51
  def change_device_class(device_class)
@@ -206,7 +201,11 @@ module Zenoss
206
201
  private
207
202
 
208
203
  def rest(method)
209
- super("#{@path}/#{@device}/#{method}")
204
+ @zenoss.rest(URI.encode("#{self.uid}/#{method}"))
205
+ end
206
+
207
+ def custom_rest(req_path, callback_func = nil, callback_attr=nil)
208
+ @zenoss.custom_rest(self.uid, req_path, callback_func, callback_attr)
210
209
  end
211
210
 
212
211
  end # Device
File without changes
File without changes
File without changes
@@ -19,17 +19,20 @@
19
19
  #############################################################################
20
20
  module Zenoss
21
21
  module Model
22
- class RRDDataPoint
22
+ class RRDDataPoint < OpenStruct
23
23
  include Zenoss
24
24
  include Zenoss::Model
25
25
 
26
- def initialize(datapoint_path)
27
- @path = datapoint_path
28
-
29
- # Initialize common things from Model
26
+ def initialize(zenoss, datapoint_path)
27
+ @zenoss = zenoss
28
+ super({:uid => datapoint_path})
30
29
  model_init
31
30
  end
32
31
 
32
+ # -------------------- JSON API Calls ------------------- #
33
+
34
+
35
+
33
36
  # ------------------------- Utility Methods ------------------------- #
34
37
  # These are methods that do not exist as part of the official Zenoss
35
38
  # API, but from an object model they seem to make sense to me.
@@ -47,8 +50,8 @@ module Zenoss
47
50
 
48
51
  private
49
52
 
50
- def rest(method, path = "#{@path}")
51
- super("#{path}/#{method}")
53
+ def rest(method)
54
+ @zenoss.rest(URI.encode("#{self.uid}/#{method}"))
52
55
  end
53
56
 
54
57
  end # DeviceClass
@@ -0,0 +1,93 @@
1
+ #############################################################################
2
+ # Copyright © 2010 Dan Wanek <dwanek@nd.gov>
3
+ #
4
+ #
5
+ # This file is part of zenoss_client.
6
+ #
7
+ # zenoss_client is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or (at
10
+ # your option) any later version.
11
+ #
12
+ # zenoss_client is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15
+ # Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along
18
+ # with zenoss_client. If not, see <http://www.gnu.org/licenses/>.
19
+ #############################################################################
20
+ module Zenoss
21
+ module Model
22
+ module RRDView
23
+ include Zenoss::Model
24
+
25
+ # @return [Array] of datapoints
26
+ def get_rrd_data_points
27
+ (plist_to_array( custom_rest('getRRDDataPoints').chomp )).map do |dstr|
28
+ dp = dstr.sub(/^<([\w]+)\s+at\s+(.*)>$/,'\2')
29
+ RRDDataPoint.new(@zenoss,dp)
30
+ end
31
+ end
32
+
33
+ # Get key/value pairs of RRD Values for the passed data source names.
34
+ #
35
+ # @param [Array <String>] dsnames data source names from RRDDataPoint#name
36
+ # @return [Hash] key/value pairs of data source name and data source values
37
+ def get_rrd_values(dsnames)
38
+ pdict_to_hash(custom_rest("getRRDValues?dsnames=[#{dsnames.join(',')}]"))
39
+ end
40
+
41
+ # Get all of the data point falues between a certain time period
42
+ # @param [String] dpname the name of the data point to retrieve values for
43
+ # @param [String] cf the RRD consolidation function to use
44
+ # AVERAGE,MIN,MAX,LAST
45
+ # @param [Fixnum] resolution the RRD resolution to use. This is the interval
46
+ # between values. It defaults to 300 seconds (5 minutes).
47
+ # @param [DateTime] start the time to begin fetching values from
48
+ # @param [DataTime] end the time to stop fetching values at. It defaults to now.
49
+ # @example An example of the actuall HTTP call
50
+ # http://myhost:8080/zport/dmd/Devices/path/callZenossMethod?methodName=fetchRRDValue&args=[my_dpoint===AVERAGE===300===1300761000===1300776100]
51
+ def fetch_rrd_value(dpname,vstart,vend=DateTime.now,cf='AVERAGE',resolution=300)
52
+ method = "fetchRRDValue?dpname=#{dpname}"
53
+ method << "&cf=#{cf}&resolution=#{resolution}"
54
+ method << "&start=#{vstart.strftime('%s')}"
55
+ method << "&end=#{vend.strftime('%s')}"
56
+ custom_rest(method)
57
+ parse_rrd_fetch(custom_rest(method))
58
+ end
59
+
60
+ #private
61
+
62
+
63
+ # Parse the string returned by the REST call fetchRRDValue.
64
+ def parse_rrd_fetch(vstr)
65
+ vstr = vstr.chomp
66
+ vstr = vstr.slice 1, (vstr.length - 2)
67
+ parts = vstr.match(/^\(([^\)]+)\),\s*\(([^\)]+)\),\s*\[([^\]]+)\]/)
68
+
69
+ # Get the first part of the return, start, end, resolution
70
+ retparms = Hash[[:start,:end,:resolution].zip( parts[1].split(/\s*,\s*/).map {|v| v.to_i} )]
71
+ # Get the datasource name. This will almost always be 'ds0'
72
+ retparms[:rrdds] = parts[2].gsub(/['"]/,'').split(/,/).first
73
+ # Get the values
74
+ retparms[:rrdvalues] = plist_to_array(parts[3]).map do |v|
75
+ atom = v.gsub(/(\(|\))/,'').split(/\s*,\s*/)[0]
76
+ case atom
77
+ when /\d\.\d/
78
+ atom.to_f
79
+ when /^\d$/
80
+ atom.to_i
81
+ when /None/
82
+ nil
83
+ end
84
+ end
85
+ retparms
86
+ end
87
+
88
+ end # RRDView
89
+ end # Model
90
+ end # Zenoss
91
+
92
+ # Load the RRD related files
93
+ require 'zenoss/model/rrd/rrd_data_point'
@@ -17,8 +17,8 @@
17
17
  # You should have received a copy of the GNU General Public License along
18
18
  # with zenoss_client. If not, see <http://www.gnu.org/licenses/>.
19
19
  #############################################################################
20
- require 'model/services/service_organizer'
21
- require 'model/services/service_class'
22
- require 'model/services/service'
23
- require 'model/services/ip_service'
24
- require 'model/services/win_service'
20
+ require 'zenoss/model/services/service_organizer'
21
+ require 'zenoss/model/services/service_class'
22
+ require 'zenoss/model/services/service'
23
+ require 'zenoss/model/services/ip_service'
24
+ require 'zenoss/model/services/win_service'
File without changes
File without changes