foreman_ansible 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of foreman_ansible might be problematic. Click here for more details.

Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/controllers/ansible_roles_controller.rb +1 -1
  4. data/app/controllers/foreman_ansible/api/v2/hostgroups_controller_extensions.rb +3 -3
  5. data/app/controllers/foreman_ansible/api/v2/hosts_controller_extensions.rb +2 -1
  6. data/app/controllers/foreman_ansible/concerns/hosts_controller_extensions.rb +6 -2
  7. data/app/helpers/foreman_ansible/ansible_roles_helper.rb +10 -3
  8. data/app/helpers/foreman_ansible/hosts_helper_extensions.rb +1 -1
  9. data/app/lib/actions/foreman_ansible/play_host_roles.rb +3 -4
  10. data/app/lib/actions/foreman_ansible/play_hostgroup_roles.rb +3 -4
  11. data/app/models/ansible_role.rb +1 -1
  12. data/app/models/host_ansible_role.rb +1 -1
  13. data/app/models/hostgroup_ansible_role.rb +1 -1
  14. data/app/models/setting/ansible.rb +24 -6
  15. data/app/services/foreman_ansible/fact_importer.rb +1 -1
  16. data/app/services/foreman_ansible/fact_parser.rb +27 -8
  17. data/app/services/foreman_ansible/inventory_creator.rb +13 -24
  18. data/app/services/foreman_ansible/ui_roles_importer.rb +1 -1
  19. data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +3 -4
  20. data/config/routes.rb +1 -0
  21. data/db/migrate/20161122154057_automatically_set_role_timestamps.rb +9 -4
  22. data/lib/foreman_ansible/engine.rb +6 -2
  23. data/lib/foreman_ansible/version.rb +1 -1
  24. data/test/functional/api/v2/ansible_roles_controller_test.rb +1 -0
  25. data/test/functional/api/v2/hostgroups_controller_test.rb +1 -0
  26. data/test/functional/api/v2/hosts_controller_test.rb +1 -0
  27. data/test/functional/hosts_controller_test.rb +1 -0
  28. data/test/support/fixture_support.rb +5 -1
  29. data/test/support/foreman_tasks/task.rb +1 -0
  30. data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +2 -0
  31. data/test/unit/lib/foreman_ansible_core/roles_reader_test.rb +55 -19
  32. data/test/unit/services/fact_parser_test.rb +23 -0
  33. data/test/unit/services/inventory_creator_test.rb +49 -0
  34. data/test/unit/services/proxy_selector_test.rb +1 -0
  35. metadata +28 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce7360304fa351ed3cb712937e4c9eb67ea4308f
4
- data.tar.gz: 73bca3ba994f80ebdac9e109156a6c6b235e3cf4
3
+ metadata.gz: 00bb7f9d29564fb8e61f81e7406c05c50f185fbb
4
+ data.tar.gz: 6c4404d0e53c1fe991a08760af23243ce62fb542
5
5
  SHA512:
6
- metadata.gz: 60674fb5b6e5e5eb4eb9638049c10d48f4dc79128babe895a45e42a7966976ccb5e5d3132e41f16b0b00d568951e59eb7d406ebf0684492338d2e8af7c81b564
7
- data.tar.gz: 4f4655dff0cebf53f34488937737048b3fa6766dbdb668096856c6b3f1aa922618ac50ccf61674573f38146aeac626c6f12a6fe7b3350db274dae6b0da2e3024
6
+ metadata.gz: 5b13f77fa365d11d96e51da73e7cf72ac86335314a156de1b7ad7e7841efa172bbce7d69fb7820aab791f9563ec3fd5b4a2c7020fb6b08dcd966f22bb497fa90
7
+ data.tar.gz: 5d40a1a231244b4ed0efde3041946305385022a25a29994601eff5f29c8e4cb68faf509b6fa68078aae3707f2f0a6819ca3f4ddfa33aadb8915de0de484f09c0
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  require 'rake/testtask'
9
- Rake::TestTask.new("test:core") do |test|
9
+ Rake::TestTask.new('test:core') do |test|
10
10
  test_dir = File.join(File.dirname(__FILE__), 'test/lib')
11
11
  test.pattern = "#{test_dir}/**/*_test.rb"
12
12
  test.libs << test_dir
@@ -49,7 +49,7 @@ class AnsibleRolesController < ::ApplicationController
49
49
  end
50
50
 
51
51
  def no_changed_roles_message
52
- return _('No changes in roles detected.') unless @proxy.present?
52
+ return _('No changes in roles detected.') if @proxy.blank?
53
53
  _('No changes in roles detected on %s.') % @proxy.name
54
54
  end
55
55
  end
@@ -10,9 +10,9 @@ module ForemanAnsible
10
10
  # cannot extend the method properly.
11
11
  # rubocop:disable BlockLength
12
12
  included do
13
- api :POST, '/hostgroups/play_roles',
14
- N_('Plays Ansible roles on hostgroups')
15
- param :id, Array, :required => true
13
+ api :POST, '/hostgroups/:id/play_roles',
14
+ N_('Plays Ansible roles on a hostgroup')
15
+ param :id, String, :required => true
16
16
 
17
17
  def play_roles
18
18
  find_resource
@@ -7,7 +7,8 @@ module ForemanAnsible
7
7
  include ForemanTasks::Triggers
8
8
 
9
9
  included do
10
- api :POST, '/hosts/:id/play_roles', N_('Plays Ansible roles on hosts')
10
+ api :POST, '/hosts/:id/play_roles',
11
+ N_('Plays Ansible roles on a host')
11
12
  param :id, String, :required => true
12
13
 
13
14
  def play_roles
@@ -5,6 +5,10 @@ module ForemanAnsible
5
5
  extend ActiveSupport::Concern
6
6
  include ForemanTasks::Triggers
7
7
 
8
+ included do
9
+ alias_method_chain :action_permission, :ansible
10
+ end
11
+
8
12
  def play_roles
9
13
  find_resource
10
14
  task = async_task(::Actions::ForemanAnsible::PlayHostRoles, @host)
@@ -25,12 +29,12 @@ module ForemanAnsible
25
29
 
26
30
  private
27
31
 
28
- def action_permission
32
+ def action_permission_with_ansible
29
33
  case params[:action]
30
34
  when 'multiple_play_roles', 'play_roles'
31
35
  :view
32
36
  else
33
- super
37
+ action_permission_without_ansible
34
38
  end
35
39
  end
36
40
  end
@@ -3,17 +3,24 @@ module ForemanAnsible
3
3
  module AnsibleRolesHelper
4
4
  def ansible_proxy_links(hash, classes = nil)
5
5
  links = SmartProxy.with_features('Ansible').map do |proxy|
6
- display_link_if_authorized(_('Import from %s') % proxy.name,
6
+ display_link_if_authorized(_('From %s') % proxy.name,
7
7
  hash.merge(:proxy => proxy),
8
8
  :class => classes)
9
9
  end.flatten
10
- links.unshift display_link_if_authorized(_('Import from Foreman host'),
10
+ host_text = if links.any?
11
+ _('From Foreman host')
12
+ else
13
+ _('Import from Foreman host')
14
+ end
15
+ links.unshift display_link_if_authorized(host_text,
11
16
  hash,
12
17
  :class => classes)
13
18
  end
14
19
 
15
20
  def ansible_proxy_import(hash)
16
- select_action_button(_('Import'), {}, ansible_proxy_links(hash))
21
+ select_action_button(_('Import'),
22
+ { :primary => true, :class => 'roles-import' },
23
+ ansible_proxy_links(hash))
17
24
  end
18
25
 
19
26
  def import_time(role)
@@ -15,7 +15,7 @@ module ForemanAnsible
15
15
 
16
16
  def ansible_roles_button(host)
17
17
  link_to(
18
- icon_text('play', ' ' + _('Ansible roles'), :kind => 'fa'),
18
+ _('Run Ansible roles'),
19
19
  play_roles_host_path(:id => host.id),
20
20
  :id => :ansible_roles_button,
21
21
  :class => 'btn btn-default',
@@ -23,10 +23,9 @@ module Actions
23
23
  end
24
24
 
25
25
  def humanized_input
26
- _('on host %{name} through %{proxy}') % {
27
- :name => input.fetch(:host, {})[:name],
28
- :proxy => running_proxy_name
29
- }
26
+ format(_('on host %{name} through %{proxy}'),
27
+ :name => input.fetch(:host, {})[:name],
28
+ :proxy => running_proxy_name)
30
29
  end
31
30
 
32
31
  private
@@ -23,10 +23,9 @@ module Actions
23
23
  end
24
24
 
25
25
  def humanized_input
26
- _('on host group %{name} through proxy %{proxy}') % {
27
- :name => input.fetch(:hostgroup, {})[:name],
28
- :proxy => running_proxy_name
29
- }
26
+ format(_('on host group %{name} through proxy %{proxy}'),
27
+ :name => input.fetch(:hostgroup, {})[:name],
28
+ :proxy => running_proxy_name)
30
29
  end
31
30
 
32
31
  private
@@ -1,5 +1,5 @@
1
1
  # Simple model to store basic info about the Ansible role
2
- class AnsibleRole < ActiveRecord::Base
2
+ class AnsibleRole < ApplicationRecord
3
3
  include Authorizable
4
4
 
5
5
  self.include_root_in_json = false
@@ -1,5 +1,5 @@
1
1
  # Join model that hosts the connection between hosts and ansible_roles
2
- class HostAnsibleRole < ActiveRecord::Base
2
+ class HostAnsibleRole < ApplicationRecord
3
3
  audited :associated_with => :host, :allow_mass_assignment => true
4
4
  belongs_to_host
5
5
  belongs_to :ansible_role
@@ -1,5 +1,5 @@
1
1
  # Join model that hosts the connection between hostgroups and ansible_roles
2
- class HostgroupAnsibleRole < ActiveRecord::Base
2
+ class HostgroupAnsibleRole < ApplicationRecord
3
3
  belongs_to :hostgroup
4
4
  belongs_to :ansible_role
5
5
 
@@ -15,19 +15,28 @@ class Setting
15
15
  set(
16
16
  'ansible_port',
17
17
  N_('Use this port to connect to hosts '\
18
- 'and run Ansible. You can override this on hosts'\
19
- ' by adding a parameter "ansible_port"'),
18
+ 'and run Ansible. You can override this on hosts '\
19
+ 'by adding a parameter "ansible_port"'),
20
20
  22,
21
21
  N_('Port')
22
22
  ),
23
23
  set(
24
24
  'ansible_user',
25
- N_('Foreman will try to connect to hosts as this user by default'\
26
- ' when running Ansible playbooks. You can override this '\
27
- ' on hosts by adding a parameter "ansible_user"'),
25
+ N_('Foreman will try to connect to hosts as this user by '\
26
+ 'default when running Ansible playbooks. You can '\
27
+ 'override this on hosts by adding a parameter '\
28
+ '"ansible_user"'),
28
29
  'root',
29
30
  N_('User')
30
31
  ),
32
+ set(
33
+ 'ansible_become',
34
+ N_('Foreman will use the sudo command to run roles on hosts '\
35
+ 'You can override this on hosts by adding a parameter '\
36
+ '"ansible_become"'),
37
+ true,
38
+ N_('Become')
39
+ ),
31
40
  set(
32
41
  'ansible_ssh_pass',
33
42
  N_('Use this password by default when running Ansible '\
@@ -36,6 +45,15 @@ class Setting
36
45
  'ansible',
37
46
  N_('Password')
38
47
  ),
48
+ set(
49
+ 'ansible_ssh_private_key_file',
50
+ N_('Use this to supply a path to an SSH Private Key '\
51
+ 'that Ansible will use in lieu of a password '\
52
+ 'Override with "ansible_ssh_private_key_file" '\
53
+ 'host parameter'),
54
+ '',
55
+ N_('Private Key Path')
56
+ ),
39
57
  set(
40
58
  'ansible_connection',
41
59
  N_('Use this connection type by default when running '\
@@ -81,7 +99,7 @@ class Setting
81
99
  create(s.update(:category => 'Setting::Ansible'))
82
100
  end
83
101
  end
84
-
102
+ Setting::BLANK_ATTRS.push('ansible_ssh_private_key_file')
85
103
  true
86
104
  end
87
105
 
@@ -31,7 +31,7 @@ module ForemanAnsible
31
31
  end
32
32
 
33
33
  def add_missing_facts(imported_facts, parent = nil, prefix = '')
34
- imported_facts.select! { |_fact_name, fact_value| !fact_value.nil? }
34
+ imported_facts.reject! { |_fact_name, fact_value| fact_value.nil? }
35
35
 
36
36
  imported_facts.each do |imported_name, imported_value|
37
37
  fact_fqn = fact_fqn(imported_name, prefix)
@@ -18,19 +18,19 @@ module ForemanAnsible
18
18
 
19
19
  def architecture
20
20
  name = facts[:ansible_architecture] || facts[:facter_architecture]
21
- Architecture.where(:name => name).first_or_create unless name.blank?
21
+ Architecture.where(:name => name).first_or_create if name.present?
22
22
  end
23
23
 
24
24
  def model
25
25
  name = detect_fact([:ansible_product_name, :facter_virtual,
26
26
  :facter_productname, :facter_model, :model])
27
- Model.where(:name => name.strip).first_or_create unless name.blank?
27
+ Model.where(:name => name.strip).first_or_create if name.present?
28
28
  end
29
29
 
30
30
  def domain
31
31
  name = detect_fact([:ansible_domain, :facter_domain,
32
32
  :ohai_domain, :domain])
33
- Domain.where(:name => name).first_or_create unless name.blank?
33
+ Domain.where(:name => name).first_or_create if name.present?
34
34
  end
35
35
 
36
36
  def support_interfaces_parsing?
@@ -65,12 +65,12 @@ module ForemanAnsible
65
65
  private
66
66
 
67
67
  def ansible_interfaces
68
- return [] unless facts[:ansible_interfaces].present?
68
+ return [] if facts[:ansible_interfaces].blank?
69
69
  facts[:ansible_interfaces].sort
70
70
  end
71
71
 
72
72
  def ip_from_interface(interface)
73
- return unless facts[:"ansible_#{interface}"]['ipv4'].present?
73
+ return if facts[:"ansible_#{interface}"]['ipv4'].blank?
74
74
  facts[:"ansible_#{interface}"]['ipv4']['address']
75
75
  end
76
76
 
@@ -79,10 +79,29 @@ module ForemanAnsible
79
79
  facts[:ansible_lsb] && facts[:ansible_lsb]['id']
80
80
  end
81
81
 
82
+ def debian_os_major_sid
83
+ case facts[:ansible_distribution_major_version]
84
+ when /wheezy/i
85
+ '7'
86
+ when /jessie/i
87
+ '8'
88
+ when /stretch/i
89
+ '9'
90
+ when /buster/i
91
+ '10'
92
+ end
93
+ end
94
+
95
+ # rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity
82
96
  def os_major
83
- facts[:ansible_distribution_major_version] ||
84
- facts[:ansible_lsb] && facts[:ansible_lsb]['major_release'] ||
85
- (facts[:version].split('R')[0] if os_name == 'junos')
97
+ if os_name == 'Debian' &&
98
+ facts[:ansible_distribution_major_version][%r{\/sid}i]
99
+ debian_os_major_sid
100
+ else
101
+ facts[:ansible_distribution_major_version] ||
102
+ facts[:ansible_lsb] && facts[:ansible_lsb]['major_release'] ||
103
+ (facts[:version].split('R')[0] if os_name == 'junos')
104
+ end
86
105
  end
87
106
 
88
107
  def os_release
@@ -35,28 +35,13 @@ module ForemanAnsible
35
35
  end
36
36
 
37
37
  def connection_params(host)
38
- params = {
39
- 'ansible_port' => host_port(host),
40
- 'ansible_user' => host_user(host),
41
- 'ansible_ssh_pass' => host_ssh_pass(host),
42
- 'ansible_connection' => connection_type(host),
43
- 'ansible_winrm_server_cert_validation' => winrm_cert_validation(host)
44
- }
38
+ params = ansible_settings.merge ansible_extra_options(host)
45
39
  # Backward compatibility for Ansible 1.x
46
40
  params['ansible_ssh_port'] = params['ansible_port']
47
41
  params['ansible_ssh_user'] = params['ansible_user']
48
42
  params
49
43
  end
50
44
 
51
- def winrm_cert_validation(host)
52
- host.host_params['ansible_winrm_server_cert_validation'] ||
53
- Setting['ansible_winrm_server_cert_validation']
54
- end
55
-
56
- def connection_type(host)
57
- host.host_params['ansible_connection'] || Setting['ansible_connection']
58
- end
59
-
60
45
  def host_roles(host)
61
46
  host.all_ansible_roles.map(&:name)
62
47
  end
@@ -69,16 +54,20 @@ module ForemanAnsible
69
54
  host.host_params
70
55
  end
71
56
 
72
- def host_port(host)
73
- host.host_params['ansible_port'] || Setting[:ansible_port]
57
+ def ansible_settings
58
+ Hash[
59
+ %w[port user ssh_pass connection
60
+ ssh_private_key_file become
61
+ winrm_server_cert_validation].map do |setting|
62
+ ["ansible_#{setting}", Setting["ansible_#{setting}"]]
63
+ end
64
+ ]
74
65
  end
75
66
 
76
- def host_user(host)
77
- host.host_params['ansible_user'] || Setting[:ansible_user]
78
- end
79
-
80
- def host_ssh_pass(host)
81
- host.host_params['ansible_ssh_pass'] || Setting[:ansible_ssh_pass]
67
+ def ansible_extra_options(host)
68
+ host.host_params.select do |key, _|
69
+ /ansible_/.match(key) || Setting[key]
70
+ end
82
71
  end
83
72
 
84
73
  private
@@ -6,7 +6,7 @@ module ForemanAnsible
6
6
  end
7
7
 
8
8
  def finish_import(changes)
9
- return unless changes.present?
9
+ return if changes.blank?
10
10
  create_new_roles changes['new'] if changes['new']
11
11
  delete_old_roles changes['obsolete'] if changes['obsolete']
12
12
  end
@@ -7,10 +7,9 @@
7
7
  {
8
8
  :disabled => f.object.inherited_ansible_roles.map(&:id),
9
9
  :label => _('Available roles'),
10
- :help_inline => popover('' ,
11
- _('This list of roles will be applied when the host finishes '\
12
- 'provisioning. Users can also play these roles through the API '\
13
- 'or by clicking on the Play Roles button on the Host page '))
10
+ :label_help => _('This list of roles will be applied when the host finishes<br/> '\
11
+ 'provisioning. Users can also play these roles through the API<br/>'\
12
+ 'or by clicking on the Play Roles button on the Host page ').html_safe
14
13
  },
15
14
  { 'data-inheriteds' => f.object.inherited_ansible_roles.map(&:id).to_json }) %>
16
15
  </div>
data/config/routes.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # rubocop:disable BlockLength
1
2
  Rails.application.routes.draw do
2
3
  scope '/ansible' do
3
4
  constraints(:id => %r{[^\/]+}) do
@@ -1,11 +1,16 @@
1
+ # Creation and updates timestamps for Ansible Roles
1
2
  class AutomaticallySetRoleTimestamps < ActiveRecord::Migration
2
3
  def up
3
- change_column :ansible_roles, :created_at, :datetime, :null => true, :default => nil
4
- change_column :ansible_roles, :updated_at, :datetime, :null => true, :default => nil
4
+ change_column :ansible_roles, :created_at, :datetime, :null => true,
5
+ :default => nil
6
+ change_column :ansible_roles, :updated_at, :datetime, :null => true,
7
+ :default => nil
5
8
  end
6
9
 
7
10
  def down
8
- change_column :ansible_roles, :created_at, :datetime, :null => false, :default => Time.now.utc
9
- change_column :ansible_roles, :updated_at, :datetime, :null => false, :default => Time.now.utc
11
+ change_column :ansible_roles, :created_at, :datetime,
12
+ :null => false, :default => Time.now.utc
13
+ change_column :ansible_roles, :updated_at, :datetime,
14
+ :null => false, :default => Time.now.utc
10
15
  end
11
16
  end
@@ -5,6 +5,7 @@ require 'foreman_ansible_core'
5
5
 
6
6
  module ForemanAnsible
7
7
  # This engine connects ForemanAnsible with Foreman core
8
+ # rubocop:disable ClassLength
8
9
  class Engine < ::Rails::Engine
9
10
  engine_name 'foreman_ansible'
10
11
 
@@ -30,9 +31,10 @@ module ForemanAnsible
30
31
  Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
31
32
  end
32
33
 
34
+ # rubocop:disable BlockLength
33
35
  initializer 'foreman_ansible.register_plugin', :before => :finisher_hook do
34
36
  Foreman::Plugin.register :foreman_ansible do
35
- requires_foreman '>= 1.12'
37
+ requires_foreman '>= 1.15'
36
38
 
37
39
  security_block :foreman_ansible do
38
40
  permission :play_roles_on_host,
@@ -64,6 +66,8 @@ module ForemanAnsible
64
66
  :view_ansible_roles, :destroy_ansible_roles,
65
67
  :import_ansible_roles]
66
68
 
69
+ add_all_permissions_to_default_roles
70
+
67
71
  role_assignment_params = { :ansible_role_ids => [],
68
72
  :ansible_roles => [] }
69
73
  parameter_filter Host::Managed, role_assignment_params
@@ -96,7 +100,7 @@ module ForemanAnsible
96
100
  end
97
101
 
98
102
  initializer 'foreman_ansible.assets.precompile' do |app|
99
- app.config.assets.precompile += %w(foreman_ansible/Ansible.png)
103
+ app.config.assets.precompile += %w[foreman_ansible/Ansible.png]
100
104
  end
101
105
 
102
106
  initializer 'foreman_ansible.configure_assets', :group => :assets do
@@ -2,5 +2,5 @@
2
2
  # This way other parts of Foreman can just call ForemanAnsible::VERSION
3
3
  # and detect what version the plugin is running.
4
4
  module ForemanAnsible
5
- VERSION = '1.4.5'.freeze
5
+ VERSION = '1.4.6'.freeze
6
6
  end
@@ -2,6 +2,7 @@ require 'test_plugin_helper'
2
2
 
3
3
  module Api
4
4
  module V2
5
+ # Tests for the controller to CRUD Ansible Roles
5
6
  class AnsibleRolesControllerTest < ActionController::TestCase
6
7
  setup do
7
8
  @role = FactoryGirl.create(:ansible_role)
@@ -3,6 +3,7 @@ require 'dynflow/testing'
3
3
 
4
4
  module Api
5
5
  module V2
6
+ # Tests for the extra methods to play roles on Hostgroup
6
7
  class HostgroupsControllerTest < ActionController::TestCase
7
8
  include ::Dynflow::Testing
8
9
 
@@ -2,6 +2,7 @@ require 'test_plugin_helper'
2
2
 
3
3
  module Api
4
4
  module V2
5
+ # Tests for the extra methods to play roles on a Host
5
6
  class HostsControllerTest < ActionController::TestCase
6
7
  include ::Dynflow::Testing
7
8
 
@@ -9,6 +9,7 @@ class HostsControllerExtensionsTest < ActionController::TestCase
9
9
 
10
10
  tests ::HostsController
11
11
 
12
+ # rubocop:disable Metrics/BlockLength
12
13
  context 'role assignment' do
13
14
  setup do
14
15
  @role = FactoryGirl.create(:ansible_role)
@@ -1,11 +1,15 @@
1
1
  module ForemanAnsible
2
+ # Allow to add fixtures to plugins
2
3
  module PluginFixtures
3
4
  FIXTURE_MAPPING = {
4
5
  :ansible_permissions => :permissions
5
6
  }.freeze
6
7
 
7
8
  def self.add_fixtures(new_fixture_path)
8
- FileUtils.cp(Dir.glob("#{Rails.root}/test/fixtures/*"), new_fixture_path)
9
+ FileUtils.cp(
10
+ Dir.glob(Rails.root.join('test', 'fixtures', '*')),
11
+ new_fixture_path
12
+ )
9
13
  copy_plugin_fixtures new_fixture_path
10
14
  end
11
15
 
@@ -1,5 +1,6 @@
1
1
  module Support
2
2
  module ForemanTasks
3
+ # Stubbing for foreman tasks
3
4
  module Task
4
5
  def stub_tasks!
5
6
  @controller.stubs(:sync_task).returns(build_task_stub)
@@ -1,5 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
+ # Playbook Runner - this class uses foreman_tasks_core
4
+ # to run playbooks
3
5
  class PlaybookRunnerTest < ActiveSupport::TestCase
4
6
  context 'roles dir' do
5
7
  test 'reads default when none provided' do
@@ -1,5 +1,7 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
+ # Tests for the Roles Reader service of ansible core,
4
+ # this class simply reads roles from its path in ansible.cfg
3
5
  class RolesReaderTest < ActiveSupport::TestCase
4
6
  CONFIG_PATH = '/etc/ansible/ansible.cfg'.freeze
5
7
  ROLES_PATH = '/etc/ansible/roles'.freeze
@@ -8,50 +10,84 @@ class RolesReaderTest < ActiveSupport::TestCase
8
10
  test 'detects commented roles_path' do
9
11
  expect_content_config ['#roles_path = thisiscommented!']
10
12
  assert_equal(ROLES_PATH,
11
- ForemanAnsibleCore::RolesReader.roles_path(CONFIG_PATH))
13
+ ForemanAnsibleCore::RolesReader.roles_path)
12
14
  end
13
15
 
14
16
  test 'returns default path if no roles_path defined' do
15
17
  expect_content_config ['norolepath!']
16
18
  assert_equal(ROLES_PATH,
17
- ForemanAnsibleCore::RolesReader.roles_path(CONFIG_PATH))
19
+ ForemanAnsibleCore::RolesReader.roles_path)
18
20
  end
19
21
 
20
22
  test 'returns roles_path if one is defined' do
21
23
  expect_content_config ['roles_path = /mycustom/ansibleroles/path']
22
24
  assert_equal('/mycustom/ansibleroles/path',
23
- ForemanAnsibleCore::RolesReader.roles_path(CONFIG_PATH))
25
+ ForemanAnsibleCore::RolesReader.roles_path)
24
26
  end
25
27
  end
26
28
 
27
29
  describe '#list_roles' do
28
- setup do
29
- # Return a path without actually reading the config file to make tests
30
- # pass even on hosts without Ansible installed
31
- ForemanAnsibleCore::RolesReader.stubs(:roles_path).
32
- returns('/etc/ansible/roles')
30
+ test 'reads roles from paths' do
31
+ expect_content_config ["roles_path = #{ROLES_PATH}"]
32
+ ForemanAnsibleCore::RolesReader.expects(:read_roles)
33
+ .with(ROLES_PATH)
34
+ ForemanAnsibleCore::RolesReader.list_roles
33
35
  end
34
36
 
35
- test 'handles "No such file or dir" with exception' do
36
- Dir.expects(:glob).with("#{ROLES_PATH}/*").raises(Errno::ENOENT)
37
- ex = assert_raises(ForemanAnsibleCore::ReadConfigFileException) do
38
- ForemanAnsibleCore::RolesReader.list_roles
37
+ test 'reads roles from paths' do
38
+ roles_paths = ['/mycustom/roles/path', '/another/path']
39
+ roles_paths.each do |path|
40
+ ForemanAnsibleCore::RolesReader.expects(:read_roles)
41
+ .with(path)
39
42
  end
40
- assert_match(/Could not read Ansible config file/, ex.message)
43
+ expect_content_config ["roles_path = #{roles_paths.join(':')}"]
44
+ ForemanAnsibleCore::RolesReader.list_roles
41
45
  end
42
46
 
43
- test 'raises error if the roles path is not readable' do
44
- Dir.expects(:glob).with("#{ROLES_PATH}/*").raises(Errno::EACCES)
45
- ex = assert_raises(ForemanAnsibleCore::ReadConfigFileException) do
46
- ForemanAnsibleCore::RolesReader.list_roles
47
+ context 'with unreadable roles path' do
48
+ setup do
49
+ expect_content_config ["roles_path = #{ROLES_PATH}"]
50
+ end
51
+
52
+ test 'handles "No such file or dir" with exception' do
53
+ Dir.expects(:glob).with("#{ROLES_PATH}/*").raises(Errno::ENOENT)
54
+ ex = assert_raises(ForemanAnsibleCore::ReadRolesException) do
55
+ ForemanAnsibleCore::RolesReader.list_roles
56
+ end
57
+ assert_match(/Could not read Ansible roles/, ex.message)
58
+ end
59
+
60
+ test 'raises error if the roles path is not readable' do
61
+ Dir.expects(:glob).with("#{ROLES_PATH}/*").raises(Errno::EACCES)
62
+ ex = assert_raises(ForemanAnsibleCore::ReadRolesException) do
63
+ ForemanAnsibleCore::RolesReader.list_roles
64
+ end
65
+ assert_match(/Could not read Ansible roles/, ex.message)
66
+ end
67
+ end
68
+
69
+ context 'with unreadable config' do
70
+ test 'handles "No such file or dir" with exception' do
71
+ File.expects(:readlines).with(CONFIG_PATH).raises(Errno::ENOENT)
72
+ ex = assert_raises(ForemanAnsibleCore::ReadConfigFileException) do
73
+ ForemanAnsibleCore::RolesReader.list_roles
74
+ end
75
+ assert_match(/Could not read Ansible config file/, ex.message)
76
+ end
77
+
78
+ test 'raises error if the roles path is not readable' do
79
+ File.expects(:readlines).with(CONFIG_PATH).raises(Errno::EACCES)
80
+ ex = assert_raises(ForemanAnsibleCore::ReadConfigFileException) do
81
+ ForemanAnsibleCore::RolesReader.list_roles
82
+ end
83
+ assert_match(/Could not read Ansible config file/, ex.message)
47
84
  end
48
- assert_match(/Could not read Ansible config file/, ex.message)
49
85
  end
50
86
  end
51
87
 
52
88
  private
53
89
 
54
90
  def expect_content_config(ansible_cfg_content)
55
- File.expects(:readlines).with(CONFIG_PATH).returns(ansible_cfg_content)
91
+ ForemanAnsibleCore::RolesReader.expects(:roles_path_from_config).returns(ansible_cfg_content)
56
92
  end
57
93
  end
@@ -50,4 +50,27 @@ module ForemanAnsible
50
50
  sample_mock.expects(:first_or_create)
51
51
  end
52
52
  end
53
+
54
+ # Tests for Debian parser
55
+ class DebianFactParserTest < ActiveSupport::TestCase
56
+ setup do
57
+ @facts_parser = ForemanAnsible::FactParser.new(
58
+ HashWithIndifferentAccess.new(
59
+ '_type' => 'ansible',
60
+ '_timestamp' => '2015-10-29 20:01:51 +0100',
61
+ 'ansible_facts' =>
62
+ {
63
+ 'ansible_distribution_major_version' => 'buster/sid',
64
+ 'ansible_distribution' => 'Debian'
65
+ }
66
+ )
67
+ )
68
+ end
69
+
70
+ test 'Parses debian unstable aka sid correctly' do
71
+ os = @facts_parser.operatingsystem
72
+ assert_equal '10', os.major
73
+ assert_equal 'Debian', os.name
74
+ end
75
+ end
53
76
  end
@@ -0,0 +1,49 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanAnsible
4
+ # Test how the inventory creator service transforms host params into
5
+ # inventory variables and connection options
6
+ class InventoryCreatorTest < ActiveSupport::TestCase
7
+ setup do
8
+ @host = FactoryGirl.build(:host)
9
+ end
10
+
11
+ test 'ansible_ parameters get turned into host variables' do
12
+ extra_options = {
13
+ 'ansible_integer_option' => 1,
14
+ 'ansible_string_option' => '1',
15
+ 'ansible_boolean_option' => true,
16
+ 'ansible_user' => 'someone'
17
+ }
18
+ @host.expects(:host_params).returns(extra_options).at_least_once
19
+ inventory = ForemanAnsible::InventoryCreator.new(@host)
20
+
21
+ assert_empty extra_options.to_a - inventory.connection_params(@host).to_a
22
+ end
23
+
24
+ test 'settings are respected if param cannot be found' do
25
+ extra_options = { 'ansible_user' => 'someone', 'ansible_port' => 2000 }
26
+ Setting.expects(:[]).with('ansible_become').returns(nil).at_least_once
27
+ Setting.expects(:[]).with('ansible_ssh_private_key_file').
28
+ returns(nil).at_least_once
29
+ Setting.expects(:[]).with('ansible_port').returns(nil).at_least_once
30
+ Setting.expects(:[]).with('ansible_user').returns(nil).at_least_once
31
+ Setting.expects(:[]).with('ansible_ssh_pass').
32
+ returns('asafepassword').at_least_once
33
+ Setting.expects(:[]).with('ansible_winrm_server_cert_validation').
34
+ returns(true).at_least_once
35
+ Setting.expects(:[]).with('ansible_connection').
36
+ returns('ssh').at_least_once
37
+ @host.expects(:host_params).returns(extra_options).at_least_once
38
+ inventory = ForemanAnsible::InventoryCreator.new(@host)
39
+ connection_params = inventory.connection_params(@host)
40
+ assert_empty extra_options.to_a - inventory.connection_params(@host).to_a
41
+ assert_equal Setting['ansible_connection'],
42
+ connection_params['ansible_connection']
43
+ assert_equal Setting['ansible_ssh_pass'],
44
+ connection_params['ansible_ssh_pass']
45
+ assert_equal Setting['ansible_winrm_server_cert_validation'],
46
+ connection_params['ansible_winrm_server_cert_validation']
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
+ # Tests for the Proxy Selector service
3
4
  class ProxySelectorTest < ActiveSupport::TestCase
4
5
  setup do
5
6
  @host = FactoryGirl.create(:host)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_ansible
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.4.6
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: 2017-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -187,6 +187,7 @@ files:
187
187
  - test/unit/services/fact_importer_test.rb
188
188
  - test/unit/services/fact_parser_test.rb
189
189
  - test/unit/services/fact_sparser_test.rb
190
+ - test/unit/services/inventory_creator_test.rb
190
191
  - test/unit/services/proxy_selector_test.rb
191
192
  - test/unit/services/roles_importer_test.rb
192
193
  - test/unit/services/structured_fact_importer_test.rb
@@ -211,38 +212,39 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
212
  version: '0'
212
213
  requirements: []
213
214
  rubyforge_project:
214
- rubygems_version: 2.4.8
215
+ rubygems_version: 2.6.13
215
216
  signing_key:
216
217
  specification_version: 4
217
218
  summary: Ansible integration with Foreman (theforeman.org)
218
219
  test_files:
219
- - test/factories/ansible_proxy.rb
220
- - test/factories/ansible_roles.rb
221
- - test/fixtures/ansible_permissions.yml
222
- - test/fixtures/sample_facts.json
223
- - test/functional/api/v2/hosts_controller_test.rb
224
- - test/functional/api/v2/ansible_roles_controller_test.rb
225
- - test/functional/api/v2/hostgroups_controller_test.rb
226
- - test/functional/hosts_controller_test.rb
227
- - test/functional/ansible_roles_controller_test.rb
228
- - test/support/fixture_support.rb
229
- - test/support/foreman_tasks/task.rb
230
- - test/support/foreman_test_helper_additions.rb
231
220
  - test/unit/ansible_role_test.rb
232
- - test/unit/concerns/host_managed_extensions_test.rb
233
- - test/unit/concerns/hostgroup_extensions_test.rb
234
- - test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb
235
- - test/unit/host_ansible_role_test.rb
236
221
  - test/unit/hostgroup_ansible_role_test.rb
237
- - test/unit/lib/foreman_ansible_core/playbook_runner_test.rb
238
- - test/unit/lib/foreman_ansible_core/roles_reader_test.rb
239
- - test/unit/lib/proxy_api/ansible_test.rb
240
222
  - test/unit/services/api_roles_importer_test.rb
241
- - test/unit/services/fact_importer_test.rb
242
- - test/unit/services/fact_parser_test.rb
243
223
  - test/unit/services/fact_sparser_test.rb
244
- - test/unit/services/roles_importer_test.rb
224
+ - test/unit/services/proxy_selector_test.rb
245
225
  - test/unit/services/structured_fact_importer_test.rb
246
226
  - test/unit/services/ui_roles_importer_test.rb
247
- - test/unit/services/proxy_selector_test.rb
227
+ - test/unit/services/inventory_creator_test.rb
228
+ - test/unit/services/fact_parser_test.rb
229
+ - test/unit/services/roles_importer_test.rb
230
+ - test/unit/services/fact_importer_test.rb
231
+ - test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb
232
+ - test/unit/lib/foreman_ansible_core/playbook_runner_test.rb
233
+ - test/unit/lib/foreman_ansible_core/roles_reader_test.rb
234
+ - test/unit/lib/proxy_api/ansible_test.rb
235
+ - test/unit/host_ansible_role_test.rb
236
+ - test/unit/concerns/host_managed_extensions_test.rb
237
+ - test/unit/concerns/hostgroup_extensions_test.rb
238
+ - test/factories/ansible_proxy.rb
239
+ - test/factories/ansible_roles.rb
248
240
  - test/test_plugin_helper.rb
241
+ - test/fixtures/ansible_permissions.yml
242
+ - test/fixtures/sample_facts.json
243
+ - test/support/fixture_support.rb
244
+ - test/support/foreman_test_helper_additions.rb
245
+ - test/support/foreman_tasks/task.rb
246
+ - test/functional/ansible_roles_controller_test.rb
247
+ - test/functional/api/v2/ansible_roles_controller_test.rb
248
+ - test/functional/api/v2/hostgroups_controller_test.rb
249
+ - test/functional/api/v2/hosts_controller_test.rb
250
+ - test/functional/hosts_controller_test.rb