foreman/app/models/concerns/orchestration/ssh_provision.rb @ fba2bf5f
dd42df0a | Ohad Levy | module Orchestration::SSHProvision
|
|
dc457681 | Joseph Mitchell Magen | extend ActiveSupport::Concern
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | included do
|
|
after_validation :validate_ssh_provisioning, :queue_ssh_provision
|
|||
attr_accessor :template_file, :client
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def ssh_provision?
|
|
fba2bf5f | Greg Sutcliffe | compute_attributes.present? && capabilities.include?(:image) && !image.try(:user_data)
|
|
dc457681 | Joseph Mitchell Magen | end
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | protected
|
|
def queue_ssh_provision
|
|||
return unless ssh_provision? and errors.empty?
|
|||
new_record? ? queue_ssh_provision_create : queue_ssh_provision_update
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | # I guess this is not going to happen on create as we might not have an ip address yet.
|
|
def queue_ssh_provision_create
|
|||
730e3372 | Sam Kottler | post_queue.create(:name => _("Prepare post installation script for %s") % self, :priority => 2000,
|
|
dc457681 | Joseph Mitchell Magen | :action => [self, :setSSHProvisionScript])
|
|
730e3372 | Sam Kottler | post_queue.create(:name => _("Wait for %s to come online") % self, :priority => 2001,
|
|
dc457681 | Joseph Mitchell Magen | :action => [self, :setSSHWaitForResponse])
|
|
730e3372 | Sam Kottler | post_queue.create(:name => _("Enable certificate generation for %s") % self, :priority => 2002,
|
|
dc457681 | Joseph Mitchell Magen | :action => [self, :setSSHCert])
|
|
730e3372 | Sam Kottler | post_queue.create(:name => _("Configure instance %s via SSH") % self, :priority => 2003,
|
|
dc457681 | Joseph Mitchell Magen | :action => [self, :setSSHProvision])
|
|
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def queue_ssh_provision_update; end
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def setSSHProvisionScript
|
|
logger.info "About to start post launch script on #{name}"
|
|||
template = configTemplate(:kind => "finish")
|
|||
@host = self
|
|||
logger.info "generating template to upload to #{name}"
|
|||
self.template_file = unattended_render_to_temp_file(template.template)
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def delSSHProvisionScript; end
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def setSSHWaitForResponse
|
|
logger.info "Starting SSH provisioning script - waiting for #{ip} to respond"
|
|||
if compute_resource.respond_to?(:key_pair) and compute_resource.key_pair.try(:secret)
|
|||
credentials = { :key_data => [compute_resource.key_pair.secret] }
|
|||
elsif vm.respond_to?(:password) and vm.password.present?
|
|||
credentials = { :password => vm.password, :auth_methods => ["password"] }
|
|||
else
|
|||
raise ::Foreman::Exception.new(N_('Unable to find proper authentication method'))
|
|||
dd42df0a | Ohad Levy | end
|
|
dc457681 | Joseph Mitchell Magen | self.client = Foreman::Provision::SSH.new ip, image.username, { :template => template_file.path, :uuid => uuid }.merge(credentials)
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | rescue => e
|
|
failure _("Failed to login via SSH to %{name}: %{e}") % { :name => name, :e => e }, e.backtrace
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def delSSHWaitForResponse; end
|
|
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def setSSHCert
|
|
self.handle_ca
|
|||
return false if errors.any?
|
|||
logger.info "Revoked old certificates and enabled autosign"
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def delSSHCert
|
|
# since we enable certificates/autosign via here, we also need to make sure we clean it up in case of an error
|
|||
if puppetca?
|
|||
respond_to?(:initialize_puppetca,true) && initialize_puppetca && delCertificate && delAutosign
|
|||
end
|
|||
rescue => e
|
|||
failure _("Failed to remove certificates for %{name}: %{e}") % { :name => name, :e => e }, e.backtrace
|
|||
end
|
|||
dd42df0a | Ohad Levy | ||
dc457681 | Joseph Mitchell Magen | def setSSHProvision
|
|
logger.info "SSH connection established to #{ip} - executing template"
|
|||
if client.deploy!
|
|||
# since we are in a after_commit callback, we need to fetch our host again
|
|||
h = Host.find(id)
|
|||
h.build = false
|
|||
h.installed_at = Time.now.utc
|
|||
# calling validations would trigger the whole orchestration layer again, we don't want it while we are inside an orchestration action ourselves.
|
|||
h.save(:validate => false)
|
|||
# but it does mean we need to manually remove puppetca autosign, remove this when we no longer part of after_commit callback
|
|||
respond_to?(:initialize_puppetca,true) && initialize_puppetca && delAutosign if puppetca?
|
|||
else
|
|||
raise ::Foreman::Exception.new(N_("Provision script had a non zero exit, removing instance"))
|
|||
dd42df0a | Ohad Levy | end
|
|
dc457681 | Joseph Mitchell Magen | rescue => e
|
|
failure _("Failed to launch script on %{name}: %{e}") % { :name => name, :e => e }, e.backtrace
|
|||
dd42df0a | Ohad Levy | end
|
|
def delSSHProvision; end
|
|||
def validate_ssh_provisioning
|
|||
return unless ssh_provision?
|
|||
return if Rails.env == "test"
|
|||
status = true
|
|||
begin
|
|||
65f3ce1e | David Swift | template = configTemplate(:kind => "finish")
|
|
dd42df0a | Ohad Levy | rescue => e
|
|
65f3ce1e | David Swift | status = false
|
|
dd42df0a | Ohad Levy | end
|
|
65f3ce1e | David Swift | status = false if template.nil?
|
|
bfbf7ed8 | Lukas Zapletal | failure(_("No finish templates were found for this host, make sure you define at least one in your %s settings") % os ) unless status
|
|
dd42df0a | Ohad Levy | end
|
|
end
|