bin/check-consul-leader.rb
#! /usr/bin/env ruby
# frozen_string_literal: true
#
# check-consul-leader
#
# DESCRIPTION:
# This plugin checks if consul is up and reachable. It then checks
# the status/leader and ensures there is a current leader.
#
# OUTPUT:
# plain text
#
# PLATFORMS:
# Linux
#
# DEPENDENCIES:
# gem: sensu-plugin
# gem: rest-client
#
# USAGE:
# #YELLOW
#
# NOTES:
#
# LICENSE:
# Copyright 2015 Sonian, Inc. and contributors. <support@sensuapp.org>
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
#
require 'sensu-plugin/check/cli'
require 'rest-client'
require 'resolv'
#
# Consul Status
#
class ConsulStatus < Sensu::Plugin::Check::CLI
option :server,
description: 'consul server',
short: '-s SERVER',
long: '--server SERVER',
default: '127.0.0.1'
option :port,
description: 'consul http port',
short: '-p PORT',
long: '--port PORT',
default: '8500'
option :scheme,
description: 'consul listener scheme',
short: '-S SCHEME',
long: '--scheme SCHEME',
default: 'http'
option :insecure,
description: 'set this flag to disable SSL verification',
short: '-k',
long: '--insecure',
boolean: true,
default: false
option :capath,
description: 'absolute path to an alternative CA file',
short: '-c CAPATH',
long: '--capath CAPATH'
option :timeout,
description: 'connection will time out after this many seconds',
short: '-t TIMEOUT_IN_SECONDS',
long: '--timeout TIMEOUT_IN_SECONDS',
proc: proc { |t| t.to_i },
default: 5
option :token,
description: 'ACL token',
long: '--token ACL_TOKEN'
def valid_ip(ip)
case ip.to_s
when Resolv::IPv4::Regex
true
when Resolv::IPv6::Regex
true
else
false
end
end
def strip_ip(str)
ipv4_regex = '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
ipv6_regex = '\[.*\]'
if str =~ /^.*#{ipv4_regex}.*$/ # rubocop:disable Style/GuardClause
return str.match(/#{ipv4_regex}/)
elsif str =~ /^.*#{ipv6_regex}.*$/
return str[/#{ipv6_regex}/][1..-2]
else
return str
end
end
def run
options = { timeout: config[:timeout],
verify_ssl: (OpenSSL::SSL::VERIFY_NONE if defined? config[:insecure]),
ssl_ca_file: (config[:capath] if defined? config[:capath]),
headers: { 'X-Consul-Token' => config[:token] } }
url = "#{config[:scheme]}://#{config[:server]}:#{config[:port]}/v1/status/leader"
r = RestClient::Resource.new(url, options).get
if r.code == 200
if valid_ip(strip_ip(r.body))
ok 'Consul is UP and has a leader'
else
critical 'Consul is UP, but it has NO leader'
end
else
critical 'Consul is not responding'
end
rescue Errno::ECONNREFUSED
critical 'Consul is not responding'
rescue RestClient::RequestTimeout
critical 'Consul Connection timed out'
rescue RestClient::Exception => e
unknown "Consul returned: #{e}"
end
end