foreman_ansible_core 1.1.1 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f416c282ff17d92a2c756375ecd3332b6781a8c9
4
- data.tar.gz: 07cb920eb62b34aa9d96683e81d0b7918262d77e
3
+ metadata.gz: 7fdc186ce16d241d9cd97689ce7e3b75171b3d21
4
+ data.tar.gz: 41d0830a8eba1bc7074c0e623d6188bfbf48485a
5
5
  SHA512:
6
- metadata.gz: 014b581ee8de8afcb3842f501ab72a950374cd536dc83f419c1d4c119d9a11156d84021136354b150e0df8e7b2b44cdbb6d3bf8024819c67a08ef0810688ab55
7
- data.tar.gz: 88f4a747f66b93186c7a73ee91fdd8923b93fb246efd1e304d4a0e8bafa0636eabc1150ab61a4068a3437f30559aaca7e1a114e6af973fbd201edb9cb87c84b2
6
+ metadata.gz: a7fe6f8c44ac273b5587097e967920a38724140926a4738d220f0b12926858378a4f3b282d3e924736f13e7bcd2076ac27bd009cc0be0fb78e80b306529dd390
7
+ data.tar.gz: e5c89340ddae000a582667216a453546b92c1c9ad3e1f7eba063dc8f655ead6986553f3a99535553a3eed7ae2a6501af8b1607fece85b7b5165e80a98ca02223
@@ -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
@@ -30,6 +30,6 @@ module ForemanAnsibleCore
30
30
  end
31
31
  end
32
32
 
33
- class ReadConfigFileException < ForemanAnsibleCore::Exception
34
- end
33
+ class ReadConfigFileException < ForemanAnsibleCore::Exception; end
34
+ class ReadRolesException < ForemanAnsibleCore::Exception; end
35
35
  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
- if !ansible_dir.nil? && File.exist?(ansible_dir)
104
- @ansible_dir = ansible_dir
105
- else
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
- logger.info('[foreman_ansible] - Reading roles from '\
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(ansible_config_file = DEFAULT_CONFIG_FILE)
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 default_path if roles_line.empty?
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 default_path unless roles_path_key == 'roles_path'
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
@@ -1,3 +1,3 @@
1
1
  module ForemanAnsibleCore
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  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: 1.1.1
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: 2017-03-30 00:00:00.000000000 Z
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.42'
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.42'
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
- Ansible integration with Foreman - core parts for dealing with Ansible concepts,
43
- usable by foreman_ansible or smart_proxy_ansible to delegate the execution.
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.4.8
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'