Revision 8d10c655
Added by Greg Sutcliffe almost 11 years ago
- ID 8d10c655228f67447dba1aa62f1cd2bb933ce4e0
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
Fixes #2576 - Add optional update of Host.ip from built request