Class: SmartProxyAcdCore::AcdRunner

Inherits:
ForemanTasksCore::Runner::CommandRunner
  • Object
show all
Defined in:
lib/smart_proxy_acd_core/acd_runner.rb

Overview

Implements the AcdRunner to be used by foreman_remote_execution

Constant Summary collapse

DEFAULT_REFRESH_INTERVAL =
1

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options, suspended_action:) ⇒ AcdRunner

Returns a new instance of AcdRunner.



50
51
52
53
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 50

def initialize(options, suspended_action:)
  super(options, :suspended_action => suspended_action)
  @options = options
end

Class Method Details

.parse_dynflow_settings(path) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 15

def parse_dynflow_settings(path)
  return @dynflow_settings if defined? @dynflow_settings
  if File.exist?(path)
    @dynflow_settings = {}
    YAML.load_file(path).each do |key, value|
      @dynflow_settings[key.to_s] = value
    end
  end
  @dynflow_settings
end

.parse_ssl_optionsObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 26

def parse_ssl_options
  return @ssl_options if defined? @ssl_options

  @ssl_options = {}
  return @ssl_options unless URI.parse(@dynflow_settings['foreman_url']).scheme == 'https'

  @ssl_options[:verify_ssl] = OpenSSL::SSL::VERIFY_PEER

  private_key_file = @dynflow_settings['foreman_ssl_key'] || @dynflow_settings['ssl_private_key']
  if private_key_file
    private_key = File.read(private_key_file)
    @ssl_options[:ssl_client_key] = OpenSSL::PKey::RSA.new(private_key)
  end
  certificate_file = @dynflow_settings['foreman_ssl_cert'] || @dynflow_settings['ssl_certificate']
  if certificate_file
    certificate = File.read(certificate_file)
    @ssl_options[:ssl_client_cert] = OpenSSL::X509::Certificate.new(certificate)
  end
  ca_file = @dynflow_settings['foreman_ssl_ca'] || @dynflow_settings['ssl_ca_file']
  @ssl_options[:ssl_ca_file] = ca_file if ca_file
  @ssl_options
end

Instance Method Details

#cleanupObject



81
82
83
84
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 81

def cleanup
  File.unlink(@playbook_tmp_base64_file) if File.exist?(@playbook_tmp_base64_file)
  FileUtils.rm_rf(@playbook_tmp_dir) if Dir.exist?(@playbook_tmp_dir)
end

#closeObject



104
105
106
107
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 104

def close
  logger.debug("Cleanup ansible playbook #{@playbook_tmp_dir} and #{@playbook_tmp_base64_file}")
  cleanup
end

#get_playbook(playbook_id) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 55

def get_playbook(playbook_id)
  logger.debug("Get playbook with id #{playbook_id}")
  response = playbook_resource(playbook_id).get
  if response.code.to_s != '200'
    raise "Failed performing callback to Foreman server: #{response.code} #{response.body}"
  end
  tmp_file = Tempfile.new.path
  File.write(tmp_file, response)
  @playbook_tmp_base64_file = tmp_file
end

#killObject



109
110
111
112
113
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 109

def kill
  publish_data('== TASK ABORTED BY USER ==', 'stdout')
  publish_exit_status(1)
  ::Process.kill('SIGTERM', @command_pid)
end

#playbook_resource(playbook_id) ⇒ Object



66
67
68
69
70
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 66

def playbook_resource(playbook_id)
  dynflow_settings = self.class.parse_dynflow_settings('/etc/smart_proxy_dynflow_core/settings.yml')
  playbook_url = dynflow_settings['foreman_url'] + "/acd/api/v2/ansible_playbooks/#{playbook_id}/grab"
  @resource ||= RestClient::Resource.new(playbook_url, self.class.parse_ssl_options)
end

#startObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 86

def start
  parse_acd_job

  publish_data("Grab playbook to configure application #{@application_name}...", 'stdout')
  get_playbook(@playbook_id)
  store_playbook

  @playbook_path = File.join(@playbook_tmp_dir, @playbook_file)
  raise "Could not run playbook: playbook file #{@playbook_file} not found in playbook dir #{@playbook_tmp_dir}" unless File.exist?(@playbook_path)

  publish_data('Write temporary inventory', 'stdout')
  write_inventory

  command = generate_command
  logger.debug("Running command #{command.join(' ')}")
  initialize_command(*command)
end

#store_playbookObject



72
73
74
75
76
77
78
79
# File 'lib/smart_proxy_acd_core/acd_runner.rb', line 72

def store_playbook
  logger.debug('Unpack ansible playbook')
  dir = Dir.mktmpdir
  raise 'Could not create temporary directory to run ansible playbook' if dir.nil? || !Dir.exist?(dir)
  command = "base64 -d #{@playbook_tmp_base64_file} | tar xz -C #{dir}"
  system(command)
  @playbook_tmp_dir = dir
end