foreman_ansible_core 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/foreman_ansible_core.rb +10 -0
- data/lib/foreman_ansible_core/command_creator.rb +44 -0
- data/lib/foreman_ansible_core/exception.rb +2 -2
- data/lib/foreman_ansible_core/playbook_runner.rb +10 -40
- data/lib/foreman_ansible_core/remote_execution_core/ansible_runner.rb +44 -0
- data/lib/foreman_ansible_core/remote_execution_core/settings_override.rb +18 -0
- data/lib/foreman_ansible_core/roles_reader.rb +34 -18
- data/lib/foreman_ansible_core/version.rb +1 -1
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fdc186ce16d241d9cd97689ce7e3b75171b3d21
|
4
|
+
data.tar.gz: 41d0830a8eba1bc7074c0e623d6188bfbf48485a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7fe6f8c44ac273b5587097e967920a38724140926a4738d220f0b12926858378a4f3b282d3e924736f13e7bcd2076ac27bd009cc0be0fb78e80b306529dd390
|
7
|
+
data.tar.gz: e5c89340ddae000a582667216a453546b92c1c9ad3e1f7eba063dc8f655ead6986553f3a99535553a3eed7ae2a6501af8b1607fece85b7b5165e80a98ca02223
|
data/lib/foreman_ansible_core.rb
CHANGED
@@ -14,6 +14,16 @@ module ForemanAnsibleCore
|
|
14
14
|
require 'foreman_ansible_core/actions'
|
15
15
|
end
|
16
16
|
|
17
|
+
if defined? ForemanRemoteExecutionCore
|
18
|
+
require 'foreman_remote_execution_core/actions'
|
19
|
+
require 'foreman_ansible_core/remote_execution_core/ansible_runner'
|
20
|
+
require 'foreman_ansible_core/remote_execution_core/settings_override'
|
21
|
+
ForemanRemoteExecutionCore::Actions::RunScript.send(
|
22
|
+
:prepend,
|
23
|
+
ForemanAnsibleCore::RemoteExecutionCore::SettingsOverride
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
17
27
|
require 'foreman_ansible_core/roles_reader'
|
18
28
|
require 'foreman_ansible_core/version'
|
19
29
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ForemanAnsibleCore
|
2
|
+
# Creates the actual command to be passed to foreman_tasks_core to run
|
3
|
+
class CommandCreator
|
4
|
+
attr_reader :command
|
5
|
+
|
6
|
+
def initialize(inventory_file, playbook_file, options = {})
|
7
|
+
@options = options
|
8
|
+
@command = [{ 'JSON_INVENTORY_FILE' => inventory_file }]
|
9
|
+
@command << 'ansible-playbook'
|
10
|
+
@command = command_options(@command)
|
11
|
+
@command << playbook_file
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def command_options(command)
|
17
|
+
command.concat(['-i', json_inventory_script])
|
18
|
+
command.concat([setup_verbosity]) if verbose?
|
19
|
+
command.concat(['-T', @options[:timeout]]) unless @options[:timeout].nil?
|
20
|
+
command
|
21
|
+
end
|
22
|
+
|
23
|
+
def json_inventory_script
|
24
|
+
File.expand_path('../../bin/json_inventory.sh', File.dirname(__FILE__))
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_verbosity
|
28
|
+
verbosity_level = @options[:verbosity_level].to_i
|
29
|
+
verbosity = '-'
|
30
|
+
verbosity_level.times do
|
31
|
+
verbosity += 'v'
|
32
|
+
end
|
33
|
+
verbosity
|
34
|
+
end
|
35
|
+
|
36
|
+
def verbose?
|
37
|
+
verbosity_level = @options[:verbosity_level]
|
38
|
+
# rubocop:disable Rails/Present
|
39
|
+
!verbosity_level.nil? && !verbosity_level.empty? &&
|
40
|
+
verbosity_level.to_i > 0
|
41
|
+
# rubocop:enable Rails/Present
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'foreman_tasks_core/runner/command_runner'
|
2
|
+
require_relative 'command_creator'
|
2
3
|
require 'tmpdir'
|
3
4
|
|
4
5
|
module ForemanAnsibleCore
|
5
6
|
# Implements ForemanTasksCore::Runner::Base interface for running
|
6
7
|
# Ansible playbooks, used by the Foreman Ansible plugin and Ansible proxy
|
7
8
|
class PlaybookRunner < ForemanTasksCore::Runner::CommandRunner
|
9
|
+
attr_reader :command_out, :command_in, :command_pid
|
10
|
+
|
8
11
|
def initialize(inventory, playbook, options = {})
|
9
12
|
super
|
10
13
|
@inventory = inventory
|
@@ -16,25 +19,16 @@ module ForemanAnsibleCore
|
|
16
19
|
def start
|
17
20
|
write_inventory
|
18
21
|
write_playbook
|
22
|
+
command = CommandCreator.new(inventory_file,
|
23
|
+
playbook_file,
|
24
|
+
@options).command
|
19
25
|
logger.debug('[foreman_ansible] - Initializing Ansible Runner')
|
20
26
|
Dir.chdir(@ansible_dir) do
|
21
27
|
initialize_command(*command)
|
28
|
+
logger.debug("[foreman_ansible] - Running command #{command}")
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
25
|
-
def command
|
26
|
-
command = [{ 'JSON_INVENTORY_FILE' => inventory_file }]
|
27
|
-
command << 'ansible-playbook'
|
28
|
-
command.concat(['-i', json_inventory_script])
|
29
|
-
if verbose?
|
30
|
-
command.concat([setup_verbosity])
|
31
|
-
end
|
32
|
-
command.concat(['-T', @options[:timeout]]) unless @options[:timeout].nil?
|
33
|
-
command << playbook_file
|
34
|
-
logger.debug("[foreman_ansible] - Running command #{command}")
|
35
|
-
command
|
36
|
-
end
|
37
|
-
|
38
32
|
def kill
|
39
33
|
publish_data('== TASK ABORTED BY USER ==', 'stdout')
|
40
34
|
publish_exit_status(1)
|
@@ -47,10 +41,6 @@ module ForemanAnsibleCore
|
|
47
41
|
FileUtils.remove_entry(@working_dir) if @tmp_working_dir
|
48
42
|
end
|
49
43
|
|
50
|
-
def json_inventory_script
|
51
|
-
File.expand_path('../../bin/json_inventory.sh', File.dirname(__FILE__))
|
52
|
-
end
|
53
|
-
|
54
44
|
private
|
55
45
|
|
56
46
|
def write_inventory
|
@@ -100,29 +90,9 @@ module ForemanAnsibleCore
|
|
100
90
|
end
|
101
91
|
|
102
92
|
def initialize_ansible_dir(ansible_dir)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
raise "Ansible dir #{ansible_dir} does not exist"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def setup_verbosity
|
111
|
-
verbosity_level = @options[:verbosity_level].to_i
|
112
|
-
logger.debug('[foreman_ansible] - Setting Ansible verbosity level to'\
|
113
|
-
"#{verbosity_level}")
|
114
|
-
verbosity = '-'
|
115
|
-
verbosity_level.times do
|
116
|
-
verbosity += 'v'
|
117
|
-
end
|
118
|
-
verbosity
|
93
|
+
raise "Ansible dir #{ansible_dir} does not exist" unless
|
94
|
+
!ansible_dir.nil? && File.exist?(ansible_dir)
|
95
|
+
@ansible_dir = ansible_dir
|
119
96
|
end
|
120
|
-
|
121
|
-
def verbose?
|
122
|
-
verbosity_level = @options[:verbosity_level]
|
123
|
-
!verbosity_level.nil? && !verbosity_level.empty? &&
|
124
|
-
verbosity_level.to_i > 0
|
125
|
-
end
|
126
|
-
|
127
97
|
end
|
128
98
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
if defined? ::ForemanRemoteExecutionCore
|
2
|
+
module ForemanAnsibleCore
|
3
|
+
module RemoteExecutionCore
|
4
|
+
# Takes an inventory and runs it through REXCore CommandRunner
|
5
|
+
class AnsibleRunner < ::ForemanTasksCore::Runner::CommandRunner
|
6
|
+
DEFAULT_REFRESH_INTERVAL = 1
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
super(options)
|
10
|
+
@playbook_runner = ForemanAnsibleCore::PlaybookRunner.new(
|
11
|
+
options['ansible_inventory'],
|
12
|
+
options['script'],
|
13
|
+
options
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
@playbook_runner.start
|
19
|
+
rescue StandardError => e
|
20
|
+
logger.error(
|
21
|
+
'error while initalizing command'\
|
22
|
+
" #{e.class} #{e.message}:\n #{e.backtrace.join("\n")}"
|
23
|
+
)
|
24
|
+
publish_exception('Error initializing command', e)
|
25
|
+
end
|
26
|
+
|
27
|
+
def fill_continuous_output(continuous_output)
|
28
|
+
delegated_output.fetch('result', []).each do |raw_output|
|
29
|
+
continuous_output.add_raw_output(raw_output)
|
30
|
+
end
|
31
|
+
rescue StandardError => e
|
32
|
+
continuous_output.add_exception(_('Error loading data from proxy'), e)
|
33
|
+
end
|
34
|
+
|
35
|
+
def refresh
|
36
|
+
@command_out = @playbook_runner.command_out
|
37
|
+
@command_in = @playbook_runner.command_in
|
38
|
+
@command_pid = @playbook_runner.command_pid
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ForemanAnsibleCore
|
2
|
+
module RemoteExecutionCore
|
3
|
+
# Ensure the Ansible provider is used whenever a JobTemplate using this
|
4
|
+
# provider is called.
|
5
|
+
module SettingsOverride
|
6
|
+
def initiate_runner
|
7
|
+
return super unless input['ansible_inventory']
|
8
|
+
additional_options = {
|
9
|
+
:step_id => run_step_id,
|
10
|
+
:uuid => execution_plan_id
|
11
|
+
}
|
12
|
+
::ForemanAnsibleCore::RemoteExecutionCore::AnsibleRunner.new(
|
13
|
+
input.merge(additional_options)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,31 +3,18 @@ module ForemanAnsibleCore
|
|
3
3
|
class RolesReader
|
4
4
|
class << self
|
5
5
|
DEFAULT_CONFIG_FILE = '/etc/ansible/ansible.cfg'.freeze
|
6
|
+
DEFAULT_ROLES_PATH = '/etc/ansible/roles'.freeze
|
6
7
|
|
7
8
|
def list_roles
|
8
|
-
|
9
|
-
'/etc/ansible/ansible.cfg roles_path')
|
10
|
-
Dir.glob("#{roles_path}/*").map do |path|
|
11
|
-
path.split('/').last
|
12
|
-
end
|
13
|
-
rescue Errno::ENOENT, Errno::EACCES => e
|
14
|
-
logger.debug("[foreman_ansible] - #{e.backtrace}")
|
15
|
-
exception_message = '[foreman_ansible] - Could not read Ansible config'\
|
16
|
-
" file #{DEFAULT_CONFIG_FILE} - #{e.message}"
|
17
|
-
raise ReadConfigFileException.new(exception_message)
|
9
|
+
roles_path.split(':').map { |path| read_roles(path) }.flatten
|
18
10
|
end
|
19
11
|
|
20
|
-
def roles_path(
|
21
|
-
default_path = '/etc/ansible/roles'
|
22
|
-
roles_line = File.readlines(ansible_config_file).select do |line|
|
23
|
-
line =~ /roles_path/
|
24
|
-
end
|
12
|
+
def roles_path(roles_line = roles_path_from_config)
|
25
13
|
# Default to /etc/ansible/roles if none found
|
26
|
-
return
|
14
|
+
return DEFAULT_ROLES_PATH if roles_line.empty?
|
27
15
|
roles_path_key = roles_line.first.split('=').first.strip
|
28
16
|
# In case of commented roles_path key "#roles_path", return default
|
29
|
-
return
|
30
|
-
# In case roles_path is there, and is not commented, return the value
|
17
|
+
return DEFAULT_ROLES_PATH unless roles_path_key == 'roles_path'
|
31
18
|
roles_line.first.split('=').last.strip
|
32
19
|
end
|
33
20
|
|
@@ -40,6 +27,35 @@ module ForemanAnsibleCore
|
|
40
27
|
::Proxy::LogBuffer::Decorator.instance
|
41
28
|
end
|
42
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def read_roles(roles_path)
|
34
|
+
rescue_and_raise_file_exception ReadRolesException,
|
35
|
+
roles_path, 'roles' do
|
36
|
+
Dir.glob("#{roles_path}/*").map do |path|
|
37
|
+
path.split('/').last
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def roles_path_from_config
|
43
|
+
rescue_and_raise_file_exception ReadConfigFileException,
|
44
|
+
DEFAULT_CONFIG_FILE, 'config file' do
|
45
|
+
File.readlines(DEFAULT_CONFIG_FILE).select do |line|
|
46
|
+
line =~ /roles_path/
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def rescue_and_raise_file_exception(exception, path, type)
|
52
|
+
yield
|
53
|
+
rescue Errno::ENOENT, Errno::EACCES => e
|
54
|
+
logger.debug(e.backtrace)
|
55
|
+
exception_message = "Could not read Ansible #{type} "\
|
56
|
+
"#{path} - #{e.message}"
|
57
|
+
raise exception.new(exception_message)
|
58
|
+
end
|
43
59
|
end
|
44
60
|
end
|
45
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_ansible_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Lobato Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.52'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.52'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: foreman-tasks-core
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,9 +38,9 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.1'
|
41
|
-
description: |
|
42
|
-
|
43
|
-
|
41
|
+
description: |2
|
42
|
+
Ansible integration with Foreman - core parts for dealing with Ansible concepts,
|
43
|
+
usable by foreman_ansible or smart_proxy_ansible to delegate the execution.
|
44
44
|
email:
|
45
45
|
- elobatocs@gmail.com
|
46
46
|
executables: []
|
@@ -51,8 +51,11 @@ files:
|
|
51
51
|
- bin/json_inventory.sh
|
52
52
|
- lib/foreman_ansible_core.rb
|
53
53
|
- lib/foreman_ansible_core/actions.rb
|
54
|
+
- lib/foreman_ansible_core/command_creator.rb
|
54
55
|
- lib/foreman_ansible_core/exception.rb
|
55
56
|
- lib/foreman_ansible_core/playbook_runner.rb
|
57
|
+
- lib/foreman_ansible_core/remote_execution_core/ansible_runner.rb
|
58
|
+
- lib/foreman_ansible_core/remote_execution_core/settings_override.rb
|
56
59
|
- lib/foreman_ansible_core/roles_reader.rb
|
57
60
|
- lib/foreman_ansible_core/version.rb
|
58
61
|
homepage: https://github.com/theforeman/foreman_ansible
|
@@ -75,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
78
|
version: '0'
|
76
79
|
requirements: []
|
77
80
|
rubyforge_project:
|
78
|
-
rubygems_version: 2.
|
81
|
+
rubygems_version: 2.6.12
|
79
82
|
signing_key:
|
80
83
|
specification_version: 4
|
81
84
|
summary: 'Ansible integration with Foreman (theforeman.org): core bits'
|