#!/usr/bin/env ruby # frozen_string_literal: false # # check-whois-domain-expiration-multi # # DESCRIPTION: # This plugin checks domain expiration dates using the 'whois' gem. # # OUTPUT: # plain text # # PLATFORMS: # *nix systems # # DEPENDENCIES: # gem: sensu-plugin # gem: whois # # USAGE: # ./check-whois-domain-expiration-multi.rb -d therealtimsmith.com,mightyoakspreschool.com # WhoisDomainExpirationCheck WARNING: mightyoakspreschool.com: 30 days # # LICENSE: # Copyright 2015 Tim Smith (tim@cozy.co) - Cozy Services Ltd. # Based on check-whois-domain-expiration, Copyright 2015 michael j talarczyk # and contributors. # Released under the same terms as Sensu (the MIT license); see LICENSE # for details. require 'sensu-plugin/check/cli' require 'whois' require 'whois-parser' # # Check Whois domain expiration # class WhoisDomainExpirationCheck < Sensu::Plugin::Check::CLI option :domain, short: '-d DOMAINS', long: '--domains DOMAIN', required: true, description: 'Domain(s) to check. Separate by commas for 2+' option :warning, short: '-w DAYS', long: '--warn DAYS', default: 30, proc: proc(&:to_i), description: 'Warn if fewer than DAYS away' option :critical, short: '-c DAYS', long: '--critical DAYS', proc: proc(&:to_i), default: 7, description: 'Critical if fewer than DAYS away' option :'ignore-errors', short: '-i', long: '--ignore-errors', boolean: true, default: false, description: 'Ignore connection or parsing errors' option :'report-errors', short: '-r LEVEL', long: '--report-errors LEVEL', proc: proc(&:to_sym), in: %i[unknown warning critical], default: :unknown, description: 'Level for reporting connection or parsing errors' option :timeout, short: '-t SECONDS', long: '--timeout SECONDS', proc: proc(&:to_i), default: 10, description: 'Timeout for whois lookup' option :help, short: '-h', long: '--help', description: 'Show this message', on: :tail, boolean: true, show_options: true, exit: 0 # split the provided domain list and perform whois lookups on each # return a hash with domains grouped by their status level def expiration_results domains = config[:domain].split(',') warning_days = config[:warning].to_i critical_days = config[:critical].to_i max_retries = 4 results = { critical: {}, warning: {}, ok: {}, unknown: {} } whois = Whois::Client.new(timeout: config[:timeout]) domains.each do |domain| begin tries ||= 0 whois_result = whois.lookup(domain).parser rescue Timeout::Error, Errno::ECONNRESET, Whois::ConnectionError tries += 1 if tries < max_retries retry else results[:unknown][domain] = 'Connection error' unless config[:'ignore-errors'] next end end begin expires_on = DateTime.parse(whois_result.expires_on.to_s) domain_result = (expires_on - DateTime.now).to_i if domain_result <= critical_days results[:critical][domain] = domain_result elsif domain_result <= warning_days results[:warning][domain] = domain_result else results[:ok][domain] = domain_result end rescue StandardError results[:unknown][domain] = 'Parsing error' unless config[:'ignore-errors'] end end results end def run results = expiration_results warn_results = results[:critical].merge(results[:warning]).map { |u, v| "#{u} (#{v} days left)" } unknown_results = results[:unknown].map { |u, v| "#{u} (#{v})" } message warn_results.concat(unknown_results).join(', ') if !results[:critical].empty? || (!results[:unknown].empty? && config[:'report-errors'] == :critical) critical elsif !results[:warning].empty? || (!results[:unknown].empty? && config[:'report-errors'] == :warning) warning elsif !results[:unknown].empty? unknown else ok 'No domains expire in the near term' end end end