(POOLER-166) Check for stale dns records

This commit is contained in:
Samuel Beaulieu 2020-05-29 11:51:23 -05:00
parent eb0df8d83f
commit 6304743240
2 changed files with 53 additions and 6 deletions

View file

@ -2,6 +2,7 @@
require 'vmpooler/providers'
require 'spicy-proton'
require 'resolv' # ruby standard lib
module Vmpooler
class PoolManager
@ -295,22 +296,46 @@ module Vmpooler
end
def find_unique_hostname(pool_name)
# generate hostname that is not already in use in vmpooler
# also check that no dns record already exists
hostname_retries = 0
max_hostname_retries = 3
while hostname_retries < max_hostname_retries
hostname, available = generate_and_check_hostname(pool_name)
break if available
domain = $config[:config]['domain']
dns_ip, dns_available = check_dns_available(hostname, domain)
break if available && dns_available
hostname_retries += 1
$metrics.increment("errors.duplicatehostname.#{pool_name}")
$logger.log('s', "[!] [#{pool_name}] Generated hostname #{hostname} was not unique (attempt \##{hostname_retries} of #{max_hostname_retries})")
if !available
$metrics.increment("errors.duplicatehostname.#{pool_name}")
$logger.log('s', "[!] [#{pool_name}] Generated hostname #{hostname} was not unique (attempt \##{hostname_retries} of #{max_hostname_retries})")
elsif !dns_available
$metrics.increment("errors.staledns.#{hostname}")
$logger.log('s', "[!] [#{pool_name}] Generated hostname #{hostname} already exists in DNS records (#{dns_ip}), stale DNS")
end
end
raise "Unable to generate a unique hostname after #{hostname_retries} attempts. The last hostname checked was #{hostname}" unless available
raise "Unable to generate a unique hostname after #{hostname_retries} attempts. The last hostname checked was #{hostname}" unless available && dns_available
hostname
end
def check_dns_available(vm_name, domain = nil)
# Query the DNS for the name we want to create and if it already exists, mark it unavailable
# This protects against stale DNS records
vm_name = "#{vm_name}.#{domain}" if domain
begin
dns_ip = Resolv.getaddress(vm_name)
rescue Resolv::ResolvError
# this is the expected case, swallow the error
# eg "no address for blah-daisy"
return ['', true]
end
[dns_ip, false]
end
def _clone_vm(pool_name, provider)
new_vmname = find_unique_hostname(pool_name)