bin/check-marathon-task.rb in sensu-plugins-mesos-2.0.0 vs bin/check-marathon-task.rb in sensu-plugins-mesos-2.1.0

- old
+ new

@@ -28,17 +28,17 @@ # Released under the same terms as Sensu (the MIT license); see LICENSE # for details. # require 'sensu-plugin/check/cli' -require 'net/http' +require 'rest-client' require 'json' # This plugin checks that the given Mesos/Marathon task is running properly. # # This means that all of the following is true: -# 1. There are N tasks for the app, as defined by the --instances parameter +# 1. There are N tasks for the app, as defined by the --instances parameter or checks configured tasks in Marathon as fallback # 2. Each task's state is running # 3. No task is unhealthy, as defined in Marathon # # A task is seen as **unhealthy** by Marathon if any of the health checks for # the task is not **alive**. Alive means that a check has a last success that @@ -69,11 +69,12 @@ required: true option :instances, short: '-i INSTANCES', long: '--instances INSTANCES', - required: true, + required: false, + default: 0, proc: proc(&:to_i) option :protocol, short: '-P PROTOCOL', long: '--protocol PROTOCOL', @@ -87,47 +88,43 @@ option :password, long: '--password PASSWORD', required: false - def run - if config[:instances].zero? - unknown 'number of instances should be an integer' - end + option :timeout, + description: 'timeout in seconds', + short: '-T TIMEOUT', + long: '--timeout TIMEOUT', + proc: proc(&:to_i), + default: 5 + def run if !config[:username].nil? && config[:password].nil? || config[:username].nil? && !config[:password].nil? unknown 'You must provide both username and password' end failures = [] uri = config[:uri] config[:server].split(',').each do |s| begin - url = URI.parse("#{config[:protocol]}://#{s}:#{config[:port]}#{uri}") - req = Net::HTTP::Get.new(url) - req.add_field('Accept', 'application/json') - if !config[:username].nil? && !config[:password].nil? - req.basic_auth(config[:username], config[:password]) - end - r = Net::HTTP.start(url.host, url.port, - use_ssl: config[:protocol] == 'https') do |h| - h.request(req) - end + auth_headers = {} + auth_headers = { Authorization: "#{config[:username]} #{config[:password]}" } if !config[:username].nil? && !config[:password].nil? + r = RestClient::Resource.new("#{config[:protocol]}://#{s}:#{config[:port]}#{uri}", auth_headers, config[:timeout]).get + expected = if config[:instances].zero? + default_tasks(s) + else + config[:instances] + end + ok_count, unhealthy = check_tasks r - ok_count, unhealthy = check_tasks r.body + message = "#{ok_count}/#{expected} #{config[:task]} tasks running" - message = "#{ok_count}/#{config[:instances]} #{config[:task]} tasks running" + message << ":\n" << unhealthy.join("\n") if unhealthy.any? - if unhealthy.any? - message << ":\n" << unhealthy.join("\n") - end + critical message if unhealthy.any? || ok_count < config[:instances] - if unhealthy.any? || ok_count < config[:instances] - critical message - end - ok message rescue Errno::ECONNREFUSED, SocketError failures << "Marathon on #{s} could not be reached" rescue => err failures << "error caught trying to reach Marathon on #{s}: #{err}" @@ -170,7 +167,16 @@ unhealthy << message end end [tasks.length, unhealthy] + end + + def default_tasks(server) + expected_tasks_url = "/v2/apps/#{config[:task]}" + auth_headers = {} + auth_headers = { Authorization: "#{config[:username]} #{config[:password]}" } if !config[:username].nil? && !config[:password].nil? + r = RestClient::Resource.new("#{config[:protocol]}://#{server}:#{config[:port]}#{expected_tasks_url}", auth_headers, config[:timeout]).get + n_tasks = JSON.parse(r)['app']['instances'] + n_tasks end end