sensu 0.25.0.beta → 0.25.0.rc1

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: be31b512054dbd9dfbcaa26aafd11cafff18cb51
4
- data.tar.gz: 3baad83fdc34d79b765e1145f8d5c44074865bd5
3
+ metadata.gz: 6d58b06b0ce22836e1207b27f5e270e943647acf
4
+ data.tar.gz: cfc35367183ebd01f250d3357498a8eb9eef6f59
5
5
  SHA512:
6
- metadata.gz: 1ce252cc6ecfaccf54a175d61222955df5b269cf60a0dc031cd9cf1e8d9a33b74cb8ed2177bebbf24a0c8dd6e9439a5cd7a8f41d7095b70746cad7e110425f79
7
- data.tar.gz: 7118338b715eafaec7e0fb16d1df8f8256f275b16881d9678d0243e2d63086f86dbdaae8b9abe22f318b3d382aeb3e9984959a7af078a905789c2fb213123157
6
+ metadata.gz: adfef52a3dd93c3f21b4bbf906ce9bbb2d954fdff39113a5efe500b546e5ba965adea6b6c64cf336b42f2e2341534353cef88644146ee2879565f4f51efbc66b
7
+ data.tar.gz: a91f043f664beae6ddab0c3cedece51148533e584a5de451c969c2fd11b022382527c6e2dbaa79a5feafa98a3fc85132fd184e28b80acdfe3abeb0ca9eaaadfe
@@ -1,4 +1,3 @@
1
- require "sensu/api/validators"
2
1
  require "sensu/api/routes"
3
2
 
4
3
  gem "em-http-server", "0.1.8"
@@ -13,39 +12,56 @@ module Sensu
13
12
 
14
13
  attr_accessor :logger, :settings, :redis, :transport
15
14
 
16
- # Log the HTTP request. This method determines the remote
17
- # address for the HTTP client, `@remote_address`. The debug log
18
- # level is used for requests as response logging includes the
19
- # same information.
20
- def log_request
21
- _, @remote_address = Socket.unpack_sockaddr_in(get_peername)
22
- @logger.debug("api request", {
23
- :remote_address => @remote_address,
15
+ # Create a hash containing the HTTP request details. This method
16
+ # determines the remote address for the HTTP client (using
17
+ # EventMachine Connection `get_peername()`).
18
+ #
19
+ # @result [Hash]
20
+ def request_details
21
+ return @request_details if @request_details
22
+ _, remote_address = Socket.unpack_sockaddr_in(get_peername)
23
+ @request_details = {
24
+ :remote_address => remote_address,
24
25
  :user_agent => @http[:user_agent],
25
- :request_method => @http_request_method,
26
- :request_uri => @http_request_uri,
27
- :request_query_string => @http_query_string,
28
- :request_body => @http_content
29
- })
26
+ :method => @http_request_method,
27
+ :uri => @http_request_uri,
28
+ :query_string => @http_query_string,
29
+ :body => @http_content
30
+ }
31
+ if @http[:x_forwarded_for]
32
+ @request_details[:x_forwarded_for] = @http[:x_forwarded_for]
33
+ end
34
+ @request_details
35
+ end
36
+
37
+ # Log the HTTP request. The debug log level is used for requests
38
+ # as response logging includes the same information.
39
+ def log_request
40
+ @logger.debug("api request", request_details)
30
41
  end
31
42
 
32
43
  # Log the HTTP response.
33
44
  def log_response
34
45
  @logger.info("api response", {
35
- :remote_address => @remote_address,
36
- :user_agent => @http[:user_agent],
37
- :request_method => @http_request_method,
38
- :request_uri => @http_request_uri,
39
- :request_query_string => @http_query_string,
40
- :request_body => @http_content,
41
- :response_status => @response.status,
42
- :response_body => @response.content
46
+ :request => request_details,
47
+ :status => @response.status,
48
+ :content_length => @response.content.to_s.bytesize
43
49
  })
44
50
  end
45
51
 
46
- # Parse the HTTP query string for parameters. This method
47
- # creates `@params`, a hash of parsed query parameters, used by
48
- # the API routes.
52
+ # Parse the HTTP request URI using a regular expression,
53
+ # returning the URI unescaped match data values.
54
+ #
55
+ # @param regex [Regexp]
56
+ # @return [Array] URI unescaped match data values.
57
+ def parse_uri(regex)
58
+ uri_match = regex.match(@http_request_uri)[1..-1]
59
+ uri_match.map { |s| URI.unescape(s) }
60
+ end
61
+
62
+ # Parse the HTTP request query string for parameters. This
63
+ # method creates `@params`, a hash of parsed query parameters,
64
+ # used by the API routes.
49
65
  def parse_parameters
50
66
  @params = {}
51
67
  if @http_query_string
@@ -22,13 +22,13 @@ module Sensu
22
22
  end
23
23
  end
24
24
 
25
- # Start the Sensu API HTTP server. This method sets the service
26
- # state to `:running`.
27
- def start
28
- api = @settings[:api] || {}
29
- bind = api[:bind] || "0.0.0.0"
30
- port = api[:port] || 4567
25
+ # Start the API HTTP server. This method sets `@http_server`.
26
+ #
27
+ # @param bind [String] address to listen on.
28
+ # @param port [Integer] to listen on.
29
+ def start_http_server(bind, port)
31
30
  @logger.info("api listening", {
31
+ :protocol => "http",
32
32
  :bind => bind,
33
33
  :port => port
34
34
  })
@@ -38,6 +38,15 @@ module Sensu
38
38
  handler.redis = @redis
39
39
  handler.transport = @transport
40
40
  end
41
+ end
42
+
43
+ # Start the Sensu API HTTP server. This method sets the service
44
+ # state to `:running`.
45
+ def start
46
+ api = @settings[:api] || {}
47
+ bind = api[:bind] || "0.0.0.0"
48
+ port = api[:port] || 4567
49
+ start_http_server(bind, port)
41
50
  super
42
51
  end
43
52
 
@@ -8,6 +8,7 @@ module Sensu
8
8
  AGGREGATE_CHECKS_URI = /^\/aggregates\/([\w\.-]+)\/checks$/
9
9
  AGGREGATE_RESULTS_SEVERITY_URI = /^\/aggregates\/([\w\.-]+)\/results\/([\w\.-]+)$/
10
10
 
11
+ # GET /aggregates
11
12
  def get_aggregates
12
13
  @redis.smembers("aggregates") do |aggregates|
13
14
  aggregates.map! do |aggregate|
@@ -18,8 +19,9 @@ module Sensu
18
19
  end
19
20
  end
20
21
 
22
+ # GET /aggregates/:aggregate
21
23
  def get_aggregate
22
- aggregate = AGGREGATE_URI.match(@http_request_uri)[1]
24
+ aggregate = parse_uri(AGGREGATE_URI).first
23
25
  @redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
24
26
  unless aggregate_members.empty?
25
27
  @response_content = {
@@ -75,8 +77,9 @@ module Sensu
75
77
  end
76
78
  end
77
79
 
80
+ # DELETE /aggregates/:aggregate
78
81
  def delete_aggregate
79
- aggregate = AGGREGATE_URI.match(@http_request_uri)[1]
82
+ aggregate = parse_uri(AGGREGATE_URI).first
80
83
  @redis.smembers("aggregates") do |aggregates|
81
84
  if aggregates.include?(aggregate)
82
85
  @redis.srem("aggregates", aggregate) do
@@ -90,8 +93,9 @@ module Sensu
90
93
  end
91
94
  end
92
95
 
96
+ # GET /aggregates/:aggregate/clients
93
97
  def get_aggregate_clients
94
- aggregate = AGGREGATE_CLIENTS_URI.match(@http_request_uri)[1]
98
+ aggregate = parse_uri(AGGREGATE_CLIENTS_URI).first
95
99
  @response_content = []
96
100
  @redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
97
101
  unless aggregate_members.empty?
@@ -114,8 +118,9 @@ module Sensu
114
118
  end
115
119
  end
116
120
 
121
+ # GET /aggregates/:aggregate/checks
117
122
  def get_aggregate_checks
118
- aggregate = AGGREGATE_CHECKS_URI.match(@http_request_uri)[1]
123
+ aggregate = parse_uri(AGGREGATE_CHECKS_URI).first
119
124
  @response_content = []
120
125
  @redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
121
126
  unless aggregate_members.empty?
@@ -138,14 +143,13 @@ module Sensu
138
143
  end
139
144
  end
140
145
 
146
+ # GET /aggregates/:aggregate/results/:severity
141
147
  def get_aggregate_results_severity
142
- uri_match = AGGREGATE_RESULTS_SEVERITY_URI.match(@http_request_uri)
143
- aggregate = uri_match[1]
144
- severity = uri_match[2]
145
- @response_content = []
148
+ aggregate, severity = parse_uri(AGGREGATE_RESULTS_SEVERITY_URI)
146
149
  if SEVERITIES.include?(severity)
147
150
  @redis.smembers("aggregates:#{aggregate}") do |aggregate_members|
148
151
  unless aggregate_members.empty?
152
+ @response_content = []
149
153
  summaries = Hash.new
150
154
  max_age = integer_parameter(@params[:max_age])
151
155
  current_timestamp = Time.now.to_i
@@ -5,13 +5,15 @@ module Sensu
5
5
  CHECKS_URI = /^\/checks$/
6
6
  CHECK_URI = /^\/checks\/([\w\.-]+)$/
7
7
 
8
+ # GET /checks
8
9
  def get_checks
9
10
  @response_content = @settings.checks
10
11
  respond
11
12
  end
12
13
 
14
+ # GET /checks/:check_name
13
15
  def get_check
14
- check_name = CHECK_URI.match(@http_request_uri)[1]
16
+ check_name = parse_uri(CHECK_URI).first
15
17
  if @settings[:checks][check_name]
16
18
  @response_content = @settings[:checks][check_name].merge(:name => check_name)
17
19
  respond
@@ -1,3 +1,4 @@
1
+ require "sensu/api/validators/client"
1
2
  require "sensu/api/utilities/resolve_event"
2
3
 
3
4
  module Sensu
@@ -10,6 +11,7 @@ module Sensu
10
11
  CLIENT_URI = /^\/clients\/([\w\.-]+)$/
11
12
  CLIENT_HISTORY_URI = /^\/clients\/([\w\.-]+)\/history$/
12
13
 
14
+ # POST /clients
13
15
  def post_clients
14
16
  read_data do |client|
15
17
  client[:keepalives] = client.fetch(:keepalives, false)
@@ -29,6 +31,7 @@ module Sensu
29
31
  end
30
32
  end
31
33
 
34
+ # GET /clients
32
35
  def get_clients
33
36
  @response_content = []
34
37
  @redis.smembers("clients") do |clients|
@@ -53,8 +56,9 @@ module Sensu
53
56
  end
54
57
  end
55
58
 
59
+ # GET /clients/:client_name
56
60
  def get_client
57
- client_name = CLIENT_URI.match(@http_request_uri)[1]
61
+ client_name = parse_uri(CLIENT_URI).first
58
62
  @redis.get("client:#{client_name}") do |client_json|
59
63
  unless client_json.nil?
60
64
  @response_content = Sensu::JSON.load(client_json)
@@ -65,8 +69,9 @@ module Sensu
65
69
  end
66
70
  end
67
71
 
72
+ # GET /clients/:client_name/history
68
73
  def get_client_history
69
- client_name = CLIENT_HISTORY_URI.match(@http_request_uri)[1]
74
+ client_name = parse_uri(CLIENT_HISTORY_URI).first
70
75
  @response_content = []
71
76
  @redis.smembers("result:#{client_name}") do |checks|
72
77
  unless checks.empty?
@@ -104,8 +109,9 @@ module Sensu
104
109
  end
105
110
  end
106
111
 
112
+ # DELETE /clients/:client_name
107
113
  def delete_client
108
- client_name = CLIENT_URI.match(@http_request_uri)[1]
114
+ client_name = parse_uri(CLIENT_URI).first
109
115
  @redis.get("client:#{client_name}") do |client_json|
110
116
  unless client_json.nil?
111
117
  @redis.hgetall("events:#{client_name}") do |events|
@@ -10,6 +10,7 @@ module Sensu
10
10
  EVENTS_CLIENT_URI = /^\/events\/([\w\.-]+)$/
11
11
  EVENT_URI = /^\/events\/([\w\.-]+)\/([\w\.-]+)$/
12
12
 
13
+ # GET /events
13
14
  def get_events
14
15
  @response_content = []
15
16
  @redis.smembers("clients") do |clients|
@@ -30,8 +31,9 @@ module Sensu
30
31
  end
31
32
  end
32
33
 
34
+ # GET /events/:client_name
33
35
  def get_events_client
34
- client_name = EVENTS_CLIENT_URI.match(@http_request_uri)[1]
36
+ client_name = parse_uri(EVENTS_CLIENT_URI).first
35
37
  @response_content = []
36
38
  @redis.hgetall("events:#{client_name}") do |events|
37
39
  events.each do |check_name, event_json|
@@ -41,10 +43,9 @@ module Sensu
41
43
  end
42
44
  end
43
45
 
46
+ # GET /events/:client_name/:check_name
44
47
  def get_event
45
- uri_match = EVENT_URI.match(@http_request_uri)
46
- client_name = uri_match[1]
47
- check_name = uri_match[2]
48
+ client_name, check_name = parse_uri(EVENT_URI)
48
49
  @redis.hgetall("events:#{client_name}") do |events|
49
50
  event_json = events[check_name]
50
51
  unless event_json.nil?
@@ -56,10 +57,9 @@ module Sensu
56
57
  end
57
58
  end
58
59
 
60
+ # DELETE /events/:client_name/:check_name
59
61
  def delete_event
60
- uri_match = EVENT_URI.match(@http_request_uri)
61
- client_name = uri_match[1]
62
- check_name = uri_match[2]
62
+ client_name, check_name = parse_uri(EVENT_URI)
63
63
  @redis.hgetall("events:#{client_name}") do |events|
64
64
  if events.include?(check_name)
65
65
  resolve_event(events[check_name])
@@ -8,6 +8,7 @@ module Sensu
8
8
 
9
9
  HEALTH_URI = /^\/health$/
10
10
 
11
+ # GET /health
11
12
  def get_health
12
13
  if @redis.connected? && @transport.connected?
13
14
  healthy = []
@@ -8,6 +8,7 @@ module Sensu
8
8
 
9
9
  INFO_URI = /^\/info$/
10
10
 
11
+ # GET /info
11
12
  def get_info
12
13
  transport_info do |info|
13
14
  @response_content = {
@@ -8,6 +8,7 @@ module Sensu
8
8
 
9
9
  REQUEST_URI = /^\/request$/
10
10
 
11
+ # POST /request
11
12
  def post_request
12
13
  rules = {
13
14
  :check => {:type => String, :nil_ok => false},
@@ -8,6 +8,7 @@ module Sensu
8
8
 
9
9
  RESOLVE_URI = /^\/resolve$/
10
10
 
11
+ # POST /resolve
11
12
  def post_resolve
12
13
  rules = {
13
14
  :client => {:type => String, :nil_ok => false},
@@ -10,6 +10,7 @@ module Sensu
10
10
  RESULTS_CLIENT_URI = /^\/results\/([\w\.-]+)$/
11
11
  RESULT_URI = /^\/results\/([\w\.-]+)\/([\w\.-]+)$/
12
12
 
13
+ # POST /results
13
14
  def post_results
14
15
  rules = {
15
16
  :name => {:type => String, :nil_ok => false, :regex => /\A[\w\.-]+\z/},
@@ -24,6 +25,7 @@ module Sensu
24
25
  end
25
26
  end
26
27
 
28
+ # GET /results
27
29
  def get_results
28
30
  @response_content = []
29
31
  @redis.smembers("clients") do |clients|
@@ -54,8 +56,9 @@ module Sensu
54
56
  end
55
57
  end
56
58
 
59
+ # GET /results/:client_name
57
60
  def get_results_client
58
- client_name = RESULTS_CLIENT_URI.match(@http_request_uri)[1]
61
+ client_name = parse_uri(RESULTS_CLIENT_URI).first
59
62
  @response_content = []
60
63
  @redis.smembers("result:#{client_name}") do |checks|
61
64
  unless checks.empty?
@@ -72,15 +75,14 @@ module Sensu
72
75
  end
73
76
  end
74
77
  else
75
- not_found!
78
+ respond
76
79
  end
77
80
  end
78
81
  end
79
82
 
83
+ # GET /results/:client_name/:check_name
80
84
  def get_result
81
- uri_match = RESULT_URI.match(@http_request_uri)
82
- client_name = uri_match[1]
83
- check_name = uri_match[2]
85
+ client_name, check_name = parse_uri(RESULT_URI)
84
86
  result_key = "result:#{client_name}:#{check_name}"
85
87
  @redis.get(result_key) do |result_json|
86
88
  unless result_json.nil?
@@ -93,10 +95,9 @@ module Sensu
93
95
  end
94
96
  end
95
97
 
98
+ # DELETE /results/:client_name/:check_name
96
99
  def delete_result
97
- uri_match = RESULT_URI.match(@http_request_uri)
98
- client_name = uri_match[1]
99
- check_name = uri_match[2]
100
+ client_name, check_name = parse_uri(RESULT_URI)
100
101
  result_key = "result:#{client_name}:#{check_name}"
101
102
  @redis.exists(result_key) do |result_exists|
102
103
  if result_exists
@@ -5,8 +5,9 @@ module Sensu
5
5
  STASHES_URI = /^\/stashes$/
6
6
  STASH_URI = /^\/stash(?:es)?\/(.*)$/
7
7
 
8
+ # POST /stash/:path or /stashes/:path
8
9
  def post_stash
9
- path = STASH_URI.match(@http_request_uri)[1]
10
+ path = parse_uri(STASH_URI).first
10
11
  read_data do |data|
11
12
  @redis.set("stash:#{path}", Sensu::JSON.dump(data)) do
12
13
  @redis.sadd("stashes", path) do
@@ -17,8 +18,9 @@ module Sensu
17
18
  end
18
19
  end
19
20
 
21
+ # GET /stash/:path or /stashes/:path
20
22
  def get_stash
21
- path = STASH_URI.match(@http_request_uri)[1]
23
+ path = parse_uri(STASH_URI).first
22
24
  @redis.get("stash:#{path}") do |stash_json|
23
25
  unless stash_json.nil?
24
26
  @response_content = Sensu::JSON.load(stash_json)
@@ -29,8 +31,9 @@ module Sensu
29
31
  end
30
32
  end
31
33
 
34
+ # DELETE /stash/:path or /stashes/:path
32
35
  def delete_stash
33
- path = STASH_URI.match(@http_request_uri)[1]
36
+ path = parse_uri(STASH_URI).first
34
37
  @redis.exists("stash:#{path}") do |stash_exists|
35
38
  if stash_exists
36
39
  @redis.srem("stashes", path) do
@@ -44,6 +47,7 @@ module Sensu
44
47
  end
45
48
  end
46
49
 
50
+ # GET /stashes
47
51
  def get_stashes
48
52
  @response_content = []
49
53
  @redis.smembers("stashes") do |stashes|
@@ -74,6 +78,7 @@ module Sensu
74
78
  end
75
79
  end
76
80
 
81
+ # POST /stashes
77
82
  def post_stashes
78
83
  rules = {
79
84
  :path => {:type => String, :nil_ok => false},
@@ -1,12 +1,10 @@
1
+ require "sensu/api/validators/invalid"
1
2
  require "sensu/settings/rules"
2
3
  require "sensu/settings/validators/client"
3
4
 
4
5
  module Sensu
5
6
  module API
6
7
  module Validators
7
- # The error class for validation.
8
- class Invalid < RuntimeError; end
9
-
10
8
  class Client
11
9
  # Include Sensu Settings rules and client validator.
12
10
  include Sensu::Settings::Rules
@@ -0,0 +1,8 @@
1
+ module Sensu
2
+ module API
3
+ module Validators
4
+ # The error class for validation.
5
+ class Invalid < RuntimeError; end
6
+ end
7
+ end
8
+ end
@@ -131,21 +131,24 @@ module Sensu
131
131
  # the result. This method guards against multiple executions for
132
132
  # the same check. Check attribute value tokens are substituted
133
133
  # with the associated client attribute values, via
134
- # `object_substitute_tokens()`. If there are unmatched check
135
- # attribute value tokens, the check will not be executed,
136
- # instead a check result will be published reporting the
137
- # unmatched tokens.
134
+ # `object_substitute_tokens()`. The original check command is
135
+ # always published, to guard against publishing
136
+ # sensitive/redacted client attribute values. If there are
137
+ # unmatched check attribute value tokens, the check will not be
138
+ # executed, instead a check result will be published reporting
139
+ # the unmatched tokens.
138
140
  #
139
141
  # @param check [Hash]
140
142
  def execute_check_command(check)
141
143
  @logger.debug("attempting to execute check command", :check => check)
142
144
  unless @checks_in_progress.include?(check[:name])
143
145
  @checks_in_progress << check[:name]
144
- check, unmatched_tokens = object_substitute_tokens(check)
146
+ substituted, unmatched_tokens = object_substitute_tokens(check.dup)
147
+ check = substituted.merge(:command => check[:command])
145
148
  if unmatched_tokens.empty?
146
149
  started = Time.now.to_f
147
150
  check[:executed] = started.to_i
148
- Spawn.process(check[:command], :timeout => check[:timeout]) do |output, status|
151
+ Spawn.process(substituted[:command], :timeout => check[:timeout]) do |output, status|
149
152
  check[:duration] = ("%.3f" % (Time.now.to_f - started)).to_f
150
153
  check[:output] = output
151
154
  check[:status] = status
@@ -1,7 +1,7 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
3
  # Sensu release version.
4
- VERSION = "0.25.0.beta".freeze
4
+ VERSION = "0.25.0.rc1".freeze
5
5
 
6
6
  # Sensu check severities.
7
7
  SEVERITIES = %w[ok warning critical unknown].freeze
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0.beta
4
+ version: 0.25.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Porter
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-06-10 00:00:00.000000000 Z
12
+ date: 2016-06-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -244,7 +244,8 @@ files:
244
244
  - lib/sensu/api/utilities/publish_check_result.rb
245
245
  - lib/sensu/api/utilities/resolve_event.rb
246
246
  - lib/sensu/api/utilities/transport_info.rb
247
- - lib/sensu/api/validators.rb
247
+ - lib/sensu/api/validators/client.rb
248
+ - lib/sensu/api/validators/invalid.rb
248
249
  - lib/sensu/cli.rb
249
250
  - lib/sensu/client/process.rb
250
251
  - lib/sensu/client/socket.rb