scout_agent 3.2.2 → 3.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/Rakefile +4 -3
- data/data/cacert.pem +3154 -0
- data/data/gpl-2.0.txt +339 -0
- data/data/lgpl-2.1.txt +504 -0
- data/lib/scout_agent.rb +3 -3
- data/lib/scout_agent/agent/master_agent.rb +35 -5
- data/lib/scout_agent/api.rb +3 -23
- data/lib/scout_agent/assignment/queue.rb +18 -3
- data/lib/scout_agent/server.rb +18 -3
- data/test/tc_core_extensions.rb +1 -0
- metadata +8 -5
data/lib/scout_agent.rb
CHANGED
@@ -27,9 +27,9 @@ require "scout_agent/dispatcher"
|
|
27
27
|
require "scout_agent/api"
|
28
28
|
|
29
29
|
# require gems
|
30
|
-
require_lib_or_gem "json", "=1.1.
|
30
|
+
require_lib_or_gem "json", "=1.1.6"
|
31
31
|
require_lib_or_gem "amalgalite", "=0.9.0"
|
32
|
-
require_lib_or_gem "rest_client", "=0
|
32
|
+
require_lib_or_gem "rest_client", "=1.0"
|
33
33
|
require_lib_or_gem "xmpp4r", "=0.4"
|
34
34
|
require_lib_or_gem "xmpp4r/roster" # loads from xmpp4r's version
|
35
35
|
|
@@ -92,7 +92,7 @@ module ScoutAgent
|
|
92
92
|
end
|
93
93
|
|
94
94
|
# The version of this agent.
|
95
|
-
VERSION = "3.2.
|
95
|
+
VERSION = "3.2.3".freeze
|
96
96
|
# A Pathname reference to the agent code directory, used in dynamic loading.
|
97
97
|
LIB_DIR = Pathname.new(File.dirname(__FILE__)) + agent_name
|
98
98
|
end
|
@@ -17,6 +17,21 @@ module ScoutAgent
|
|
17
17
|
# databases and cleaning out old log files.
|
18
18
|
#
|
19
19
|
class MasterAgent < Agent
|
20
|
+
#
|
21
|
+
# These are the error codes and descriptions for failure conditions the
|
22
|
+
# mission process may not be able to report.
|
23
|
+
#
|
24
|
+
MISSION_ERRORS = { 76 => "was already running",
|
25
|
+
16 => "couldn't be compiled",
|
26
|
+
6 => "couldn't be loaded" }
|
27
|
+
#
|
28
|
+
# These are the +MISSION_ERRORS+ by name (the last word of the description
|
29
|
+
# as a Symbol).
|
30
|
+
#
|
31
|
+
MISSION_ERROR_NAMES = Hash[ *MISSION_ERRORS.map { |code, name|
|
32
|
+
[name[/\S+\z/].to_sym, code]
|
33
|
+
}.flatten ]
|
34
|
+
|
20
35
|
#
|
21
36
|
# Prepares the primary event loop for execution. The main function at
|
22
37
|
# this point is to ensure that we can load all of the needed databases.
|
@@ -182,13 +197,26 @@ module ScoutAgent
|
|
182
197
|
end
|
183
198
|
@mission_pid = nil
|
184
199
|
unless $?.success? # record that the Mission exited with an error
|
200
|
+
error_status = $?.exitstatus
|
185
201
|
log.warn( "#{mission[:name]} exited with an error: " +
|
186
|
-
"#{
|
202
|
+
"#{error_status}." )
|
203
|
+
body = "Exit status: #{error_status}"
|
204
|
+
if description = MISSION_ERRORS[error_status]
|
205
|
+
body << <<-END_ERROR_DESCRIPTION
|
206
|
+
|
207
|
+
|
208
|
+
This error often means that a mission #{description}.
|
209
|
+
This can be a natural function of the agent cleaning up after
|
210
|
+
itself and it shouldn't be any cause for alarm if just see it
|
211
|
+
now and then. However, if you are seeing this error a lot,
|
212
|
+
please contact Scout support.
|
213
|
+
END_ERROR_DESCRIPTION
|
214
|
+
end
|
187
215
|
@db.write_report(
|
188
216
|
mission[:id],
|
189
217
|
:error,
|
190
218
|
:subject => "#{mission[:name]} exited with an error",
|
191
|
-
:body =>
|
219
|
+
:body => body
|
192
220
|
)
|
193
221
|
end
|
194
222
|
rescue Timeout::Error # Mission exceeded allowed execution
|
@@ -345,7 +373,7 @@ module ScoutAgent
|
|
345
373
|
|
346
374
|
# clear the parent's identity and assume mine
|
347
375
|
IDCard.me = nil
|
348
|
-
IDCard.new(:mission).authorize or exit(
|
376
|
+
IDCard.new(:mission).authorize or exit(MISSION_ERROR_NAMES[:running])
|
349
377
|
|
350
378
|
# get a handle on the log
|
351
379
|
@log = ScoutAgent.prepare_wire_tap(:mission)
|
@@ -373,7 +401,8 @@ module ScoutAgent
|
|
373
401
|
:subject => "#{mission[:name]} could not be compiled",
|
374
402
|
:body => "#{error.message}\n#{error.backtrace.join("\n")}"
|
375
403
|
)
|
376
|
-
|
404
|
+
# warn parent if we can't report
|
405
|
+
exit(reported ? 0 : MISSION_ERROR_NAMES[:compiled])
|
377
406
|
end
|
378
407
|
end
|
379
408
|
|
@@ -400,7 +429,8 @@ module ScoutAgent
|
|
400
429
|
:subject => "#{mission[:name]} could not be prepared",
|
401
430
|
:body => "The code didn't define a Scout::Plugin subclass"
|
402
431
|
)
|
403
|
-
|
432
|
+
# warn parent if we can't report
|
433
|
+
exit(reported ? 0 : MISSION_ERROR_NAMES[:loaded])
|
404
434
|
end
|
405
435
|
end
|
406
436
|
|
data/lib/scout_agent/api.rb
CHANGED
@@ -4,26 +4,6 @@
|
|
4
4
|
require "rbconfig" # used to find the Ruby we are running under
|
5
5
|
require "pathname" # all paths are Pathname objects
|
6
6
|
|
7
|
-
begin
|
8
|
-
#
|
9
|
-
# the agent communicates in JSON, so we need to load the gem unless we are in
|
10
|
-
# something like Rails that already provides us with JSON capabilities
|
11
|
-
#
|
12
|
-
require "json" unless Hash.new.respond_to? :to_json
|
13
|
-
rescue LoadError # library not found
|
14
|
-
begin
|
15
|
-
require "rubygems"
|
16
|
-
begin
|
17
|
-
gem("json", "=1.1.4")
|
18
|
-
rescue NoMethodError
|
19
|
-
abort "Please upgrade RubyGems as the gem() method is required."
|
20
|
-
end
|
21
|
-
require "json"
|
22
|
-
rescue LoadError # library not found
|
23
|
-
abort "Please install the 'json' gem to use this API."
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
7
|
module ScoutAgent
|
28
8
|
#
|
29
9
|
# This module contains methods used to communicate with the agent
|
@@ -96,7 +76,7 @@ module ScoutAgent
|
|
96
76
|
map { |s| "'#{API.shell_escape(s)}'" }.join(" ")
|
97
77
|
begin
|
98
78
|
response = open("| #{command} 2>&1", "r+") { |agent|
|
99
|
-
agent.
|
79
|
+
agent.print Marshal.dump(@input) if @input
|
100
80
|
agent.close_write
|
101
81
|
agent.read
|
102
82
|
}
|
@@ -144,7 +124,7 @@ module ScoutAgent
|
|
144
124
|
#
|
145
125
|
def validate(mission_id_or_report_type, fields)
|
146
126
|
unless mission_id_or_report_type.to_s =~
|
147
|
-
/\A(?:report|hint|alert|error
|
127
|
+
/\A(?:report|hint|alert|error|0*[1-9]\d*)\z/
|
148
128
|
raise ArgumentError, "Invalid mission ID or report type"
|
149
129
|
end
|
150
130
|
|
@@ -156,7 +136,7 @@ module ScoutAgent
|
|
156
136
|
unless plugin_id
|
157
137
|
raise ArgumentError, "A :plugin_id is a required field for reports"
|
158
138
|
end
|
159
|
-
unless plugin_id.to_s =~ /\
|
139
|
+
unless plugin_id.to_s =~ /\A0*[1-9]\d*\z/
|
160
140
|
raise ArgumentError, "The :plugin_id must be a positive Integer"
|
161
141
|
end
|
162
142
|
end
|
@@ -11,6 +11,11 @@ module ScoutAgent
|
|
11
11
|
#
|
12
12
|
# scout_agent q ID_OR_TYPE <<< '{"fields": "in JSON"}'
|
13
13
|
#
|
14
|
+
# or:
|
15
|
+
#
|
16
|
+
# ruby -e 'print Marshal.dump(:fields => "in Ruby")' | \
|
17
|
+
# scout_agent q ID_OR_TYPE
|
18
|
+
#
|
14
19
|
# This command queues some data from an external source for a plugin. The
|
15
20
|
# plugin to receive the message is given by ID in +ID_OR_TYPE+. That plugin
|
16
21
|
# will be able to collect this data during its next run.
|
@@ -21,6 +26,9 @@ module ScoutAgent
|
|
21
26
|
# be a Hash (object in JSON terminology) that includes the key "plugin_id"
|
22
27
|
# associated with an ID value for the reporting plugin.
|
23
28
|
#
|
29
|
+
# If you prefer, you can pass Marshal data from Ruby for the fields instead
|
30
|
+
# of JSON.
|
31
|
+
#
|
24
32
|
class Queue < Assignment
|
25
33
|
#
|
26
34
|
# A list of errors that can be sent to the user when attempting to queue a
|
@@ -37,7 +45,7 @@ module ScoutAgent
|
|
37
45
|
[ :missing_fields,
|
38
46
|
"You must provide fields to queue." ],
|
39
47
|
[ :invalid_fields,
|
40
|
-
"You must pass valid JSON for the fields." ],
|
48
|
+
"You must pass valid JSON or Marshal data for the fields." ],
|
41
49
|
[ :invalid_report_fields,
|
42
50
|
"Field data must be a Hash to pass to the server." ],
|
43
51
|
[ :missing_plugin_id_field,
|
@@ -80,8 +88,15 @@ module ScoutAgent
|
|
80
88
|
end
|
81
89
|
bytes = fields.size
|
82
90
|
begin
|
83
|
-
fields
|
84
|
-
|
91
|
+
if ["{", "["].include? fields[0, 1] # it's JSON
|
92
|
+
fields = JSON.parse(fields)
|
93
|
+
else # it's Marshal
|
94
|
+
fields = Marshal.load(fields)
|
95
|
+
if fields.is_a? Hash # Stringify Hash keys
|
96
|
+
fields = Hash[*fields.map { |k, v| [k.to_s, v] }.flatten]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
rescue Exception
|
85
100
|
abort_with_error(:invalid_fields)
|
86
101
|
end
|
87
102
|
|
data/lib/scout_agent/server.rb
CHANGED
@@ -15,8 +15,12 @@ module ScoutAgent
|
|
15
15
|
@log = log
|
16
16
|
@rest_client = RestClient::Resource.new(
|
17
17
|
Plan.agent_url,
|
18
|
-
:headers
|
19
|
-
|
18
|
+
:headers => { :client_version => ScoutAgent::VERSION,
|
19
|
+
:accept_encoding => "gzip" },
|
20
|
+
:ssl_ca_file => File.join( File.dirname(__FILE__),
|
21
|
+
*%w[.. .. data cacert.pem] ),
|
22
|
+
:verify_ssl => OpenSSL::SSL::VERIFY_PEER |
|
23
|
+
OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
20
24
|
)
|
21
25
|
# make sure proxy is set, if needed
|
22
26
|
RestClient.proxy = Plan.proxy_url
|
@@ -47,6 +51,9 @@ module ScoutAgent
|
|
47
51
|
rescue RestClient::NotModified
|
48
52
|
log.info("Plan was not modified.")
|
49
53
|
"" # empty plan
|
54
|
+
rescue OpenSSL::SSL::SSLError
|
55
|
+
log.warn("SSL verification failed. The plan could not be trusted.")
|
56
|
+
nil # cannot trust any plan we received
|
50
57
|
rescue Exception => error # networking problem
|
51
58
|
log.warn("Plan could not be retrieved: #{error.class}.")
|
52
59
|
nil # failed to retrieve plan
|
@@ -81,6 +88,10 @@ module ScoutAgent
|
|
81
88
|
log.warn( "Check-in was returned as a failure code: " +
|
82
89
|
"#{error.http_code}." )
|
83
90
|
false
|
91
|
+
rescue OpenSSL::SSL::SSLError
|
92
|
+
log.warn( "SSL verification failed. " +
|
93
|
+
"Could not send check-in to untrusted server." )
|
94
|
+
false # cannot trust server
|
84
95
|
rescue Exception => error # networking problem
|
85
96
|
log.warn("Check-in could not be sent: #{error.class}.")
|
86
97
|
false # we failed to send and will retry later
|
@@ -103,7 +114,11 @@ module ScoutAgent
|
|
103
114
|
log.warn( "Log upload was returned as a failure code: " +
|
104
115
|
"#{error.http_code}." )
|
105
116
|
false
|
106
|
-
rescue
|
117
|
+
rescue OpenSSL::SSL::SSLError
|
118
|
+
log.warn( "SSL verification failed. " +
|
119
|
+
"Could not send log to untrusted server." )
|
120
|
+
false # cannot trust server
|
121
|
+
rescue Exception => error # networking problem
|
107
122
|
log.warn("Log could not be sent: #{error.class}.")
|
108
123
|
false # could not send log
|
109
124
|
end
|
data/test/tc_core_extensions.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Edward Gray II
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2009-
|
15
|
+
date: 2009-06-01 00:00:00 -05:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0
|
46
|
+
version: "1.0"
|
47
47
|
version:
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: json
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
requirements:
|
54
54
|
- - "="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: 1.1.
|
56
|
+
version: 1.1.6
|
57
57
|
version:
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: xmpp4r
|
@@ -136,6 +136,9 @@ files:
|
|
136
136
|
- test/ts_all.rb
|
137
137
|
- Rakefile
|
138
138
|
- setup.rb
|
139
|
+
- data/cacert.pem
|
140
|
+
- data/gpl-2.0.txt
|
141
|
+
- data/lgpl-2.1.txt
|
139
142
|
- AUTHORS
|
140
143
|
- COPYING
|
141
144
|
- README
|
@@ -182,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
185
|
requirements: []
|
183
186
|
|
184
187
|
rubyforge_project: scout
|
185
|
-
rubygems_version: 1.3.
|
188
|
+
rubygems_version: 1.3.4
|
186
189
|
signing_key:
|
187
190
|
specification_version: 3
|
188
191
|
summary: Scout makes monitoring and reporting on your servers as flexible and simple as possible.
|