foreman_ansible 1.5.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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] ||