scout 5.2.2 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,9 @@
1
- == 5.2.2
1
+ == 5.3.0
2
+
3
+ * Ping over http instead of https. All plan retrievals and check-ins are still SSL
4
+ * Added ability to post troubleshooting report back to scoutapp.com
5
+
6
+ == 5.2.2
2
7
 
3
8
  * More graceful handling of *rare* client_history.yaml corruption
4
9
 
data/lib/scout.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby -wKU
2
2
 
3
3
  module Scout
4
- VERSION = "5.2.2".freeze
4
+ VERSION = "5.3.0".freeze
5
5
  end
6
6
 
7
7
  require "scout/command"
data/lib/scout/command.rb CHANGED
@@ -37,8 +37,8 @@ module Scout
37
37
  opts.separator " ... OR ..."
38
38
  opts.separator " #{program_name} [OPTIONS] install"
39
39
  opts.separator " Troubleshoot:"
40
- opts.separator " #{program_name} troubleshoot"
41
- opts.separator " ... print Scout environment info. Recommend directing output to a file."
40
+ opts.separator " #{program_name} [OPTIONS] troubleshoot"
41
+ opts.separator " ... print troubleshooting info, or post it back to scoutapp.com."
42
42
  opts.separator " Local plugin testing:"
43
43
  opts.separator " #{program_name} [OPTIONS] test " +
44
44
  "PATH_TO_PLUGIN [PLUGIN_OPTIONS]"
@@ -88,6 +88,16 @@ module Scout
88
88
  options[:force] = bool
89
89
  end
90
90
 
91
+ opts.separator " "
92
+ opts.separator "Troubleshooting Options:"
93
+ opts.separator "--------------------------------------------------------------------------"
94
+ opts.on( "--post", "For use with 'troubleshoot' - post the troubleshooting results back to scoutapp.com") do
95
+ options[:troubleshoot_post] = true
96
+ end
97
+ opts.on( "--no-history", "For use with 'troubleshoot' - don't include the history file contents.") do
98
+ options[:troubleshoot_no_history] = true
99
+ end
100
+
91
101
  opts.separator " "
92
102
  opts.separator "Examples: "
93
103
  opts.separator "--------------------------------------------------------------------------"
@@ -1,12 +1,25 @@
1
1
  #!/usr/bin/env ruby -wKU
2
2
 
3
- require "pp"
3
+ require "uri"
4
+ require "socket"
5
+ require "net/https"
6
+ require "timeout"
7
+
4
8
 
5
9
  module Scout
6
10
  class Command
11
+ class APITimeoutError < RuntimeError; end
12
+
13
+ HTTP_HEADERS = { "Client-Version" => Scout::VERSION,
14
+ "Client-Hostname" => Socket.gethostname}
15
+
7
16
  class Troubleshoot < Command
17
+
8
18
  def initialize(options, args)
19
+ @post = options[:troubleshoot_post]
20
+ @include_history = !options[:troubleshoot_no_history]
9
21
  @contents=[]
22
+ options[:verbose]=true # force verbose logging for this command
10
23
  super
11
24
  end
12
25
 
@@ -32,19 +45,31 @@ module Scout
32
45
  heading "Installed Gems"
33
46
  text `gem list --local`
34
47
 
35
- heading "History file Contents"
36
- contents=File.read(history) rescue "History not found at #{log_path}"
37
- text contents
48
+
49
+ if @include_history
50
+ heading "History file Contents"
51
+ contents=File.read(history) rescue "History not found at #{log_path}"
52
+ text contents
53
+ else
54
+ heading "Skipping History file Contents"
55
+ end
38
56
 
39
57
  heading "Agent directory Contents"
40
58
  text `ls -la #{config_dir}`
41
59
 
42
60
  heading ""
43
61
 
44
- puts "Done"
45
-
46
- puts @contents.join("\n")
47
-
62
+ if @post
63
+ puts "Posting troubleshooting info to #{@server} ... "
64
+ url = URI.join( @server,"/admin/troubleshooting_reports")
65
+ post_form(url, "Couldn't contact server at #{@server}",{:body=>contents_as_text}) do |res|
66
+ puts "Scout server says: \"#{res.body}\""
67
+ end
68
+ else
69
+ puts contents_as_text
70
+ end
71
+
72
+ puts " ... Done"
48
73
  end
49
74
  end
50
75
 
@@ -61,5 +86,57 @@ module Scout
61
86
  @contents << s
62
87
  end
63
88
 
89
+ def contents_as_text
90
+ @contents.join("\n")
91
+ end
92
+
93
+ def post_form(url, error, form_data, headers = Hash.new, &response_handler)
94
+ return unless url
95
+ request(url, response_handler, error) do |connection|
96
+ post = Net::HTTP::Post.new( url.path +
97
+ (url.query ? ('?' + url.query) : ''),
98
+ HTTP_HEADERS.merge(headers) )
99
+ post.set_form_data(form_data)
100
+ connection.request(post)
101
+ end
102
+ end
103
+
104
+ def request(url, response_handler, error, &connector)
105
+ response = nil
106
+ Timeout.timeout(5 * 60, APITimeoutError) do
107
+ http = Net::HTTP.new(url.host, url.port)
108
+ if url.is_a? URI::HTTPS
109
+ http.use_ssl = true
110
+ http.ca_file = File.join( File.dirname(__FILE__),
111
+ *%w[.. .. data cacert.pem] )
112
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER |
113
+ OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
114
+ end
115
+ response = no_warnings { http.start(&connector) }
116
+ end
117
+ case response
118
+ when Net::HTTPSuccess, Net::HTTPNotModified
119
+ response_handler[response] unless response_handler.nil?
120
+ else
121
+ error = "Server says: #{response['x-scout-msg']}" if response['x-scout-msg']
122
+ log.fatal error
123
+ raise SystemExit.new(error)
124
+ end
125
+ rescue Timeout::Error
126
+ log.fatal "Request timed out."
127
+ exit
128
+ rescue Exception
129
+ raise if $!.is_a? SystemExit
130
+ log.fatal "An HTTP error occurred: #{$!.message}"
131
+ exit
132
+ end
133
+
134
+ def no_warnings
135
+ old_verbose = $VERBOSE
136
+ $VERBOSE = false
137
+ yield
138
+ ensure
139
+ $VERBOSE = old_verbose
140
+ end
64
141
  end
65
142
  end
data/lib/scout/server.rb CHANGED
@@ -62,6 +62,26 @@ module Scout
62
62
  end
63
63
  end
64
64
 
65
+ def refresh?
66
+ return true if !ping_key
67
+
68
+ url=URI.join( @server.sub("https://","http://"), "/clients/#{ping_key}/ping.scout")
69
+
70
+ headers = {"x-scout-tty" => ($stdin.tty? ? 'true' : 'false')}
71
+ if @history["plan_last_modified"] and @history["old_plugins"]
72
+ headers["If-Modified-Since"] = @history["plan_last_modified"]
73
+ end
74
+ get(url, "Could not ping #{url} for refresh info", headers) do |res|
75
+ if res.is_a?(Net::HTTPNotModified)
76
+ return false
77
+ else
78
+ info "Plan has been modified!"
79
+ return true
80
+ end
81
+ end
82
+ end
83
+
84
+
65
85
  #
66
86
  # Retrieves the Plugin Plan from the server. This is the list of plugins
67
87
  # to execute, along with all options.
@@ -70,23 +90,13 @@ module Scout
70
90
  # 1) it sets the @plugin_plan with either A) whatever is in history, B) the results of the /plan retrieval
71
91
  # 2) it sets @checkin_to = true IF so directed by the scout server
72
92
  def fetch_plan
73
- url = urlify(:plan)
74
- info "Pinging server at #{url}..."
75
- headers = {"x-scout-tty" => ($stdin.tty? ? 'true' : 'false')}
93
+ if refresh?
76
94
 
77
- if @history["plan_last_modified"] and @history["old_plugins"]
78
- headers["If-Modified-Since"] = @history["plan_last_modified"]
79
- end
80
- get(url, "Could not retrieve plan from server.", headers) do |res|
81
- if res.is_a? Net::HTTPNotModified
82
- info "Plan not modified. Will reuse saved plan."
83
- @plugin_plan = Array(@history["old_plugins"])
84
- # Add local plugins to the plan. Note that local plugins are NOT saved to history file
85
- @plugin_plan += get_local_plugins
86
- @directives = @history["directives"] || Hash.new
95
+ url = urlify(:plan)
96
+ info "Fetching plan from server at #{url}..."
97
+ headers = {"x-scout-tty" => ($stdin.tty? ? 'true' : 'false')}
87
98
 
88
- else
89
- info "plan has been modified. Will run the new plan now."
99
+ get(url, "Could not retrieve plan from server.", headers) do |res|
90
100
  begin
91
101
  body = res.body
92
102
  if res["Content-Encoding"] == "gzip" and body and not body.empty?
@@ -144,6 +154,11 @@ module Scout
144
154
  exit
145
155
  end
146
156
  end
157
+ else
158
+ info "Plan not modified."
159
+ @plugin_plan = Array(@history["old_plugins"])
160
+ @plugin_plan += get_local_plugins
161
+ @directives = @history["directives"] || Hash.new
147
162
  end
148
163
  end
149
164
 
@@ -174,6 +189,10 @@ module Scout
174
189
  (@history['directives'] || {})['sleep_interval'].to_f
175
190
  end
176
191
 
192
+ def ping_key
193
+ (@history['directives'] || {})['ping_key']
194
+ end
195
+
177
196
  # uses values from history and current time to determine if we should checkin at this time
178
197
  def time_to_checkin?
179
198
  @history['last_checkin'] == nil ||
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 5
8
- - 2
9
- - 2
10
- version: 5.2.2
8
+ - 3
9
+ - 0
10
+ version: 5.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Scout Monitoring
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-01 00:00:00 -08:00
18
+ date: 2011-03-07 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency