Revision 4e68ddfe
Added by Julian Todt almost 6 years ago
app/controllers/unattended_controller.rb | ||
---|---|---|
before_action :get_host_details, :except => [:hostgroup_template, :built, :failed]
|
||
before_action :get_built_host_details, :only => [:built, :failed]
|
||
before_action :allowed_to_install?, :except => :hostgroup_template
|
||
before_action :handle_ca, :if => Proc.new { params[:kind] == 'provision' }
|
||
before_action :handle_realm, :if => Proc.new { params[:kind] == 'provision' }
|
||
# load "helper" variables to be available in the templates
|
||
before_action :load_template_vars, :only => :host_template
|
||
... | ... | |
(@host.build || @spoof || Setting[:access_unattended_without_build]) ? true : head(:method_not_allowed)
|
||
end
|
||
|
||
# Cleans Certificate and enable autosign. This is run as a before_action for provisioning templates.
|
||
# The host is requesting its build configuration so I guess we just send them some text so a post mortum can see what happened
|
||
def handle_ca
|
||
# The reason we do it here is to minimize the amount of time it is possible to automatically get a certificate
|
||
|
||
# We don't do anything if we are in spoof mode.
|
||
return true if @spoof
|
||
|
||
# This should terminate the before_action and the action. We return a HTTP
|
||
# error so the installer knows something is wrong. This is tested with
|
||
# Anaconda, but maybe Suninstall will choke on it.
|
||
render(:plain => _("Failed to clean any old certificates or add the autosign entry. Terminating the build!"), :status => :internal_server_error) unless @host.handle_ca
|
||
# TODO: Email the user who initiated this build operation.
|
||
end
|
||
|
||
# Reset realm OTP. This is run as a before_action for provisioning templates.
|
||
def handle_realm
|
||
# We don't do anything if we are in spoof mode.
|
app/models/concerns/orchestration/compute.rb | ||
---|---|---|
end
|
||
|
||
self.compute_attributes[:user_data] = unattended_render(template.template)
|
||
self.handle_ca
|
||
|
||
return false if errors.any?
|
||
logger.info "Revoked old certificates and enabled autosign for UserData"
|
app/models/concerns/orchestration/puppetca.rb | ||
---|---|---|
def setCertificate
|
||
end
|
||
|
||
# Reset certname based on whether to use uuids or the hostname
|
||
def resetCertname
|
||
logger.info "Resetting certname for #{name}"
|
||
self.certname = Setting[:use_uuid_for_certificates] ? Foreman.uuid : hostname
|
||
end
|
||
|
||
# Adds the host's name to the autosign.conf file
|
||
def setAutosign
|
||
logger.info "Adding autosign entry for #{name}"
|
||
... | ... | |
new_record? ? queue_puppetca_create : queue_puppetca_update
|
||
end
|
||
|
||
# we don't perform any actions upon create
|
||
# PuppetCA is set only when a provisioning script (such as a kickstart) is being requested.
|
||
def queue_puppetca_certname_reset
|
||
queue.create(:name => _("Reset PuppetCA certname for %s") % self, :priority => 49,
|
||
:action => [self, :resetCertname])
|
||
end
|
||
|
||
def queue_puppetca_create
|
||
queue.create(:name => _("Cleanup PuppetCA certificates for %s") % self, :priority => 51,
|
||
:action => [self, :delCertificate])
|
||
queue.create(:name => _("Enable PuppetCA autosigning for %s") % self, :priority => 55,
|
||
:action => [self, :setAutosign])
|
||
end
|
||
|
||
def queue_puppetca_update
|
||
# Host has been built --> remove auto sign
|
||
queue_puppetca_autosign_destroy if old.build? && !build?
|
||
if old.build? && !build?
|
||
# Host has been built --> remove auto sign
|
||
queue_puppetca_autosign_destroy
|
||
elsif !old.build? && build?
|
||
# Host was set to build mode
|
||
# If use_uuid_for_certificates is true, reuse the certname UUID value.
|
||
# If false, then reset the certname if it does not match the hostname.
|
||
if (Setting[:use_uuid_for_certificates] ? !Foreman.is_uuid?(certname) : certname != hostname)
|
||
queue_puppetca_certname_reset
|
||
end
|
||
queue_puppetca_autosign_destroy
|
||
queue_puppetca_create
|
||
end
|
||
true
|
||
end
|
||
|
||
def queue_puppetca_destroy
|
||
return unless puppetca? && errors.empty?
|
||
return unless Setting[:manage_puppetca]
|
||
queue.create(:name => _("Delete PuppetCA certificates for %s") % self, :priority => 50,
|
||
queue.create(:name => _("Delete PuppetCA certificates for %s") % self, :priority => 59,
|
||
:action => [self, :delCertificate])
|
||
queue_puppetca_autosign_destroy
|
||
true
|
||
end
|
||
|
||
def queue_puppetca_autosign_destroy
|
||
queue.create(:name => _("Delete PuppetCA autosign entry for %s") % self, :priority => 55,
|
||
queue.create(:name => _("Disable PuppetCA autosigning for %s") % self, :priority => 50,
|
||
:action => [self, :delAutosign])
|
||
end
|
||
end
|
app/models/host/managed.rb | ||
---|---|---|
(puppetmaster == "puppet") ? "puppet.#{domain.name}" : puppetmaster.to_s
|
||
end
|
||
|
||
# Cleans Certificate and enable Autosign
|
||
# Called before a host is given their provisioning template
|
||
# Returns : Boolean status of the operation
|
||
def handle_ca
|
||
# If there's no puppetca, tell the caller that everything is ok
|
||
return true unless Setting[:manage_puppetca]
|
||
return true unless puppetca?
|
||
|
||
# From here out, we expect things to work and return true
|
||
return false unless respond_to?(:initialize_puppetca, true)
|
||
return false unless initialize_puppetca
|
||
return false unless delCertificate
|
||
|
||
# If use_uuid_for_certificates is true, reuse the certname UUID value.
|
||
# If false, then reset the certname if it does not match the hostname.
|
||
if (Setting[:use_uuid_for_certificates] ? !Foreman.is_uuid?(certname) : certname != hostname)
|
||
logger.info "Removing certificate value #{certname} for host #{name}"
|
||
self.certname = nil
|
||
end
|
||
|
||
setAutosign
|
||
end
|
||
|
||
def import_facts(facts, source_proxy = nil)
|
||
# Facts come from 'existing' attributes/infrastructure. We skip triggering
|
||
# the orchestration of this infrastructure when we create a host this way.
|
test/models/host_test.rb | ||
---|---|---|
assert_equal domain, host.domain
|
||
end
|
||
|
||
test "handle_ca must not perform actions when the manage_puppetca setting is false" do
|
||
h = FactoryBot.create(:host)
|
||
Setting[:manage_puppetca] = false
|
||
h.expects(:initialize_puppetca).never
|
||
h.expects(:setAutosign).never
|
||
assert h.handle_ca
|
||
end
|
||
|
||
test "handle_ca must not perform actions when no Puppet CA proxy is associated even if associated with hostgroup" do
|
||
hostgroup = FactoryBot.create(:hostgroup, :with_puppet_orchestration, :with_domain, :with_os)
|
||
h = FactoryBot.create(:host, :managed, :with_environment, :hostgroup => hostgroup)
|
||
Setting[:manage_puppetca] = true
|
||
|
||
h.puppet_proxy_id = h.puppet_ca_proxy_id = nil
|
||
h.save
|
||
|
||
refute h.puppetca?
|
||
|
||
h.expects(:initialize_puppetca).never
|
||
assert h.handle_ca
|
||
end
|
||
|
||
test "handle_ca must not perform actions when no Puppet CA proxy is associated" do
|
||
h = FactoryBot.create(:host)
|
||
Setting[:manage_puppetca] = true
|
||
refute h.puppetca?
|
||
h.expects(:initialize_puppetca).never
|
||
assert h.handle_ca
|
||
end
|
||
|
||
test "handle_ca must call initialize, delete cert and add autosign methods" do
|
||
h = FactoryBot.create(:host, :with_puppet_orchestration)
|
||
Setting[:manage_puppetca] = true
|
||
assert h.puppetca?
|
||
h.expects(:initialize_puppetca).returns(true)
|
||
h.expects(:delCertificate).returns(true)
|
||
h.expects(:setAutosign).returns(true)
|
||
assert h.handle_ca
|
||
end
|
||
|
||
test "if the user toggles off the use_uuid_for_certificates option, revoke the UUID and autosign the hostname" do
|
||
h = FactoryBot.create(:host, :with_puppet_orchestration)
|
||
Setting[:manage_puppetca] = true
|
||
assert h.puppetca?
|
||
|
||
Setting[:use_uuid_for_certificates] = false
|
||
some_uuid = Foreman.uuid
|
||
h.certname = some_uuid
|
||
|
||
h.expects(:initialize_puppetca).returns(true)
|
||
mock_puppetca = Object.new
|
||
mock_puppetca.expects(:del_certificate).with(some_uuid).returns(true)
|
||
mock_puppetca.expects(:set_autosign).with(h.name).returns(true)
|
||
h.instance_variable_set("@puppetca", mock_puppetca)
|
||
|
||
assert h.handle_ca
|
||
assert_equal h.certname, h.name
|
||
end
|
||
|
||
test "if the user changes a hostname in non-use_uuid_for_cetificates mode, revoke the old hostname and autosign the new hostname" do
|
||
Setting[:use_uuid_for_certificates] = false
|
||
Setting[:manage_puppetca] = true
|
||
|
||
h = FactoryBot.create(:host, :with_puppet_orchestration)
|
||
assert h.puppetca?
|
||
|
||
old_name = 'oldhostname'
|
||
h.certname = old_name
|
||
|
||
h.expects(:initialize_puppetca).returns(true)
|
||
mock_puppetca = Object.new
|
||
mock_puppetca.expects(:del_certificate).with(old_name).returns(true)
|
||
mock_puppetca.expects(:set_autosign).with(h.name).returns(true)
|
||
h.instance_variable_set("@puppetca", mock_puppetca)
|
||
|
||
assert h.handle_ca
|
||
assert_equal h.certname, h.name
|
||
end
|
||
|
||
test "custom_disk_partition_with_erb" do
|
||
h = FactoryBot.create(:host)
|
||
h.disk = "<%= template_name %>"
|
test/models/orchestration/puppetca_test.rb | ||
---|---|---|
end
|
||
|
||
context 'a host with puppetca orchestration' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => true) }
|
||
|
||
test 'should queue puppetca update' do
|
||
host.build = false
|
||
assert_valid host
|
||
tasks = host.queue.all.map(&:name)
|
||
assert_includes tasks, "Delete PuppetCA autosign entry for #{host}"
|
||
assert_equal 1, tasks.size
|
||
context 'when entering build mode on creation' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => true) }
|
||
|
||
test 'should queue puppetca autosigning' do
|
||
assert_valid host
|
||
tasks = host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Cleanup PuppetCA certificates for #{host}"
|
||
assert_equal tasks[1], "Enable PuppetCA autosigning for #{host}"
|
||
assert_equal 2, tasks.size
|
||
end
|
||
|
||
test 'should use the hostname for autosigning on setting' do
|
||
Setting[:use_uuid_for_certificates] = false
|
||
assert_valid host
|
||
assert_equal host.certname, host.hostname
|
||
assert host.send(:initialize_puppetca)
|
||
host.puppetca.expects(:set_autosign).with(host.hostname).returns(true)
|
||
assert host.send(:setAutosign)
|
||
end
|
||
|
||
test 'should use a uuid for autosigning on setting' do
|
||
Setting[:use_uuid_for_certificates] = true
|
||
assert_valid host
|
||
assert Foreman.is_uuid?(host.certname)
|
||
assert host.send(:initialize_puppetca)
|
||
host.puppetca.expects(:set_autosign).with(host.certname).returns(true)
|
||
assert host.send(:setAutosign)
|
||
end
|
||
end
|
||
|
||
context 'when reentering build mode' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => false) }
|
||
|
||
setup do
|
||
@host = host
|
||
@host.queue.clear
|
||
@host.build = true
|
||
@host.save!
|
||
end
|
||
|
||
test 'should queue puppetca autosigning' do
|
||
tasks = @host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Disable PuppetCA autosigning for #{host}"
|
||
assert_equal tasks[1], "Cleanup PuppetCA certificates for #{host}"
|
||
assert_equal tasks[2], "Enable PuppetCA autosigning for #{host}"
|
||
assert_equal 3, tasks.size
|
||
end
|
||
end
|
||
|
||
test 'should queue puppetca destroy' do
|
||
host.send(:queue_puppetca_destroy)
|
||
tasks = host.queue.all.map(&:name)
|
||
assert_includes tasks, "Delete PuppetCA autosign entry for #{host}"
|
||
assert_includes tasks, "Delete PuppetCA certificates for #{host}"
|
||
assert_equal 2, tasks.size
|
||
context 'when reentering build mode after certname setting was changed' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => false) }
|
||
|
||
test 'should reset certname when changing from hostname to uuid' do
|
||
assert_valid host
|
||
host.queue.clear
|
||
Setting[:use_uuid_for_certificates] = true
|
||
host.build = true
|
||
host.save!
|
||
tasks = host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Disable PuppetCA autosigning for #{host}"
|
||
assert_equal tasks[1], "Cleanup PuppetCA certificates for #{host}"
|
||
assert_equal tasks[2], "Enable PuppetCA autosigning for #{host}"
|
||
assert_equal 3, tasks.size
|
||
# Foreman updates the certname automatically in this case
|
||
assert Foreman.is_uuid?(host.certname)
|
||
end
|
||
|
||
test 'should reset certname when changing from uuid to hostname' do
|
||
Setting[:use_uuid_for_certificates] = true
|
||
assert_valid host
|
||
host.queue.clear
|
||
Setting[:use_uuid_for_certificates] = false
|
||
host.build = true
|
||
host.save!
|
||
tasks = host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Reset PuppetCA certname for #{host}"
|
||
assert_equal tasks[1], "Disable PuppetCA autosigning for #{host}"
|
||
assert_equal tasks[2], "Cleanup PuppetCA certificates for #{host}"
|
||
assert_equal tasks[3], "Enable PuppetCA autosigning for #{host}"
|
||
assert_equal 4, tasks.size
|
||
end
|
||
end
|
||
|
||
context 'when host leaves build mode' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => true) }
|
||
|
||
setup do
|
||
@host = host
|
||
@host.queue.clear
|
||
@host.build = false
|
||
@host.save!
|
||
end
|
||
|
||
test 'should remove autosign entry for host' do
|
||
tasks = @host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Disable PuppetCA autosigning for #{host}"
|
||
assert_equal 1, tasks.size
|
||
end
|
||
end
|
||
|
||
context 'when host is updated' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => false) }
|
||
|
||
test 'should not queue anything if build mode is not changed' do
|
||
assert_valid host
|
||
host.queue.clear
|
||
host.comment = "updated"
|
||
host.save!
|
||
assert_equal 0, host.queue.all.size
|
||
end
|
||
end
|
||
|
||
context 'when host gets destroyed' do
|
||
let(:host) { FactoryBot.create(:host, :managed, :with_puppet_ca, :build => false) }
|
||
|
||
test 'should queue puppetca destroy' do
|
||
assert_valid host
|
||
host.queue.clear
|
||
host.send(:queue_puppetca_destroy)
|
||
tasks = host.queue.all.sort.map(&:name)
|
||
assert_equal tasks[0], "Disable PuppetCA autosigning for #{host}"
|
||
assert_equal tasks[1], "Delete PuppetCA certificates for #{host}"
|
||
assert_equal 2, tasks.size
|
||
end
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
Fixes #23626 - Move autosign to build queue