Revision 0f791ba5
Added by Daniel Lobato Garcia over 7 years ago
Gemfile | ||
---|---|---|
gem 'net-scp'
|
||
gem 'net-ssh'
|
||
gem 'net-ldap', '>= 0.8.0'
|
||
gem 'net-ping', :require => false
|
||
gem 'activerecord-session_store', '>= 0.1.1', '< 2'
|
||
gem 'sprockets', '~> 3'
|
||
gem 'sprockets-rails', '>= 2.3.3', '< 3'
|
lib/tasks/hosts.rake | ||
---|---|---|
# TRANSLATORS: do not translate
|
||
desc <<-END_DESC
|
||
Try to figure out the out of sync hosts real status
|
||
This task search hosts that have been out of sync for longer than
|
||
twice your out of sync interval by using DNS lookups and ping.
|
||
|
||
try to search them by DNS lookups and ping, if a host is not in DNS it will allow you to delete it.
|
||
Once it finishes scanning, it will prompt you to delete hosts that
|
||
don't have DNS entries nor respond to ping.
|
||
|
||
legend:
|
||
You can provide the number of seconds after which a host is considered
|
||
out of sync by using the environment variable 'OUTOFSYNC_INTERVAL'.
|
||
|
||
Legend:
|
||
"." - pingable
|
||
"x" - no ping response
|
||
|
||
Example:
|
||
Examples:
|
||
rake hosts:scan_out_of_sync RAILS_ENV="production"
|
||
rake hosts:scan_out_of_sync RAILS_ENV="production" OUTOFSYNC_INTERVAL=3600
|
||
|
||
END_DESC
|
||
|
||
namespace :hosts do
|
||
task :scan_out_of_sync => :environment do
|
||
require 'ping'
|
||
require 'net/ping/external'
|
||
require 'resolv'
|
||
|
||
def printhosts(list, description)
|
||
unless list.empty?
|
||
puts
|
||
puts "found #{list.size} #{description} hosts:"
|
||
puts "Found #{list.size} #{description}:"
|
||
puts "Name".ljust(40)+"Environment".ljust(20)+"Last Report"
|
||
puts "#{"*"*80}"
|
||
puts '*' * 80
|
||
list.each do |h|
|
||
puts h.name.ljust(40) + h.environment.to_s.ljust(20) + h.last_report.to_s(:short)
|
||
end
|
||
end
|
||
end
|
||
|
||
def out_of_sync_interval
|
||
return ENV['OUTOFSYNC_INTERVAL'] if ENV['OUTOFSYNC_INTERVAL'].present?
|
||
2 * (Setting[:puppet_interval] + Setting[:outofsync_interval])
|
||
end
|
||
|
||
pingable = []
|
||
missingdns = []
|
||
offline = []
|
||
|
||
Host.out_of_sync(1.hour.ago).all(:order => 'environment_id asc').collect do |host|
|
||
Host::Managed.out_of_sync(out_of_sync_interval.to_i.seconds.ago).
|
||
order('environment_id ASC').collect do |host|
|
||
$stdout.flush
|
||
ip = Resolv::DNS.new.getaddress(host.name).to_s rescue nil
|
||
if ip.empty?
|
||
missingdns << host
|
||
else
|
||
puts "conflict IP address for #{host.name}" unless ip == host.ip
|
||
if Ping.pingecho host.ip
|
||
if host.ip.blank?
|
||
puts "Host #{host.name} does not have an IP in Foreman. It resolved to IP: '#{ip}' through DNS. Skipping..."
|
||
next
|
||
end
|
||
all_host_ips = host.interfaces.pluck(:ip)
|
||
puts "Conflict IP address for #{host.name}" unless all_host_ips.include? ip
|
||
begin
|
||
if Net::Ping::External.new(host.ip).ping
|
||
print "."
|
||
pingable << host
|
||
else
|
||
print "x"
|
||
offline << host
|
||
end
|
||
rescue => e
|
||
Rails.logger.warn "Could not ping host #{host.name} due to an exception: #{e} - skipping"
|
||
end
|
||
end
|
||
end
|
||
puts
|
||
|
||
if missingdns.empty?
|
||
puts "All out of sync hosts exists in DNS"
|
||
puts "All out of sync hosts exist in DNS"
|
||
else
|
||
printhosts(missingdns, "hosts with no DNS entry")
|
||
puts "ctrl-c to abort - any other key to remove these hosts"
|
||
$stdin.gets
|
||
puts "Are you sure you want to continue? This task will delete the hosts above [y/N]"
|
||
input = STDIN.gets.chomp
|
||
abort("No action taken. Bye!") unless input.downcase == "y"
|
||
|
||
missingdns.each {|h| h.destroy }
|
||
missingdns.each do |h|
|
||
print "Destroying host #{h.fqdn}... "
|
||
h.destroy
|
||
puts "DESTROYED"
|
||
end
|
||
end
|
||
|
||
printhosts(offline, "offline hosts")
|
||
printhosts(pingable, "online hosts which are not running puppet")
|
||
printhosts(pingable, "online hosts which are not reporting back")
|
||
end
|
||
end
|
Also available in: Unified diff
Fixes #17837 - Fix hosts:scan_out_of_sync task
The task relies on Ping, which was removed since Ruby 1.9. I've moved it
to rely on net-ping instead. Notice the ping now relies on the 'ping'
binary being in the foreman user path for this to work with foreman-rake