smart_proxy_ansible 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/smart_proxy_ansible/configuration_loader.rb +0 -7
- data/lib/smart_proxy_ansible/playbooks_reader.rb +1 -1
- data/lib/smart_proxy_ansible/reader_helper.rb +1 -1
- data/lib/smart_proxy_ansible/runner/ansible_runner.rb +40 -35
- data/lib/smart_proxy_ansible/task_launcher/ansible_runner.rb +1 -1
- data/lib/smart_proxy_ansible/version.rb +1 -1
- metadata +5 -10
- data/lib/smart_proxy_ansible/actions.rb +0 -19
- data/lib/smart_proxy_ansible/remote_execution_core/ansible_runner.rb +0 -64
- data/lib/smart_proxy_ansible/runner/command_creator.rb +0 -61
- data/lib/smart_proxy_ansible/runner/playbook.rb +0 -138
- data/lib/smart_proxy_ansible/task_launcher/playbook.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe91bd15ae06f9e9cc9e2d54fce101129acd7fd39f8f9c3d970909e5bf029545
|
4
|
+
data.tar.gz: d6e887989f068bfa795ceada359e68d911fbeba3d308d3eb0a52e35b1571c3fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfc145591dd06dad090a054332802674e30f2c5b51ef22809b1dcd3a42e24f587cb4e577c9e41740ff691290fe4621610ba092c888f35eaba4fa3fa73a9f90dc
|
7
|
+
data.tar.gz: 53dfb48a0c82802307cb05df916a48d146bce2505148d8eb67162ef4f87bbeab626c02ecfed46e151051d12c6af1efea7c757ac50f24768654ff39933fa2b485
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Smart-proxy Ansible plugin
|
2
2
|
|
3
|
-
Proxy plugin to make [foreman_ansible](https://github.com/theforeman/foreman_ansible) actions run
|
3
|
+
Proxy plugin to make [foreman_ansible](https://github.com/theforeman/foreman_ansible) actions run on the proxy.
|
4
4
|
|
5
5
|
## Compatibility
|
6
6
|
|
@@ -11,8 +11,8 @@ This plugin requires at least Foreman Proxy 2.3.
|
|
11
11
|
### Prerequisites
|
12
12
|
|
13
13
|
We expect your proxy to also have
|
14
|
-
[smart_proxy_dynflow](https://github.com/theforeman/smart_proxy_dynflow) 0.
|
15
|
-
at least, and [
|
14
|
+
[smart_proxy_dynflow](https://github.com/theforeman/smart_proxy_dynflow) 0.5
|
15
|
+
at least, and [smart_proxy_remote_execution_ssh](https://github.com/theforeman/smart_proxy_remote_execution_ssh) 0.4 as
|
16
16
|
a gem requirement.
|
17
17
|
|
18
18
|
### Get the code
|
@@ -4,17 +4,10 @@ module Proxy::Ansible
|
|
4
4
|
require 'smart_proxy_dynflow'
|
5
5
|
require 'smart_proxy_dynflow/continuous_output'
|
6
6
|
require 'smart_proxy_ansible/task_launcher/ansible_runner'
|
7
|
-
require 'smart_proxy_ansible/task_launcher/playbook'
|
8
|
-
require 'smart_proxy_ansible/actions'
|
9
|
-
require 'smart_proxy_ansible/remote_execution_core/ansible_runner'
|
10
7
|
require 'smart_proxy_ansible/runner/ansible_runner'
|
11
|
-
require 'smart_proxy_ansible/runner/command_creator'
|
12
|
-
require 'smart_proxy_ansible/runner/playbook'
|
13
8
|
|
14
9
|
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-runner',
|
15
10
|
TaskLauncher::AnsibleRunner)
|
16
|
-
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-playbook',
|
17
|
-
TaskLauncher::Playbook)
|
18
11
|
end
|
19
12
|
end
|
20
13
|
end
|
@@ -24,7 +24,7 @@ module Proxy
|
|
24
24
|
name = ReaderHelper.playbook_or_role_full_name(path)
|
25
25
|
{
|
26
26
|
name: name,
|
27
|
-
playbooks_content: File.
|
27
|
+
playbooks_content: File.read(path)
|
28
28
|
} if playbooks_to_import.nil? || playbooks_to_import.include?(name)
|
29
29
|
end.compact
|
30
30
|
rescue Errno::ENOENT, Errno::EACCES => e
|
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'shellwords'
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
-
require 'smart_proxy_dynflow/runner/
|
4
|
+
require 'smart_proxy_dynflow/runner/process_manager_command'
|
5
5
|
require 'smart_proxy_dynflow/runner/base'
|
6
6
|
require 'smart_proxy_dynflow/runner/parent'
|
7
7
|
module Proxy::Ansible
|
8
8
|
module Runner
|
9
9
|
class AnsibleRunner < ::Proxy::Dynflow::Runner::Parent
|
10
|
-
include ::Proxy::Dynflow::Runner::
|
11
|
-
attr_reader :execution_timeout_interval
|
10
|
+
include ::Proxy::Dynflow::Runner::ProcessManagerCommand
|
11
|
+
attr_reader :execution_timeout_interval
|
12
12
|
|
13
|
-
def initialize(input, suspended_action:)
|
14
|
-
super input, :suspended_action => suspended_action
|
13
|
+
def initialize(input, suspended_action:, id: nil)
|
14
|
+
super input, :suspended_action => suspended_action, :id => id
|
15
15
|
@inventory = rebuild_secrets(rebuild_inventory(input), input)
|
16
16
|
action_input = input.values.first[:input][:action_input]
|
17
17
|
@playbook = action_input[:script]
|
@@ -34,35 +34,10 @@ module Proxy::Ansible
|
|
34
34
|
start_ansible_runner
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@command_out = r
|
42
|
-
w.close
|
43
|
-
rescue Errno::ENOENT => e
|
44
|
-
publish_exception("Error running command '#{command.join(' ')}'", e)
|
45
|
-
end
|
46
|
-
|
47
|
-
def refresh
|
48
|
-
super
|
49
|
-
@uuid ||= if (f = Dir["#{@root}/artifacts/*"].first)
|
50
|
-
File.basename(f)
|
51
|
-
end
|
52
|
-
return unless @uuid
|
53
|
-
@counter ||= 1
|
54
|
-
job_event_dir = File.join(@root, 'artifacts', @uuid, 'job_events')
|
55
|
-
loop do
|
56
|
-
files = Dir["#{job_event_dir}/*.json"].map do |file|
|
57
|
-
num = File.basename(file)[/\A\d+/].to_i unless file.include?('partial')
|
58
|
-
[file, num]
|
59
|
-
end
|
60
|
-
files_with_nums = files.select { |(_, num)| num && num >= @counter }.sort_by(&:last)
|
61
|
-
break if files_with_nums.empty?
|
62
|
-
logger.debug("[foreman_ansible] - processing event files: #{files_with_nums.map(&:first).inspect}}")
|
63
|
-
files_with_nums.map(&:first).each { |event_file| handle_event_file(event_file) }
|
64
|
-
@counter = files_with_nums.last.last + 1
|
65
|
-
end
|
37
|
+
def run_refresh_output
|
38
|
+
logger.debug('refreshing runner on demand')
|
39
|
+
process_artifacts
|
40
|
+
generate_updates
|
66
41
|
end
|
67
42
|
|
68
43
|
def timeout
|
@@ -75,7 +50,7 @@ module Proxy::Ansible
|
|
75
50
|
end
|
76
51
|
|
77
52
|
def kill
|
78
|
-
::Process.kill('SIGTERM', @
|
53
|
+
::Process.kill('SIGTERM', @process_manager.pid)
|
79
54
|
publish_exit_status(2)
|
80
55
|
@inventory['all']['hosts'].each { |hostname| @exit_statuses[hostname] = 2 }
|
81
56
|
broadcast_data('Timeout for execution passed, stopping the job', 'stderr')
|
@@ -87,8 +62,38 @@ module Proxy::Ansible
|
|
87
62
|
FileUtils.remove_entry(@root) if @tmp_working_dir && Dir.exist?(@root) && @cleanup_working_dirs
|
88
63
|
end
|
89
64
|
|
65
|
+
def publish_exit_status(status)
|
66
|
+
process_artifacts
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize_command(*command)
|
71
|
+
super
|
72
|
+
@process_manager.stdin.close unless @process_manager.done?
|
73
|
+
end
|
74
|
+
|
90
75
|
private
|
91
76
|
|
77
|
+
def process_artifacts
|
78
|
+
@counter ||= 1
|
79
|
+
@uuid ||= if (f = Dir["#{@root}/artifacts/*"].first)
|
80
|
+
File.basename(f)
|
81
|
+
end
|
82
|
+
return unless @uuid
|
83
|
+
job_event_dir = File.join(@root, 'artifacts', @uuid, 'job_events')
|
84
|
+
loop do
|
85
|
+
files = Dir["#{job_event_dir}/*.json"].map do |file|
|
86
|
+
num = File.basename(file)[/\A\d+/].to_i unless file.include?('partial')
|
87
|
+
[file, num]
|
88
|
+
end
|
89
|
+
files_with_nums = files.select { |(_, num)| num && num >= @counter }.sort_by(&:last)
|
90
|
+
break if files_with_nums.empty?
|
91
|
+
logger.debug("[foreman_ansible] - processing event files: #{files_with_nums.map(&:first).inspect}}")
|
92
|
+
files_with_nums.map(&:first).each { |event_file| handle_event_file(event_file) }
|
93
|
+
@counter = files_with_nums.last.last + 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
92
97
|
def handle_event_file(event_file)
|
93
98
|
logger.debug("[foreman_ansible] - parsing event file #{event_file}")
|
94
99
|
begin
|
@@ -25,7 +25,7 @@ module Proxy::Ansible
|
|
25
25
|
# apart when debugging
|
26
26
|
def transform_input(input)
|
27
27
|
action_input = super['action_input']
|
28
|
-
{ 'action_input' => { 'name' => action_input['name'], :task_id => action_input[:task_id] } }
|
28
|
+
{ 'action_input' => { 'name' => action_input['name'], :task_id => action_input[:task_id], :runner_id => action_input[:runner_id] } }
|
29
29
|
end
|
30
30
|
|
31
31
|
# def self.input_format
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_ansible
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -115,14 +115,14 @@ dependencies:
|
|
115
115
|
requirements:
|
116
116
|
- - "~>"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: '0.
|
118
|
+
version: '0.8'
|
119
119
|
type: :runtime
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0.
|
125
|
+
version: '0.8'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: smart_proxy_remote_execution_ssh
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,7 +152,6 @@ files:
|
|
152
152
|
- bin/json_inventory.sh
|
153
153
|
- bundler.d/ansible.rb
|
154
154
|
- lib/smart_proxy_ansible.rb
|
155
|
-
- lib/smart_proxy_ansible/actions.rb
|
156
155
|
- lib/smart_proxy_ansible/api.rb
|
157
156
|
- lib/smart_proxy_ansible/configuration_loader.rb
|
158
157
|
- lib/smart_proxy_ansible/exception.rb
|
@@ -160,13 +159,9 @@ files:
|
|
160
159
|
- lib/smart_proxy_ansible/playbooks_reader.rb
|
161
160
|
- lib/smart_proxy_ansible/plugin.rb
|
162
161
|
- lib/smart_proxy_ansible/reader_helper.rb
|
163
|
-
- lib/smart_proxy_ansible/remote_execution_core/ansible_runner.rb
|
164
162
|
- lib/smart_proxy_ansible/roles_reader.rb
|
165
163
|
- lib/smart_proxy_ansible/runner/ansible_runner.rb
|
166
|
-
- lib/smart_proxy_ansible/runner/command_creator.rb
|
167
|
-
- lib/smart_proxy_ansible/runner/playbook.rb
|
168
164
|
- lib/smart_proxy_ansible/task_launcher/ansible_runner.rb
|
169
|
-
- lib/smart_proxy_ansible/task_launcher/playbook.rb
|
170
165
|
- lib/smart_proxy_ansible/validate_settings.rb
|
171
166
|
- lib/smart_proxy_ansible/variables_extractor.rb
|
172
167
|
- lib/smart_proxy_ansible/version.rb
|
@@ -190,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
185
|
- !ruby/object:Gem::Version
|
191
186
|
version: '0'
|
192
187
|
requirements: []
|
193
|
-
rubygems_version: 3.
|
188
|
+
rubygems_version: 3.2.26
|
194
189
|
signing_key:
|
195
190
|
specification_version: 4
|
196
191
|
summary: Smart-Proxy Ansible plugin
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'smart_proxy_dynflow/action/runner'
|
4
|
-
|
5
|
-
module Proxy::Ansible
|
6
|
-
module Actions
|
7
|
-
# Action that can be run both on Foreman or Foreman proxy side
|
8
|
-
# to execute the playbook run
|
9
|
-
class RunPlaybook < Proxy::Dynflow::Action::Runner
|
10
|
-
def initiate_runner
|
11
|
-
Proxy::Ansible::Runner::Playbook.new(
|
12
|
-
input[:inventory],
|
13
|
-
input[:playbook],
|
14
|
-
input[:options]
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'smart_proxy_dynflow/runner/command_runner'
|
4
|
-
|
5
|
-
module Proxy::Ansible
|
6
|
-
module RemoteExecutionCore
|
7
|
-
# Takes an inventory and runs it through REXCore CommandRunner
|
8
|
-
class AnsibleRunner < ::Proxy::Dynflow::Runner::CommandRunner
|
9
|
-
DEFAULT_REFRESH_INTERVAL = 1
|
10
|
-
CONNECTION_PROMPT = 'Are you sure you want to continue connecting (yes/no)? '
|
11
|
-
|
12
|
-
def initialize(options, suspended_action:)
|
13
|
-
super(options, :suspended_action => suspended_action)
|
14
|
-
@playbook_runner = Proxy::Ansible::Runner::Playbook.new(
|
15
|
-
options['ansible_inventory'],
|
16
|
-
options['script'],
|
17
|
-
options,
|
18
|
-
:suspended_action => suspended_action
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
def start
|
23
|
-
@playbook_runner.logger = logger
|
24
|
-
@playbook_runner.start
|
25
|
-
rescue StandardError => e
|
26
|
-
logger.error(
|
27
|
-
'error while initalizing command'\
|
28
|
-
" #{e.class} #{e.message}:\n #{e.backtrace.join("\n")}"
|
29
|
-
)
|
30
|
-
publish_exception('Error initializing command', e)
|
31
|
-
end
|
32
|
-
|
33
|
-
def fill_continuous_output(continuous_output)
|
34
|
-
delegated_output.fetch('result', []).each do |raw_output|
|
35
|
-
continuous_output.add_raw_output(raw_output)
|
36
|
-
end
|
37
|
-
rescue StandardError => e
|
38
|
-
continuous_output.add_exception(_('Error loading data from proxy'), e)
|
39
|
-
end
|
40
|
-
|
41
|
-
def refresh
|
42
|
-
@command_out = @playbook_runner.command_out
|
43
|
-
@command_in = @playbook_runner.command_in
|
44
|
-
@command_pid = @playbook_runner.command_pid
|
45
|
-
super
|
46
|
-
kill if unknown_host_key_fingerprint?
|
47
|
-
end
|
48
|
-
|
49
|
-
def kill
|
50
|
-
publish_exit_status(1)
|
51
|
-
::Process.kill('SIGTERM', @command_pid)
|
52
|
-
close
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def unknown_host_key_fingerprint?
|
58
|
-
last_output = @continuous_output.raw_outputs.last
|
59
|
-
return if last_output.nil?
|
60
|
-
last_output['output']&.lines&.last == CONNECTION_PROMPT
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Proxy::Ansible
|
4
|
-
# Creates the actual command to be passed to smart_proxy_dynflow to run
|
5
|
-
class CommandCreator
|
6
|
-
def initialize(inventory_file, playbook_file, options = {})
|
7
|
-
@options = options
|
8
|
-
@playbook_file = playbook_file
|
9
|
-
@inventory_file = inventory_file
|
10
|
-
command
|
11
|
-
end
|
12
|
-
|
13
|
-
def command
|
14
|
-
parts = [environment_variables]
|
15
|
-
parts << 'ansible-playbook'
|
16
|
-
parts.concat(command_options)
|
17
|
-
parts << @playbook_file
|
18
|
-
parts
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def environment_variables
|
24
|
-
defaults = { 'JSON_INVENTORY_FILE' => @inventory_file }
|
25
|
-
defaults['ANSIBLE_CALLBACK_WHITELIST'] = '' if rex_command?
|
26
|
-
defaults
|
27
|
-
end
|
28
|
-
|
29
|
-
def command_options
|
30
|
-
opts = ['-i', json_inventory_script]
|
31
|
-
opts.concat([setup_verbosity]) if verbose?
|
32
|
-
opts.concat(['-T', @options[:timeout]]) unless @options[:timeout].nil?
|
33
|
-
opts
|
34
|
-
end
|
35
|
-
|
36
|
-
def json_inventory_script
|
37
|
-
File.expand_path('../../../bin/json_inventory.sh', File.dirname(__FILE__))
|
38
|
-
end
|
39
|
-
|
40
|
-
def setup_verbosity
|
41
|
-
verbosity_level = @options[:verbosity_level].to_i
|
42
|
-
verbosity = '-'
|
43
|
-
verbosity_level.times do
|
44
|
-
verbosity += 'v'
|
45
|
-
end
|
46
|
-
verbosity
|
47
|
-
end
|
48
|
-
|
49
|
-
def verbose?
|
50
|
-
verbosity_level = @options[:verbosity_level]
|
51
|
-
# rubocop:disable Rails/Present
|
52
|
-
!verbosity_level.nil? && !verbosity_level.empty? &&
|
53
|
-
verbosity_level.to_i.positive?
|
54
|
-
# rubocop:enable Rails/Present
|
55
|
-
end
|
56
|
-
|
57
|
-
def rex_command?
|
58
|
-
@options[:remote_execution_command]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,138 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'smart_proxy_dynflow/continuous_output'
|
4
|
-
require 'smart_proxy_dynflow/runner/command_runner'
|
5
|
-
require_relative 'command_creator'
|
6
|
-
require 'tmpdir'
|
7
|
-
require 'net/ssh'
|
8
|
-
|
9
|
-
module Proxy::Ansible
|
10
|
-
module Runner
|
11
|
-
# Implements Proxy::Dynflow::Runner::Base interface for running
|
12
|
-
# Ansible playbooks, used by the Foreman Ansible plugin and Ansible proxy
|
13
|
-
class Playbook < Proxy::Dynflow::Runner::CommandRunner
|
14
|
-
attr_reader :command_out, :command_in, :command_pid
|
15
|
-
|
16
|
-
def initialize(inventory, playbook, options = {}, suspended_action:)
|
17
|
-
super :suspended_action => suspended_action
|
18
|
-
@inventory = rebuild_secrets(inventory, options[:secrets])
|
19
|
-
unknown_hosts.each do |host|
|
20
|
-
add_to_known_hosts(host)
|
21
|
-
end
|
22
|
-
@playbook = playbook
|
23
|
-
@options = options
|
24
|
-
initialize_dirs
|
25
|
-
end
|
26
|
-
|
27
|
-
def start
|
28
|
-
write_inventory
|
29
|
-
write_playbook
|
30
|
-
command = CommandCreator.new(inventory_file,
|
31
|
-
playbook_file,
|
32
|
-
@options).command
|
33
|
-
logger.debug('[foreman_ansible] - Initializing Ansible Runner')
|
34
|
-
Dir.chdir(@ansible_dir) do
|
35
|
-
initialize_command(*command)
|
36
|
-
logger.debug("[foreman_ansible] - Running command '#{command.join(' ')}'")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def kill
|
41
|
-
publish_data('== TASK ABORTED BY USER ==', 'stdout')
|
42
|
-
publish_exit_status(1)
|
43
|
-
::Process.kill('SIGTERM', @command_pid)
|
44
|
-
close
|
45
|
-
end
|
46
|
-
|
47
|
-
def close
|
48
|
-
super
|
49
|
-
FileUtils.remove_entry(@working_dir) if @tmp_working_dir
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def write_inventory
|
55
|
-
ensure_directory(File.dirname(inventory_file))
|
56
|
-
File.write(inventory_file, JSON.dump(@inventory))
|
57
|
-
end
|
58
|
-
|
59
|
-
def write_playbook
|
60
|
-
ensure_directory(File.dirname(playbook_file))
|
61
|
-
File.write(playbook_file, @playbook)
|
62
|
-
end
|
63
|
-
|
64
|
-
def inventory_file
|
65
|
-
File.join(@working_dir, 'foreman-inventories', id)
|
66
|
-
end
|
67
|
-
|
68
|
-
def playbook_file
|
69
|
-
File.join(@working_dir, "foreman-playbook-#{id}.yml")
|
70
|
-
end
|
71
|
-
|
72
|
-
def events_dir
|
73
|
-
File.join(@working_dir, 'events', id.to_s)
|
74
|
-
end
|
75
|
-
|
76
|
-
def ensure_directory(path)
|
77
|
-
if File.exist?(path)
|
78
|
-
raise "#{path} expected to be a directory" unless File.directory?(path)
|
79
|
-
else
|
80
|
-
FileUtils.mkdir_p(path)
|
81
|
-
end
|
82
|
-
path
|
83
|
-
end
|
84
|
-
|
85
|
-
def initialize_dirs
|
86
|
-
settings = Proxy::Ansible::Plugin.settings
|
87
|
-
initialize_working_dir(settings[:working_dir])
|
88
|
-
initialize_ansible_dir(settings[:ansible_dir])
|
89
|
-
end
|
90
|
-
|
91
|
-
def initialize_working_dir(working_dir)
|
92
|
-
if working_dir.nil?
|
93
|
-
@working_dir = Dir.mktmpdir
|
94
|
-
@tmp_working_dir = true
|
95
|
-
else
|
96
|
-
@working_dir = File.expand_path(working_dir)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def initialize_ansible_dir(ansible_dir)
|
101
|
-
raise "Ansible dir #{ansible_dir} does not exist" unless
|
102
|
-
!ansible_dir.nil? && File.exist?(ansible_dir)
|
103
|
-
@ansible_dir = ansible_dir
|
104
|
-
end
|
105
|
-
|
106
|
-
def unknown_hosts
|
107
|
-
@inventory['all']['hosts'].select do |host|
|
108
|
-
Net::SSH::KnownHosts.search_for(host).empty?
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def add_to_known_hosts(host)
|
113
|
-
logger.warn("[foreman_ansible] - Host #{host} not found in known_hosts")
|
114
|
-
Net::SSH::Transport::Session.new(host).host_keys.each do |host_key|
|
115
|
-
Net::SSH::KnownHosts.add(host, host_key)
|
116
|
-
end
|
117
|
-
logger.warn("[foreman_ansible] - Added host key #{host} to known_hosts")
|
118
|
-
rescue StandardError => e
|
119
|
-
logger.error('[foreman_ansible] - Failed to save host key for '\
|
120
|
-
"#{host}: #{e}")
|
121
|
-
end
|
122
|
-
|
123
|
-
def rebuild_secrets(inventory, secrets)
|
124
|
-
inventory['all']['hosts'].each do |name|
|
125
|
-
per_host = secrets['per-host'][name]
|
126
|
-
|
127
|
-
new_secrets = {
|
128
|
-
'ansible_password' => inventory['ssh_password'] || per_host['ansible_password'],
|
129
|
-
'ansible_become_password' => inventory['effective_user_password'] || per_host['ansible_become_password']
|
130
|
-
}
|
131
|
-
inventory['_meta']['hostvars'][name].update(new_secrets)
|
132
|
-
end
|
133
|
-
|
134
|
-
inventory
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'smart_proxy_dynflow/action/runner'
|
2
|
-
|
3
|
-
module Proxy::Ansible
|
4
|
-
module TaskLauncher
|
5
|
-
class Playbook < Proxy::Dynflow::TaskLauncher::Batch
|
6
|
-
class PlaybookRunnerAction < Proxy::Dynflow::Action::Runner
|
7
|
-
def initiate_runner
|
8
|
-
additional_options = {
|
9
|
-
:step_id => run_step_id,
|
10
|
-
:uuid => execution_plan_id
|
11
|
-
}
|
12
|
-
::Proxy::Ansible::RemoteExecutionCore::AnsibleRunner.new(
|
13
|
-
input.merge(additional_options),
|
14
|
-
:suspended_action => suspended_action
|
15
|
-
)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def child_launcher(parent)
|
20
|
-
::Proxy::Dynflow::TaskLauncher::Single.new(world, callback, :parent => parent,
|
21
|
-
:action_class_override => PlaybookRunnerAction)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|