#! /usr/bin/env ruby # # check-jenkins-job-status # # DESCRIPTION: # Query jenkins API asking for job status # # OUTPUT: # plain text # # PLATFORMS: # Linux # # DEPENDENCIES: # gem: sensu-plugin # jenkins_api_client # # USAGE: # #YELLOW # # NOTES: # #YELLOW # add url to job's log for CRITICAL state # # LICENSE: # Copyright 2014 SUSE, GmbH # Released under the same terms as Sensu (the MIT license); see LICENSE # for details. # require 'sensu-plugin/check/cli' require 'jenkins_api_client' # # Jenkins Job Check # class JenkinsJobChecker < Sensu::Plugin::Check::CLI option :server_api_url, description: 'hostname running Jenkins API', short: '-u JENKINS-API-HOST', long: '--url JENKINS-API-HOST', required: true option :job_list, description: 'Name of a job/pattern to query. Wrap with quotes. E.g. \'^GCC\'', short: '-j JOB-LIST', long: '--jobs JOB-LIST', required: true option :client_log_level, description: 'log level option 0..3 to client', short: '-v CLIENT-LOG-LEVEL', long: '--verbose CLIENT-LOG-LEVEL', default: 3 option :username, description: 'Username for Jenkins instance', short: '-U USERNAME', long: '--username USERNAME', required: false option :password, description: "Password for Jenkins instance. Either set ENV['JENKINS_PASS'] or provide it as an option", short: '-p PASSWORD', long: '--password PASSWORD', required: false, default: ENV['JENKINS_PASS'] option :include_warnings, description: 'whether to report unstable jobs as a warning', short: '-w', long: '--include-warnings', boolean: true, required: false, default: false def run if failed_jobs.any? critical "Jobs reporting failure: #{failed_job_names}, jobs reported as unstable: #{unstable_job_names}" elsif unstable_jobs.any? && config[:include_warnings] warning "Jobs reported as unstable: #{unstable_job_names}" else ok 'All queried jobs report success' end end private def jenkins_api_client @jenkins_api_client ||= JenkinsApi::Client.new( server_url: config[:server_api_url], log_level: config[:client_log_level].to_i, username: config[:username], password: config[:password] ) end def jobs_statuses @job_listing ||= if config[:job_list] =~ /\^/ jenkins_api_client.job.list(config[:job_list]).reduce({}) do |listing, job_name| # rubocop:disable Style/EachWithObject listing[job_name] = job_status(job_name) listing end else { config[:job_list] => job_status(config[:job_list]) } end end def job_status(job_name) status = jenkins_api_client.job.get_current_build_status(job_name) # If the job is currently running, get the status of the last build instead if status == 'running' build = jenkins_api_client.job.get_build_details(job_name, 'lastCompletedBuild') if build && build['result'] status = build['result'].downcase end end status rescue critical "Error looking up Jenkins job: #{job_name}" end def unstable_jobs jobs_statuses.select { |_job_name, status| status == 'unstable' } end def failed_jobs jobs_statuses.select { |_job_name, status| status == 'failure' } end def unstable_job_names unstable_jobs.keys.join(', ') end def failed_job_names failed_jobs.keys.join(', ') end end