Skip to content

Commit

Permalink
Merge pull request #20992 from agrare/fix_miq_environment_local_ip_ad…
Browse files Browse the repository at this point in the history
…dress

Fix MiqEnvironment.local_ip_address to not prefer loopback
  • Loading branch information
Fryguy authored Feb 1, 2021
2 parents cf7f6e4 + 16f8263 commit fd276ba
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
12 changes: 10 additions & 2 deletions lib/miq_environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ def self.fully_qualified_domain_name
Socket.gethostbyname(Socket.gethostname).first
end

# Return the local IP v4 address of the local host, ignoring private addresses.
# Return the local IP v4 address of the local host
#
def self.local_ip_address
Socket.ip_address_list.detect { |addr| addr.ipv4? && !addr.ipv4_private? }&.ip_address
ipv4_addrs = Socket.ip_address_list.select(&:ipv4?).sort_by(&:ip_address)

# Prioritize "public" aka non-loopback non-private addresses first, then
# prefer private addresses, then take whatever we can get
local_addr = ipv4_addrs.detect { |ip| !ip.ipv4_loopback? && !ip.ipv4_private? }
local_addr ||= ipv4_addrs.detect { |ip| !ip.ipv4_loopback? }
local_addr ||= ipv4_addrs.first

local_addr&.ip_address
end

class Command
Expand Down
11 changes: 10 additions & 1 deletion spec/lib/miq_environment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
end

example "local_ip_address" do
expect(described_class.local_ip_address).to eq(`hostname -i`.chomp.split.first)
expect(described_class.local_ip_address).to be_in(Socket.ip_address_list.map(&:ip_address))
end

context "multiple private addresses" do
it "always returns the same address" do
allow(Socket).to receive(:ip_address_list).and_return([Addrinfo.ip("192.168.1.10"), Addrinfo.ip("10.1.2.3")])
expect(described_class.local_ip_address).to eq("10.1.2.3")
allow(Socket).to receive(:ip_address_list).and_return([Addrinfo.ip("10.1.2.3"), Addrinfo.ip("192.168.1.10")])
expect(described_class.local_ip_address).to eq("10.1.2.3")
end
end
end

Expand Down
18 changes: 12 additions & 6 deletions spec/models/miq_server/environment_manager_spec.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
require 'socket'

RSpec.describe "Server Environment Management" do
let(:mac_address) { 'a:1:b:2:c:3:d:4' }
let(:hostname) { Socket.gethostname }
let(:loopback) { '127.0.0.1' }

context ".get_network_information" do
it "when in non-production mode" do
let(:mac_address) { 'a:1:b:2:c:3:d:4' }
let(:hostname) { "localhost.localdomain" }
let(:ip_address) { "10.1.2.3" }

before do
require "uuidtools"
allow(UUIDTools::UUID).to receive(:mac_address).and_return(mac_address)
expect(MiqServer.get_network_information).to eq([loopback, hostname, mac_address])
allow(Socket).to receive(:gethostname).and_return("localhost")
allow(Socket).to receive(:gethostbyname).with("localhost").and_return([hostname])
allow(Socket).to receive(:ip_address_list).and_return([Addrinfo.ip(ip_address)])
end

it "when in non-production mode" do
expect(MiqServer.get_network_information).to eq([ip_address, hostname, mac_address])
end
end

Expand Down

0 comments on commit fd276ba

Please sign in to comment.