Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getnameinfo as a fall through case for fqdn resolution #1810

Merged
merged 11 commits into from
Oct 4, 2023
27 changes: 26 additions & 1 deletion lib/ohai/mixin/network_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#

require "socket" unless defined?(Socket)
require "resolv" unless defined?(Resolv)

module Ohai
module Mixin
Expand All @@ -37,6 +38,11 @@
dec
end

def ip?(hostname)
tpowell-progress marked this conversation as resolved.
Show resolved Hide resolved
!!(canonname =~ Resolv::IPv4::Regex) || !!(canonname =~ Resolv::IPv6::Regex)

Check failure on line 43 in lib/ohai/mixin/network_helper.rb

View workflow job for this annotation

GitHub Actions / chefstyle

[Correctable] Layout/EmptyLinesAroundMethodBody: Extra empty line detected at method body end.
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
Expand All @@ -47,7 +53,26 @@
# server), and the method should return the hostname and not the IP address.
#
def canonicalize_hostname(hostname)
Addrinfo.getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first.canonname
ai = Addrinfo
.getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME)
.first

canonname = ai&.canonname
# 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)
tpowell-progress marked this conversation as resolved.
Show resolved Hide resolved

# 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)
tpowell-progress marked this conversation as resolved.
Show resolved Hide resolved

# if all else fails, return the name we were given as a safety
hostname
end

def canonicalize_hostname_with_retries(hostname)
Expand Down
1 change: 1 addition & 0 deletions spec/unit/mixin/network_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
addrinfo = instance_double(Addrinfo)
expect(Addrinfo).to receive(:getaddrinfo).with(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME).and_return([addrinfo])
expect(addrinfo).to receive(:canonname).and_return(hostname)
expect(addrinfo).to receive(:getnameinfo).and_return([hostname, "0"]) if windows?
expect(mixin.canonicalize_hostname(hostname)).to eql(hostname)
end
end
Expand Down
Loading