scout 5.9.8.pre → 5.9.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 194c916c84d7cc8a77e55c249f138e241e2bb640
4
- data.tar.gz: 4aadaca0469ba3bddb08393264e39e528a9fc335
3
+ metadata.gz: 3914b32858d1534ab42529c219405b21f7fe06c6
4
+ data.tar.gz: 6cf184690dbeb91bdda9ff084817a8b1be57872a
5
5
  SHA512:
6
- metadata.gz: 3ae8da04d1b7dff3e2c0fd7111c481b685d123dd2cd16ea3b97cae5a04a330d336904ca7909dd9421a8e96186a6410e14cbd2cdfd74954e6e56c491fc489c5a5
7
- data.tar.gz: 19ef5795f05007fefb8f4a5fab15bdff62da3f9b54fdccd6759fd4196eeea3d740f6e775a6bedacf8be611162375ab0379a3d1cb02afb027f289a666541dc5b6
6
+ metadata.gz: 58e2dd42b9ead9b0b480e6573c5ecf8424a0cf55373cf4e444d4731e9d17229970174818b7a3f9355ca50e475c1a6969a3adaae97177d7395c67aba9693a21ba
7
+ data.tar.gz: 7ebf6361ba4c84e397677771b9ebd1bbe1dda647ad59d005be1bf1f040766dcaaa9b21840b2d87b01cc3ab66a031c14abe1ba14d4c87b87c81cf99d6104be307
@@ -1,6 +1,6 @@
1
1
  # 5.9.8
2
2
 
3
- * Added Nagios plugin support via the `--nagios` flag.
3
+ * Make validation of private plugins more robust
4
4
 
5
5
  # 5.9.7.1
6
6
 
@@ -9,7 +9,6 @@
9
9
  # 5.9.7
10
10
 
11
11
  * Preliminary support for realtime compatibility with GO agent
12
- >>>>>>> master
13
12
 
14
13
  # 5.9.5
15
14
 
@@ -8,9 +8,6 @@ require "scout/version"
8
8
  require "scout/http"
9
9
  require "scout/command"
10
10
  require "scout/plugin"
11
- require "scout/third_party_plugins/third_party_plugins"
12
- require "scout/third_party_plugins/munin_plugin"
13
- require "scout/third_party_plugins/nagios_plugin"
14
11
  require "scout/plugin_options"
15
12
  require "scout/scout_logger"
16
13
  require "scout/server_base"
@@ -97,14 +97,6 @@ module Scout
97
97
  options[:environment] = environment
98
98
  end
99
99
 
100
- opts.on( "--nagios [NRPE CONFIG PATH]", "Run Nagios plugins defined in the specified NRPE config file. If no path is provided, plugins are loaded from '/etc/nagios/nrpe.cfg'." ) do |nrpe_config_file_path|
101
- options[:nrpe_config_file_path] = nrpe_config_file_path || '/etc/nagios/nrpe.cfg'
102
- end
103
-
104
- opts.on( "--munin [MUNIN PLUGIN PATH]", "Load Munin plugins from the specified path. If no path is provided, plugins are loaded from '/etc/munin/plugins'." ) do |munin_plugin_path|
105
- options[:munin_plugin_path] = munin_plugin_path || '/etc/munin/plugins'
106
- end
107
-
108
100
  opts.separator " "
109
101
  opts.separator "Common Options:"
110
102
  opts.separator "--------------------------------------------------------------------------"
@@ -192,8 +184,6 @@ module Scout
192
184
  @https_proxy = options[:https_proxy] || ""
193
185
  @hostname = options[:hostname] || Socket.gethostname
194
186
  @environment = options[:environment] || ""
195
- @munin_plugin_path = options[:munin_plugin_path]
196
- @nrpe_config_file_path = options[:nrpe_config_file_path]
197
187
  @options = options
198
188
  @args = args
199
189
 
@@ -10,7 +10,7 @@ module Scout
10
10
  log.debug("Running Scout [#{Scout::VERSION}] with server_metrics [#{ServerMetrics::VERSION}] on #{@hostname}") if log
11
11
  log.debug("Configuration directory is #{configuration_directory} ") if log
12
12
  # TODO: too much external logic of command doing things TO server. This should be moved into the server class.
13
- @scout = Scout::Server.new(server, key, history, log, server_name, @http_proxy, @https_proxy, @roles, @hostname, @environment, @munin_plugin_path, @nrpe_config_file_path)
13
+ @scout = Scout::Server.new(server, key, history, log, server_name, @http_proxy, @https_proxy, @roles, @hostname, @environment)
14
14
  @scout.load_history
15
15
 
16
16
  unless $stdin.tty?
@@ -1,13 +1,14 @@
1
+
1
2
  Dir.glob(File.join(File.dirname(__FILE__), *%w[.. .. vendor *])).each do |dir|
2
3
  $LOAD_PATH << File.join(dir,"lib")
3
4
  end
5
+
4
6
  require "multi_json"
5
7
  require "pusher"
6
8
  require "httpclient"
7
9
 
8
10
  module Scout
9
11
  class Server < Scout::ServerBase
10
- include ThirdPartyPlugins
11
12
  #
12
13
  # A plugin cannot take more than DEFAULT_PLUGIN_TIMEOUT seconds to execute,
13
14
  # otherwise, a timeout error is generated. This can be overriden by
@@ -27,7 +28,7 @@ module Scout
27
28
  attr_reader :client_key
28
29
 
29
30
  # Creates a new Scout Server connection.
30
- def initialize(server, client_key, history_file, logger=nil, server_name=nil, http_proxy='', https_proxy='', roles='', hostname=nil, environment='', munin_plugin_path, nrpe_config_file_path)
31
+ def initialize(server, client_key, history_file, logger=nil, server_name=nil, http_proxy='', https_proxy='', roles='', hostname=nil, environment='')
31
32
  @server = server
32
33
  @client_key = client_key
33
34
  @history_file = history_file
@@ -39,8 +40,6 @@ module Scout
39
40
  @roles = roles || ''
40
41
  @hostname = hostname
41
42
  @environment = environment
42
- @munin_plugin_path = munin_plugin_path
43
- @nrpe_config_file_path = nrpe_config_file_path
44
43
  @plugin_plan = []
45
44
  @plugins_with_signature_errors = []
46
45
  @directives = {} # take_snapshots, interval, sleep_interval
@@ -106,7 +105,11 @@ module Scout
106
105
  body_as_hash = JSON.parse(body)
107
106
 
108
107
  temp_plugins=Array(body_as_hash["plugins"])
109
- temp_plugins.each_with_index do |plugin,i|
108
+ # create a second array so the array we're iterating over doesn't mutate while we're iterating
109
+ valid_plugins = temp_plugins.dup
110
+ temp_plugins.each do |plugin|
111
+ # grab the index of this plugin in the valid_plugins array
112
+ valid_index = valid_plugins.index(plugin)
110
113
  signature=plugin['signature']
111
114
  id_and_name = "#{plugin['id']}-#{plugin['name']}".sub(/\A-/, "")
112
115
  if signature
@@ -117,12 +120,12 @@ module Scout
117
120
  if !verify_public_key(account_public_key, decoded_signature, code)
118
121
  info "#{id_and_name} signature verification failed for both the Scout and account public keys"
119
122
  plugin['sig_error'] = "The code signature failed verification against both the Scout and account public key. Please ensure the public key installed at #{@account_public_key_path} was generated with the same private key used to sign the plugin."
120
- @plugins_with_signature_errors << temp_plugins.delete_at(i)
123
+ @plugins_with_signature_errors << valid_plugins.delete_at(valid_index)
121
124
  end
122
125
  else
123
126
  info "#{id_and_name} signature doesn't match!"
124
127
  plugin['sig_error'] = "The code signature failed verification. Please place your account-specific public key at #{@account_public_key_path}."
125
- @plugins_with_signature_errors << temp_plugins.delete_at(i)
128
+ @plugins_with_signature_errors << valid_plugins.delete_at(valid_index)
126
129
  end
127
130
  end
128
131
  # filename is set for local plugins. these don't have signatures.
@@ -131,11 +134,11 @@ module Scout
131
134
  else
132
135
  info "#{id_and_name} has no signature!"
133
136
  plugin['sig_error'] = "The code has no signature and cannot be verified."
134
- @plugins_with_signature_errors << temp_plugins.delete_at(i)
137
+ @plugins_with_signature_errors << valid_plugins.delete_at(valid_index)
135
138
  end
136
139
  end
137
140
 
138
- @plugin_plan = temp_plugins
141
+ @plugin_plan = valid_plugins
139
142
  @directives = body_as_hash["directives"].is_a?(Hash) ? body_as_hash["directives"] : Hash.new
140
143
  @history["plan_last_modified"] = res["last-modified"]
141
144
  @history["old_plugins"] = @plugin_plan
@@ -147,8 +150,8 @@ module Scout
147
150
 
148
151
  @new_plan = true # used in determination if we should checkin this time or not
149
152
 
153
+ # Add local plugins to the plan.
150
154
  @plugin_plan += get_local_plugins
151
- @plugin_plan += get_third_party_plugins
152
155
  rescue Exception =>e
153
156
  fatal "Plan from server was malformed: #{e.message} - #{e.backtrace}"
154
157
  exit
@@ -158,7 +161,6 @@ module Scout
158
161
  info "Plan not modified."
159
162
  @plugin_plan = Array(@history["old_plugins"])
160
163
  @plugin_plan += get_local_plugins
161
- @plugin_plan += get_third_party_plugins
162
164
  @directives = @history["directives"] || Hash.new
163
165
 
164
166
  end
@@ -395,40 +397,34 @@ module Scout
395
397
  plugin['origin'] = nil
396
398
  end
397
399
  end
398
- if !third_party?(plugin)
399
- debug "Compiling plugin..."
400
- begin
401
- eval( code_to_run,
402
- TOPLEVEL_BINDING,
403
- plugin['path'] || plugin['name'] )
404
- info "Plugin compiled."
405
- rescue Exception
406
- raise if $!.is_a? SystemExit
407
- error "Plugin #{plugin['path'] || plugin['name']} would not compile: #{$!.message}"
408
- @checkin[:errors] << build_report(plugin,:subject => "Plugin would not compile", :body=>"#{$!.message}\n\n#{$!.backtrace}")
409
- return
410
- end
400
+ debug "Compiling plugin..."
401
+ begin
402
+ eval( code_to_run,
403
+ TOPLEVEL_BINDING,
404
+ plugin['path'] || plugin['name'] )
405
+ info "Plugin compiled."
406
+ rescue Exception
407
+ raise if $!.is_a? SystemExit
408
+ error "Plugin #{plugin['path'] || plugin['name']} would not compile: #{$!.message}"
409
+ @checkin[:errors] << build_report(plugin,:subject => "Plugin would not compile", :body=>"#{$!.message}\n\n#{$!.backtrace}")
410
+ return
411
+ end
411
412
 
412
- # Lookup any local options in plugin_config.properies as needed
413
- options=(plugin['options'] || Hash.new)
414
- options.each_pair do |k,v|
415
- if v=~/^lookup:(.+)$/
416
- lookup_key = $1.strip
417
- if plugin_config[lookup_key]
418
- options[k]=plugin_config[lookup_key]
419
- else
420
- info "Plugin #{id_and_name}: option #{k} appears to be a lookup, but we can't find #{lookup_key} in #{@plugin_config_path}"
421
- end
413
+ # Lookup any local options in plugin_config.properies as needed
414
+ options=(plugin['options'] || Hash.new)
415
+ options.each_pair do |k,v|
416
+ if v=~/^lookup:(.+)$/
417
+ lookup_key = $1.strip
418
+ if plugin_config[lookup_key]
419
+ options[k]=plugin_config[lookup_key]
420
+ else
421
+ info "Plugin #{id_and_name}: option #{k} appears to be a lookup, but we can't find #{lookup_key} in #{@plugin_config_path}"
422
422
  end
423
423
  end
424
- elsif munin?(plugin)
425
- Plugin.last_defined = MuninPlugin
426
- elsif nagios?(plugin)
427
- Plugin.last_defined = NagiosPlugin
428
424
  end
429
425
 
430
426
  debug "Loading plugin..."
431
- if job = third_party?(plugin) ? load_third_party(plugin) : Plugin.last_defined.load( last_run, (memory || Hash.new), options)
427
+ if job = Plugin.last_defined.load( last_run, (memory || Hash.new), options)
432
428
  info "Plugin loaded."
433
429
  debug "Running plugin..."
434
430
  begin
@@ -494,8 +490,7 @@ module Scout
494
490
  if Plugin.last_defined
495
491
  debug "Removing plugin code..."
496
492
  begin
497
- klasses = Plugin.last_defined.to_s.split("::")
498
- Object.send(:remove_const, klasses.include?("Scout") ? klasses.last : klasses.first) # munin and nagios plugins have "Scout::Munin/Nagios". don't want to remove 'Scout'.
493
+ Object.send(:remove_const, Plugin.last_defined.to_s.split("::").first)
499
494
  Plugin.last_defined = nil
500
495
  info "Plugin Removed."
501
496
  rescue
@@ -1,3 +1,3 @@
1
1
  module Scout
2
- VERSION = "5.9.8.pre"
2
+ VERSION = "5.9.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.9.8.pre
4
+ version: 5.9.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andre Lewis
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-10-16 00:00:00.000000000 Z
13
+ date: 2015-01-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: elif
@@ -78,9 +78,6 @@ files:
78
78
  - lib/scout/server_base.rb
79
79
  - lib/scout/streamer.rb
80
80
  - lib/scout/streamer_daemon.rb
81
- - lib/scout/third_party_plugins/munin_plugin.rb
82
- - lib/scout/third_party_plugins/nagios_plugin.rb
83
- - lib/scout/third_party_plugins/third_party_plugins.rb
84
81
  - lib/scout/version.rb
85
82
  - scout.gemspec
86
83
  - test/plugins/disk_usage.rb
@@ -329,9 +326,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
329
326
  version: '0'
330
327
  required_rubygems_version: !ruby/object:Gem::Requirement
331
328
  requirements:
332
- - - ">"
329
+ - - ">="
333
330
  - !ruby/object:Gem::Version
334
- version: 1.3.1
331
+ version: '0'
335
332
  requirements: []
336
333
  rubyforge_project: scout
337
334
  rubygems_version: 2.2.2
@@ -340,8 +337,5 @@ specification_version: 4
340
337
  summary: Scout is an easy-to-use hosted server monitoring service. The scout Ruby
341
338
  gem reports metrics to our service. The agent runs plugins, configured via the Scout
342
339
  web interface, to monitor a server.
343
- test_files:
344
- - test/plugins/disk_usage.rb
345
- - test/scout_test.rb
346
- - test/streamer_test.rb
340
+ test_files: []
347
341
  has_rdoc:
@@ -1,25 +0,0 @@
1
- module Scout
2
- class MuninPlugin < Scout::Plugin
3
- attr_accessor :file_name, :dir
4
-
5
- # The file name of the munin plugin to run inside the munin plugins directory.
6
- def initialize(options)
7
- self.file_name = options['file_name']
8
- self.dir = options['dir']
9
- end
10
-
11
- def build_report
12
- output = IO.popen("cd #{dir};munin-run #{file_name}").readlines[0..19]
13
- data = {}
14
- output.each do |l|
15
- # "i0.value 724\n"
16
- match_data = l.match("^(.*).value\s(.*)$")
17
- next if match_data.nil? # "multigraph diskstats_latency\n"
18
- name = match_data[1]
19
- value = match_data[2].to_f
20
- data[name] = value
21
- end
22
- report(data)
23
- end
24
- end
25
- end
@@ -1,54 +0,0 @@
1
- module Scout
2
- class NagiosPlugin < Scout::Plugin
3
- attr_accessor :cmd
4
-
5
- # The command, with arguments, to run a nagios plugin.
6
- # Ex: /usr/lib/nagios/plugins/check_procs -w 150 -c 200
7
- def initialize(cmd)
8
- self.cmd = cmd
9
- end
10
-
11
- def build_report
12
- return if !sanity_check
13
-
14
- # We only support parsing the first line of nagios plugin output
15
- IO.popen("#{cmd}") {|io| @nagios_output = io.readlines[0] }
16
-
17
- # Use exit status integer for OK/WARN/ERROR/CRIT status
18
- plugin_status = $?.exitstatus
19
-
20
- data = parse_nagios_output(@nagios_output)
21
- report(data.merge({:status => plugin_status}))
22
- end
23
-
24
- def sanity_check
25
- match = cmd.match(/(\S+)/)
26
- file = match[1].to_s
27
- if !File.exists?(file)
28
- error("The Nagios plugin file does not exist", "The file does not exist: #{file}.")
29
- elsif !File.executable?(file)
30
- error("Can not execute Nagios plugin", "The file is not executable: #{file}.")
31
- end
32
- data_for_server[:errors].any? ? false : true
33
- end
34
-
35
- def parse_nagios_output(output)
36
- text_field, perf_field = output.split('|',2)
37
- perf_data = {}
38
- if !perf_field.nil? && perf_field.strip!.length
39
- # Split the perf field
40
- # 1) on spaces
41
- # 2) up to the first 10 metrics
42
- # 3) split each "k=v;;;;" formatted metric into a key and value
43
- # 4) add the key to perf_data, and the digits from the value
44
- perf_field.split(" ")[0,10].inject(perf_data) {|r,e| k,v=e.split('=')[0,2]; r[k] = v.slice!(/^[\d.]*/).to_f if k && v; r}
45
- end
46
-
47
- #TODO - Allow ability to define regex captures of the text field numerical values as metrics
48
- text_data = {}
49
-
50
- return perf_data.merge(text_data)
51
- end
52
-
53
- end
54
- end
@@ -1,95 +0,0 @@
1
- # Abstracted logic for handling third-party plugins in the +Server+ class.
2
- module ThirdPartyPlugins
3
- # Returns true if the plugin hash is associated w/a 3rd-party plugin like Nagios or Munin.
4
- def third_party?(hash)
5
- self.munin?(hash) or self.nagios?(hash)
6
- end
7
-
8
- def munin?(hash)
9
- hash['type'].to_s == 'MUNIN'
10
- end
11
-
12
- def nagios?(hash)
13
- hash['type'].to_s == 'NAGIOS'
14
- end
15
-
16
- # Loading third-party plugins is simplier as they don't have options or memory.
17
- def load_third_party(hash)
18
- if munin?(hash)
19
- MuninPlugin.new(hash['file_name'])
20
- elsif nagios?(hash)
21
- Scout::NagiosPlugin.new(hash['cmd'])
22
- end
23
- end
24
-
25
- def get_third_party_plugins
26
- (get_munin_plugins + get_nagios_plugins).compact
27
- end
28
-
29
- def get_munin_plugins
30
- return [] unless @munin_plugin_path
31
- munin_plugin_path=Dir.glob(File.join(@munin_plugin_path,"*"))
32
- munin_plugin_path.map do |plugin_path|
33
- name = File.basename(plugin_path)
34
- options = if directives = @plugin_plan.find { |plugin| plugin['filename'] == name }
35
- directives['options']
36
- else
37
- nil
38
- end
39
- begin
40
- plugin = {
41
- 'name' => name,
42
- 'local_filename' => name,
43
- 'origin' => 'LOCAL',
44
- 'type' => 'MUNIN',
45
- 'code' => name,
46
- 'interval' => 0,
47
- 'options' => options,
48
- 'dir' => @munin_plugin_path
49
- }
50
- plugin
51
- rescue => e
52
- info "Error trying to read local plugin: #{plugin_path} -- #{e.backtrace.join('\n')}"
53
- nil
54
- end
55
- end.compact
56
- end
57
-
58
- def get_nagios_plugins
59
- return [] unless @nrpe_config_file_path
60
- begin
61
- nrpe_config = File.read(@nrpe_config_file_path)
62
- rescue => e
63
- info "Unable to read Nagios NRPE Config file [#{@nrpe_config_file_path}]: #{e.message}"
64
- return []
65
- end
66
- commands = {}
67
- nrpe_config.split("\n").each do |l|
68
- # command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200
69
- # TODO - don't parse commands w/remote args. : command[check_load]=/usr/lib/nagios/plugins/check_load -w $ARG1$ -c $ARG2$
70
- match = l.match(/(^command\[(.*)\]=)(.*)/)
71
- if match
72
- if match[3].include?('$ARG')
73
- info "Skipping Nagios Command [#{match[2]}] as it contains remote arguments."
74
- else
75
- commands[match[2]] = match[3]
76
- end
77
- end
78
- end
79
- debug "Found #{commands.size} Nagios plugins"
80
- # todo - ensure cmd file exists
81
- plugins = []
82
- commands.each do |name,cmd|
83
- plugins << {
84
- 'name' => name,
85
- 'local_filename' => name,
86
- 'origin' => 'LOCAL',
87
- 'type' => 'NAGIOS',
88
- 'code' => name,
89
- 'interval' => 0,
90
- 'cmd' => cmd # unique for nagios
91
- }
92
- end
93
- plugins
94
- end
95
- end # ThirdPartyPlugins