scout 5.9.8.pre → 5.9.8

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