foreman_ansible 1.5.2 → 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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/controllers/foreman_ansible/api/v2/hostgroups_controller_extensions.rb +6 -21
  4. data/app/controllers/foreman_ansible/api/v2/hosts_controller_extensions.rb +5 -18
  5. data/app/controllers/foreman_ansible/concerns/hostgroups_controller_extensions.rb +12 -5
  6. data/app/controllers/foreman_ansible/concerns/hosts_controller_extensions.rb +20 -16
  7. data/app/controllers/foreman_ansible/concerns/job_invocation_helper.rb +17 -0
  8. data/app/helpers/foreman_ansible/ansible_plugin_helper.rb +1 -5
  9. data/app/helpers/foreman_ansible/ansible_reports_helper.rb +2 -1
  10. data/app/helpers/foreman_ansible/hosts_helper_extensions.rb +19 -18
  11. data/app/lib/actions/foreman_ansible/helpers/host_common.rb +1 -5
  12. data/app/models/ansible_role.rb +5 -0
  13. data/app/models/concerns/foreman_ansible/has_many_ansible_roles.rb +1 -3
  14. data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +9 -0
  15. data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +0 -4
  16. data/app/models/foreman_ansible/ansible_provider.rb +24 -0
  17. data/app/models/setting/ansible.rb +4 -1
  18. data/app/services/foreman_ansible/fact_parser.rb +4 -2
  19. data/app/services/foreman_ansible/inventory_creator.rb +7 -2
  20. data/app/services/foreman_ansible/proxy_selector.rb +6 -0
  21. data/app/services/foreman_ansible/ui_roles_importer.rb +2 -0
  22. data/app/views/ansible_roles/index.html.erb +1 -2
  23. data/app/views/foreman_ansible/ansible_roles/_hostgroup_ansible_roles_button.erb +8 -7
  24. data/app/views/foreman_ansible/job_templates/ansible_roles.erb +17 -0
  25. data/config/routes.rb +1 -0
  26. data/db/migrate/20160705082036_create_ansible_role.rb +1 -1
  27. data/db/migrate/20160706074540_create_join_table_hosts_ansible_roles.rb +1 -1
  28. data/db/migrate/20160707195442_create_host_ansible_roles.rb +1 -1
  29. data/db/migrate/20160729094457_add_columns_to_ansible_role.rb +1 -1
  30. data/db/migrate/20160802153302_create_join_table_hostgroup_ansible_roles.rb +2 -1
  31. data/db/migrate/20160805094233_add_primary_key_hostgroup_ansible_roles.rb +1 -1
  32. data/db/migrate/20161122154057_automatically_set_role_timestamps.rb +1 -1
  33. data/db/seeds.d/75_job_templates.rb +20 -0
  34. data/lib/foreman_ansible/engine.rb +11 -53
  35. data/lib/foreman_ansible/register.rb +52 -0
  36. data/lib/foreman_ansible/remote_execution.rb +22 -0
  37. data/lib/foreman_ansible/version.rb +1 -1
  38. data/test/factories/ansible_proxy.rb +1 -1
  39. data/test/factories/ansible_roles.rb +1 -1
  40. data/test/functional/ansible_roles_controller_test.rb +4 -2
  41. data/test/functional/api/v2/ansible_roles_controller_test.rb +5 -3
  42. data/test/functional/api/v2/hostgroups_controller_test.rb +17 -25
  43. data/test/functional/api/v2/hosts_controller_test.rb +16 -24
  44. data/test/functional/hosts_controller_test.rb +33 -29
  45. data/test/test_plugin_helper.rb +12 -2
  46. data/test/unit/actions/run_ansible_job_test.rb +0 -0
  47. data/test/unit/actions/run_proxy_ansible_command_test.rb +0 -0
  48. data/test/unit/concerns/host_managed_extensions_test.rb +7 -7
  49. data/test/unit/concerns/hostgroup_extensions_test.rb +6 -6
  50. data/test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb +2 -2
  51. data/test/unit/host_ansible_role_test.rb +2 -2
  52. data/test/unit/hostgroup_ansible_role_test.rb +2 -2
  53. data/test/unit/lib/foreman_ansible_core/roles_reader_test.rb +4 -5
  54. data/test/unit/services/fact_importer_test.rb +3 -5
  55. data/test/unit/services/fact_parser_test.rb +0 -2
  56. data/test/unit/services/fact_sparser_test.rb +0 -2
  57. data/test/unit/services/inventory_creator_test.rb +1 -1
  58. data/test/unit/services/proxy_selector_test.rb +4 -4
  59. data/test/unit/services/roles_importer_test.rb +2 -2
  60. data/test/unit/services/structured_fact_importer_test.rb +1 -1
  61. data/test/unit/services/ui_roles_importer_test.rb +1 -1
  62. metadata +44 -31
  63. data/app/lib/actions/foreman_ansible/play_host_roles.rb +0 -42
  64. data/app/lib/actions/foreman_ansible/play_hostgroup_roles.rb +0 -56
  65. data/app/lib/actions/foreman_ansible/play_hosts_roles.rb +0 -26
  66. data/test/fixtures/ansible_permissions.yml +0 -11
  67. data/test/support/fixture_support.rb +0 -29
  68. data/test/support/foreman_tasks/task.rb +0 -48
  69. data/test/support/foreman_test_helper_additions.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cdb2243734dd64231cdbefae5b464c67f33c9607
4
- data.tar.gz: aa058575b4eb578fdb19be3da7c289f90e4d3b58
3
+ metadata.gz: 3b4137a958734d1507b19751c33bc1c5e91bc321
4
+ data.tar.gz: c2c57f2e7c31865609c7ba1a0e843edae1dc694e
5
5
  SHA512:
6
- metadata.gz: 5bb05ca2370bc1157b1e9ccb1be811847504d98dff0233d993f2ca3908c7d5e271d64e3f73669f77b64cd5b45f931ea6a9323e9ea815a91628a40195170e3d5d
7
- data.tar.gz: 5218a4406ea854950be3679140c8300d670e407a7d51d9302736844b7ecafbbe5897b94a31f2b7a8dcbf0844947446e5a7c226d93405dd0bd6b4e8c4dbe7d53e
6
+ metadata.gz: 96aadc541d8c7870a7ad14b8c5ea7a491ea793b4506aafbcf2d148d64c0fd8762d824499f05c484e8d727298e347735bff7a414a1d739713157345923b7f0728
7
+ data.tar.gz: 04a3d2a65993f39c4a0fedabd0cf08c9bc4fea720edebc7452085effb22d12d020619d318accee167f7e37ffb4ea7037dfd100d00bc5397ea6155b3634b6c005
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ end
17
17
  begin
18
18
  require 'rubocop/rake_task'
19
19
  RuboCop::RakeTask.new
20
- rescue => _
20
+ rescue StandardError => _
21
21
  puts 'Rubocop not loaded.'
22
22
  end
23
23
 
@@ -5,10 +5,10 @@ module ForemanAnsible
5
5
  module HostgroupsControllerExtensions
6
6
  extend ActiveSupport::Concern
7
7
  include ForemanTasks::Triggers
8
+ include ::ForemanAnsible::Concerns::JobInvocationHelper
8
9
 
9
10
  # Included blocks shouldn't be bound by length, as otherwise concerns
10
11
  # cannot extend the method properly.
11
- # rubocop:disable BlockLength
12
12
  included do
13
13
  api :POST, '/hostgroups/:id/play_roles',
14
14
  N_('Plays Ansible roles on a hostgroup')
@@ -16,14 +16,8 @@ module ForemanAnsible
16
16
 
17
17
  def play_roles
18
18
  find_resource
19
-
20
- @result = {
21
- :hostgroup => @hostgroup, :foreman_tasks => async_task(
22
- ::Actions::ForemanAnsible::PlayHostgroupRoles, @hostgroup
23
- )
24
- }
25
-
26
- render_message @result
19
+ composer = job_composer(:ansible_run_host, @hostgroup.hosts)
20
+ process_response composer.trigger!, composer.job_invocation
27
21
  end
28
22
 
29
23
  api :POST, '/hostgroups/play_roles',
@@ -32,18 +26,9 @@ module ForemanAnsible
32
26
 
33
27
  def multiple_play_roles
34
28
  find_multiple
35
-
36
- @result = []
37
-
38
- @hostgroups.uniq.each do |hostgroup|
39
- @result.append(
40
- :hostgroup => hostgroup, :foreman_tasks => async_task(
41
- ::Actions::ForemanAnsible::PlayHostgroupRoles, hostgroup
42
- )
43
- )
44
- end
45
-
46
- render_message @result
29
+ composer = job_composer(:ansible_run_host,
30
+ @hostgroups.map(&:hosts).flatten.uniq)
31
+ process_response composer.trigger!, composer.job_invocation
47
32
  end
48
33
  end
49
34
 
@@ -5,6 +5,7 @@ module ForemanAnsible
5
5
  module HostsControllerExtensions
6
6
  extend ActiveSupport::Concern
7
7
  include ForemanTasks::Triggers
8
+ include ::ForemanAnsible::Concerns::JobInvocationHelper
8
9
 
9
10
  included do
10
11
  api :POST, '/hosts/:id/play_roles',
@@ -12,30 +13,16 @@ module ForemanAnsible
12
13
  param :id, String, :required => true
13
14
 
14
15
  def play_roles
15
- @result = {
16
- :host => @host, :foreman_tasks => async_task(
17
- ::Actions::ForemanAnsible::PlayHostRoles, @host
18
- )
19
- }
20
-
21
- render_message @result
16
+ composer = job_composer(:ansible_run_host, @host)
17
+ process_response composer.trigger!, composer.job_invocation
22
18
  end
23
19
 
24
20
  api :POST, '/hosts/play_roles', N_('Plays Ansible roles on hosts')
25
21
  param :id, Array, :required => true
26
22
 
27
23
  def multiple_play_roles
28
- @result = []
29
-
30
- @host.each do |item|
31
- @result.append(
32
- :host => item, :foreman_tasks => async_task(
33
- ::Actions::ForemanAnsible::PlayHostRoles, item
34
- )
35
- )
36
- end
37
-
38
- render_message @result
24
+ composer = job_composer(:ansible_run_host, @host)
25
+ process_response composer.trigger!, composer.job_invocation
39
26
  end
40
27
  end
41
28
 
@@ -4,14 +4,14 @@ module ForemanAnsible
4
4
  module HostgroupsControllerExtensions
5
5
  extend ActiveSupport::Concern
6
6
  include ForemanTasks::Triggers
7
+ include ::ForemanAnsible::Concerns::JobInvocationHelper
7
8
 
8
9
  def play_roles
9
10
  find_resource
10
- task = async_task(
11
- ::Actions::ForemanAnsible::PlayHostgroupRoles,
12
- @hostgroup
13
- )
14
- redirect_to task
11
+ check_hostgroup
12
+ composer = job_composer(:ansible_run_host, @hostgroup.hosts)
13
+ composer.trigger
14
+ redirect_to job_invocation_path(composer.job_invocation)
15
15
  rescue Foreman::Exception => e
16
16
  error e.message
17
17
  redirect_to hostgroups_path
@@ -19,6 +19,13 @@ module ForemanAnsible
19
19
 
20
20
  private
21
21
 
22
+ def check_hostgroup
23
+ return unless @hostgroup.hosts.empty?
24
+ raise ::Foreman::Exception.new(
25
+ N_('Host group has no associated hosts')
26
+ )
27
+ end
28
+
22
29
  def action_permission
23
30
  case params[:action]
24
31
  when 'play_roles'
@@ -4,15 +4,29 @@ module ForemanAnsible
4
4
  module HostsControllerExtensions
5
5
  extend ActiveSupport::Concern
6
6
  include ForemanTasks::Triggers
7
+ include JobInvocationHelper
8
+
9
+ # Overrides to methods in the original hosts controller
10
+ module Overrides
11
+ def action_permission
12
+ case params[:action]
13
+ when 'multiple_play_roles', 'play_roles'
14
+ :view
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
7
20
 
8
21
  included do
9
- alias_method_chain :action_permission, :ansible
22
+ prepend Overrides
10
23
  end
11
24
 
12
25
  def play_roles
13
26
  find_resource
14
- task = async_task(::Actions::ForemanAnsible::PlayHostRoles, @host)
15
- redirect_to task
27
+ composer = job_composer(:ansible_run_host, @host)
28
+ composer.trigger
29
+ redirect_to job_invocation_path(composer.job_invocation)
16
30
  rescue Foreman::Exception => e
17
31
  error e.message
18
32
  redirect_to host_path(@host)
@@ -20,23 +34,13 @@ module ForemanAnsible
20
34
 
21
35
  def multiple_play_roles
22
36
  find_multiple
23
- task = async_task(::Actions::ForemanAnsible::PlayHostsRoles, @hosts)
24
- redirect_to task
37
+ composer = job_composer(:ansible_run_host, @hosts)
38
+ composer.trigger
39
+ redirect_to job_invocation_path(composer.job_invocation)
25
40
  rescue Foreman::Exception => e
26
41
  error e.message
27
42
  redirect_to hosts_path
28
43
  end
29
-
30
- private
31
-
32
- def action_permission_with_ansible
33
- case params[:action]
34
- when 'multiple_play_roles', 'play_roles'
35
- :view
36
- else
37
- action_permission_without_ansible
38
- end
39
- end
40
44
  end
41
45
  end
42
46
  end
@@ -0,0 +1,17 @@
1
+ module ForemanAnsible
2
+ module Concerns
3
+ # Helpers to compose the JobInvocation in other controllers
4
+ module JobInvocationHelper
5
+ extend ActiveSupport::Concern
6
+
7
+ def job_composer(feature_name, target)
8
+ composer = ::JobInvocationComposer.for_feature(feature_name, target)
9
+ return composer if composer.save
10
+ raise ::Foreman::Exception.new(
11
+ format(N_('Could not run Ansible roles for %{host}'),
12
+ :host => target)
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,12 +1,8 @@
1
- require "#{ForemanAnsible::Engine.root}/lib/foreman_ansible/version"
2
-
3
1
  module ForemanAnsible
4
2
  # General helper for foreman_ansible
5
3
  module AnsiblePluginHelper
6
4
  def ansible_doc_url
7
- major_version = ::ForemanAnsible::VERSION.split('.')[0]
8
- 'https://theforeman.org/plugins/foreman_ansible/'\
9
- "#{major_version}.x/index.html"
5
+ 'http://theforeman.org/plugins/foreman_ansible/1.x/index.html'
10
6
  end
11
7
  end
12
8
  end
@@ -22,7 +22,8 @@ module ForemanAnsible
22
22
 
23
23
  def ansible_report?(log)
24
24
  module_name(log).present?
25
- rescue # Failures when parsing the log indicates it's not an Ansible report
25
+ # Failures when parsing the log indicates it's not an Ansible report
26
+ rescue StandardError
26
27
  false
27
28
  end
28
29
  end
@@ -3,9 +3,26 @@ module ForemanAnsible
3
3
  module HostsHelperExtensions
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ module Overrides
7
+ def host_title_actions(*args)
8
+ host = args.first
9
+ if ansible_roles_present?(host)
10
+ button = ansible_roles_button(host)
11
+ title_actions(button_group(button))
12
+ end
13
+ super(*args)
14
+ end
15
+
16
+ def multiple_actions
17
+ super +
18
+ [[_('Play Ansible roles'),
19
+ multiple_play_roles_hosts_path,
20
+ false]]
21
+ end
22
+ end
23
+
6
24
  included do
7
- alias_method_chain(:host_title_actions, :run_ansible_roles)
8
- alias_method_chain(:multiple_actions, :run_ansible_roles)
25
+ prepend Overrides
9
26
  end
10
27
 
11
28
  def ansible_roles_present?(host)
@@ -22,21 +39,5 @@ module ForemanAnsible
22
39
  :'data-no-turbolink' => true
23
40
  )
24
41
  end
25
-
26
- def host_title_actions_with_run_ansible_roles(*args)
27
- host = args.first
28
- if ansible_roles_present?(host)
29
- button = ansible_roles_button(host)
30
- title_actions(button_group(button))
31
- end
32
- host_title_actions_without_run_ansible_roles(*args)
33
- end
34
-
35
- def multiple_actions_with_run_ansible_roles
36
- multiple_actions_without_run_ansible_roles +
37
- [[_('Play Ansible roles'),
38
- multiple_play_roles_hosts_path,
39
- false]]
40
- end
41
42
  end
42
43
  end
@@ -20,15 +20,11 @@ module Actions
20
20
  continuous_output.humanize
21
21
  end
22
22
 
23
- def continuous_output_providers
24
- super << self
25
- end
26
-
27
23
  def fill_continuous_output(continuous_output)
28
24
  delegated_output.fetch('result', []).each do |raw_output|
29
25
  continuous_output.add_raw_output(raw_output)
30
26
  end
31
- rescue => e
27
+ rescue StandardError => e
32
28
  continuous_output.add_exception(_('Error loading data from proxy'), e)
33
29
  end
34
30
 
@@ -12,4 +12,9 @@ class AnsibleRole < ApplicationRecord
12
12
 
13
13
  scoped_search :on => :name, :complete_value => true
14
14
  scoped_search :on => :updated_at
15
+
16
+ # Methods to be allowed in any template with safemode enabled
17
+ class Jail < Safemode::Jail
18
+ allow :name
19
+ end
15
20
  end
@@ -6,9 +6,7 @@ module ForemanAnsible
6
6
 
7
7
  included do
8
8
  def all_ansible_roles
9
- result = (ansible_roles + inherited_ansible_roles).uniq
10
- result += host_ansible_roles if is_a? Hostgroup
11
- result
9
+ (ansible_roles + inherited_ansible_roles).uniq
12
10
  end
13
11
  end
14
12
  end
@@ -33,3 +33,12 @@ module ForemanAnsible
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ module Host
38
+ class Managed
39
+ # Methods to be allowed in any template with safemode enabled
40
+ class Jail < Safemode::Jail
41
+ allow :all_ansible_roles, :ansible_roles, :inherited_ansible_roles
42
+ end
43
+ end
44
+ end
@@ -14,10 +14,6 @@ module ForemanAnsible
14
14
  roles + hostgroup.ansible_roles
15
15
  end.uniq
16
16
  end
17
-
18
- def host_ansible_roles
19
- hosts.all.includes(:ansible_roles).flat_map(&:ansible_roles)
20
- end
21
17
  end
22
18
  end
23
19
  end
@@ -0,0 +1,24 @@
1
+ if defined? ForemanRemoteExecution
2
+ module ForemanAnsible
3
+ # Provider for RemoteExecution that allows to run Ansible playbooks.
4
+ # Read the source of other RemoteExecution providers for more.
5
+ class AnsibleProvider < RemoteExecutionProvider
6
+ class << self
7
+ def humanized_name
8
+ 'Ansible'
9
+ end
10
+
11
+ def host_setting(host, setting)
12
+ host.params[setting.to_s] || Setting[setting]
13
+ end
14
+
15
+ def proxy_command_options(template_invocation, host)
16
+ super(template_invocation, host).merge(
17
+ 'ansible_inventory' =>
18
+ ::ForemanAnsible::InventoryCreator.new([host]).to_hash.to_json
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -10,7 +10,6 @@ class Setting
10
10
  # rubocop:disable BlockLength
11
11
  def load_defaults
12
12
  return unless super
13
- Setting::BLANK_ATTRS.push('ansible_ssh_private_key_file')
14
13
  transaction do
15
14
  [
16
15
  set(
@@ -86,6 +85,7 @@ class Setting
86
85
  '3' => N_('Level 3 (-vvv)'),
87
86
  '4' => N_('Level 4 (-vvvv)') }
88
87
  end
88
+ # rubocop:enable BlockLength
89
89
  ),
90
90
  set(
91
91
  'ansible_post_provision_timeout',
@@ -100,8 +100,11 @@ class Setting
100
100
  create(s.update(:category => 'Setting::Ansible'))
101
101
  end
102
102
  end
103
+ Setting::BLANK_ATTRS.push('ansible_ssh_private_key_file')
103
104
  true
104
105
  end
106
+ # rubocop:enable AbcSize
107
+ # rubocop:enable MethodLength
105
108
 
106
109
  def humanized_category
107
110
  N_('Ansible')
@@ -14,7 +14,8 @@ module ForemanAnsible
14
14
  Operatingsystem.create!(args.merge(:description => os_description))
15
15
  end
16
16
 
17
- def environment; end # Don't do anything as there's no env in Ansible
17
+ # Don't do anything as there's no env in Ansible
18
+ def environment; end
18
19
 
19
20
  def architecture
20
21
  name = facts[:ansible_architecture] || facts[:facter_architecture]
@@ -43,7 +44,7 @@ module ForemanAnsible
43
44
  #
44
45
  # This method overrides app/services/fact_parser.rb on Foreman and returns
45
46
  # an array of interface names, ['eth0', 'wlan1', etc...]
46
- def get_interfaces # rubocop:disable Style/AccessorMethodName
47
+ def get_interfaces # rubocop:disable Naming/AccessorMethodName
47
48
  pref = facts[:ansible_default_ipv4] &&
48
49
  facts[:ansible_default_ipv4]['interface']
49
50
  if pref.present?
@@ -103,6 +104,7 @@ module ForemanAnsible
103
104
  (facts[:version].split('R')[0] if os_name == 'junos')
104
105
  end
105
106
  end
107
+ # rubocop:enable AbcSize, CyclomaticComplexity, PerceivedComplexity
106
108
 
107
109
  def os_release
108
110
  facts[:ansible_distribution_version] ||