-
Notifications
You must be signed in to change notification settings - Fork 993
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
base: develop
Are you sure you want to change the base?
Conversation
30e77d0
to
9ebe07b
Compare
There was a problem hiding this 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
foreman/app/models/host/base.rb
Lines 378 to 399 in 9b8f759
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 |
end | ||
|
||
if address.ipv6? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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
:
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
.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
9ebe07b
to
4b8860c
Compare
@@ -217,8 +217,14 @@ def update_ip | |||
logger.debug "Built notice from #{ip}, current host ip is #{@host.ip}, updating" if @host.ip != ip |
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
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
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.
4b8860c
to
7899652
Compare
7899652
to
13cb803
Compare
Ready for another round |
Built request should be able to accept built requests sent from IPv6 only machine. This pr makes sure
ip6
field is updated accordingly.