From 6bde4b19708a9e5bd3b4857bffafd0464055f3b5 Mon Sep 17 00:00:00 2001 From: Thomas Powell Date: Tue, 3 Oct 2023 19:42:38 -0400 Subject: [PATCH] Refactor and tweak canonicalize_hostname logic Signed-off-by: Thomas Powell --- lib/ohai/mixin/network_helper.rb | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/ohai/mixin/network_helper.rb b/lib/ohai/mixin/network_helper.rb index 8ae307a75..005952685 100644 --- a/lib/ohai/mixin/network_helper.rb +++ b/lib/ohai/mixin/network_helper.rb @@ -19,6 +19,7 @@ # require "socket" unless defined?(Socket) +require "resolv" unless defined?(Resolv) module Ohai module Mixin @@ -37,6 +38,11 @@ def hex_to_dec_netmask(netmask) dec end + def ip?(hostname) + !!(canonname =~ Resolv::IPv4::Regex) || !!(canonname =~ Resolv::IPv6::Regex) + + end + # This does a forward and reverse lookup on the hostname to return what should be # the FQDN for the host determined by name lookup (generally DNS). If the forward # lookup fails this will throw. If the reverse lookup fails this will return the @@ -52,12 +58,21 @@ def canonicalize_hostname(hostname) .first canonname = ai&.canonname - # use canonname - return canonname if canonname != hostname || !ChefUtils.windows? + # use canonname if it's an FQDN + # This API is preferred as it never gives us an IP address for broken DNS + # (see https://github.com/chef/ohai/pull/1705) + # However, we have found that Windows hosts that are not joined to a domain + # can return a non-qualified hostname) + return canonname unless ip?(canonname) + + # If we got a non-qualified name, then we do a standard reverse resolve + # which, assuming DNS is working, will work around that windows bug + # (and maybe others) + canonname = ai&.getnameinfo&.first + return canonname unless ip?(canonname) - # canonname does not fully qualify the hostname if on Windows node that - # is not joined to a domain, but getnameinfo does. - ai&.getnameinfo&.[](0) || hostname + # if all else fails, return the name we were given as a safety + hostname end def canonicalize_hostname_with_retries(hostname)