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

Fixes #38051 - Fix built request to accept ipv6 hosts #10392

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

ShimShtein
Copy link
Member

Built request should be able to accept built requests sent from IPv6 only machine. This pr makes sure ip6 field is updated accordingly.

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some related code in

def parse_ip_address(address, ignore_link_local: true)
return nil unless address
begin
addr = IPAddr.new(address)
rescue IPAddr::InvalidAddressError
# https://tickets.puppetlabs.com/browse/FACT-1935 facter can return an
# address with the link local identifier. Ruby can't parse because of
# https://bugs.ruby-lang.org/issues/8464 so we manually strip it off
# if the interface identifier if present
if address.is_a?(String) && address.include?('%')
addr = IPAddr.new(address.split('%').first)
else
logger.warn "Ignoring invalid IP address #{address}"
return nil
end
end
return if ignore_link_local && addr.link_local?
addr.to_s
end
which has some handling around IPv6 link local addresses. I don't know if you can hit the same thing here, but I'd appreciate it if you can take a look.

Comment on lines 224 to 226
end

if address.ipv6?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
end
if address.ipv6?
elsif address.ipv6?

@@ -373,6 +373,16 @@ class UnattendedControllerTest < ActionController::TestCase
refute nic.build
end

test "should accept built notifications over ipv6 and store the address" do
nic6 = FactoryBot.build(:nic_managed, :with_ipv6)
Setting[:update_ip_from_built_request] = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this revert the change after the test? We have a helper for SETTINGS:

foreman/test/test_helper.rb

Lines 204 to 214 in 9b8f759

def with_temporary_settings(**kwargs)
old_settings = SETTINGS.dup
begin
SETTINGS.update(kwargs)
yield
ensure
SETTINGS.replace(old_settings)
end
end
end

But I'm not sure we need to a similar thing for Setting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not, but from looking at the code, we don't revert any of the settings. I suppose if the test relies on a specific setting, it should be explicitly set in the setup block.

test "should accept built notifications over ipv6 and store the address" do
nic6 = FactoryBot.build(:nic_managed, :with_ipv6)
Setting[:update_ip_from_built_request] = true
@request.env["REMOTE_ADDR"] = nic6.ip6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it easier to just use some specific IP instead of using the NIC factory?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to copy the IP generation code, so having FactoryBot actually generating one was an easy option for me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need a random IP, a static IP from the 2001:db8::/32 range is IMHO better. That way you can assert for it. Your current code could have a bug where both values are set to nil and you wouldn't notice it.

@@ -217,8 +217,14 @@ def update_ip
logger.debug "Built notice from #{ip}, current host ip is #{@host.ip}, updating" if @host.ip != ip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't taking IPv6 into account and needs to be moved into the if block's branches.

if address.ipv4?
old_ip = @host.ip
@host.ip = old_ip unless @host.update({'ip' => ip})
elsif address.ipv6?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please filter out link local addresses

Suggested change
elsif address.ipv6?
elsif address.ipv6? && !address.link_local?

You perhaps you want to log a message if it's ignored, but I wouldn't feel too strongly about it.

@ShimShtein
Copy link
Member Author

Ready for another round

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants