sensu 0.25.0.beta → 0.25.0.rc1

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: 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