Project

General

Profile

« Previous | Next » 

Revision 8d10c655

Added by Greg Sutcliffe almost 11 years ago

  • ID 8d10c655228f67447dba1aa62f1cd2bb933ce4e0

Fixes #2576 - Add optional update of Host.ip from built request

View differences:

app/controllers/unattended_controller.rb
# this actions is called by each operatingsystem post/finish script - it notify us that the OS installation is done.
def built
logger.info "#{controller_name}: #{@host.name} is Built!"
update_ip if Setting[:update_ip_from_built_request]
head(@host.built ? :created : :conflict)
end
......
def find_host_by_ip_or_mac
# try to find host based on our client ip address
ip = request.env['REMOTE_ADDR']
# check if someone is asking on behave of another system (load balance etc)
if request.env['HTTP_X_FORWARDED_FOR'].present? and (ip =~ Regexp.new(Setting[:remote_addr]))
ip = request.env['HTTP_X_FORWARDED_FOR']
end
ip = ip_from_request_env
# in case we got back multiple ips (see #1619)
ip = ip.split(',').first
......
private
# This method updates the IP held by Foreman from the incoming request.
# Useful on unmanaged DHCP systems, with token-based installs where Foreman
# doesn't know the IP in advance (and has been given a fake one just to make
# the form save)
def update_ip
ip = ip_from_request_env
logger.debug "Built notice from #{ip}, current host ip is #{@host.ip}, updating" if @host.ip != ip
# @host has been changed even if the save fails, so we have to change it back
old_ip = @host.ip
@host.ip = old_ip unless @host.update_attributes({'ip' => ip})
end
def ip_from_request_env
ip = request.env['REMOTE_ADDR']
# check if someone is asking on behalf of another system (load balance etc)
if request.env['HTTP_X_FORWARDED_FOR'].present? and (ip =~ Regexp.new(Setting[:remote_addr]))
ip = request.env['HTTP_X_FORWARDED_FOR']
end
ip
end
def safe_render template
template_name = ""
if template.is_a?(String)
......
end
end
end
app/models/setting/provisioning.rb
self.set('query_local_nameservers', N_("Should Foreman query the locally configured name server or the SOA/NS authorities"), false),
self.set('remote_addr', N_("If Foreman is running behind Passenger or a remote load balancer, the IP should be set here. This is a regular expression, so it can support several load balancers, i.e: (10.0.0.1|127.0.0.1)"), "127.0.0.1"),
self.set('token_duration', N_("Time in minutes installation tokens should be valid for, 0 to disable"), 0),
self.set('libvirt_default_console_address', N_("The IP address that should be used for the console listen address when provisioning new virtual machines via Libvirt"), "0.0.0.0")
self.set('libvirt_default_console_address', N_("The IP address that should be used for the console listen address when provisioning new virtual machines via Libvirt"), "0.0.0.0"),
self.set('update_ip_from_built_request', N_("Should we use the originating IP of the built request to update the host's IP?"), false)
].each { |s| self.create! s.update(:category => "Setting::Provisioning")}
end
test/fixtures/hosts.yml
puppet_proxy: puppetmaster
compute_resource: one
# Need a host with both build=true and managed=true for some tests
ubuntu2:
type: Host::Managed
name: temp-02.yourdomain.net
ip: 2.3.4.106
mac: ac:bb:cc:de:ee:ff
environment: production
architecture: x86_64
operatingsystem: ubuntu1010
managed: true
build: true
ptable: ubuntu
domain: yourdomain
medium: ubuntu
subnet: one
puppet_proxy: puppetmaster
compute_resource: one
minimal:
type: Host::Managed
name: temp-02.useless.net
test/fixtures/settings.yml
category: Setting::Puppet
default: "true"
description: "Foreman will create the host when new facts are received"
attribute38:
name: update_ip_from_built_request
category: Setting::Provisioning
default: "true"
description: "Should we use the originating IP of the built request to update the Host's IP?"
test/functional/unattended_controller_test.rb
assert_response :success
end
test "hosts with mismatched ip and update_ip=false should have the old ip" do
disable_orchestration # avoids dns errors
Setting[:token_duration] = 30
Setting[:update_ip_from_built_request] = false
@request.env["REMOTE_ADDR"] = '127.0.0.1'
h=hosts(:ubuntu2)
h.create_token(:value => "aaaaaa", :expires => Time.now + 5.minutes)
get :built, {'token' => h.token.value }
h_new=Host.find_by_name(h.name)
assert_response :success
assert_equal h.ip, h_new.ip
end
test "hosts with mismatched ip and update_ip true should have the new ip" do
disable_orchestration # avoids dns errors
Setting[:token_duration] = 30
Setting[:update_ip_from_built_request] = true
@request.env["REMOTE_ADDR"] = '2.3.4.199'
h=hosts(:ubuntu2)
assert_equal '2.3.4.106', h.ip
h.create_token(:value => "aaaaab", :expires => Time.now + 5.minutes)
get :built, {'token' => h.token.value }
h_new=Host.find_by_name(h.name)
assert_response :success
assert_equal '2.3.4.199', h_new.ip
end
test "hosts with mismatched ip and update_ip true and a duplicate ip should succeed with no ip update" do
disable_orchestration # avoids dns errors
Setting[:token_duration] = 30
Setting[:update_ip_from_built_request] = true
@request.env["REMOTE_ADDR"] = hosts(:redhat).ip
h=hosts(:ubuntu2)
h.create_token(:value => "aaaaac", :expires => Time.now + 5.minutes)
get :built, {'token' => h.token.value }
assert_response :success
h_new=Host.find_by_name(h.name)
assert_equal h.ip, h_new.ip
end
# Should this test be moved into renderer_test, as it excercises foreman_url() functionality?
test "template should contain tokens when tokens enabled and present for the host" do
Setting[:token_duration] = 30

Also available in: Unified diff