foreman_ansible 6.2.0 → 6.3.3

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/ansible_roles_controller.rb +12 -8
  3. data/app/controllers/ansible_variables_controller.rb +4 -0
  4. data/app/controllers/api/v2/ansible_roles_controller.rb +32 -11
  5. data/app/controllers/api/v2/ansible_variables_controller.rb +6 -4
  6. data/app/controllers/foreman_ansible/concerns/import_controller_helper.rb +3 -3
  7. data/app/helpers/foreman_ansible/ansible_reports_helper.rb +8 -0
  8. data/app/helpers/foreman_ansible/ansible_roles_data_preparations.rb +95 -0
  9. data/app/helpers/foreman_ansible/ansible_roles_helper.rb +20 -1
  10. data/app/jobs/sync_roles_and_variables.rb +20 -0
  11. data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +7 -4
  12. data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +8 -5
  13. data/app/models/foreman_ansible/ansible_provider.rb +3 -1
  14. data/app/models/host_ansible_role.rb +1 -0
  15. data/app/models/hostgroup_ansible_role.rb +1 -0
  16. data/app/models/setting/ansible.rb +9 -0
  17. data/app/services/foreman_ansible/ansible_report_importer.rb +4 -0
  18. data/app/services/foreman_ansible/ansible_report_scanner.rb +15 -1
  19. data/app/services/foreman_ansible/api_roles_importer.rb +23 -11
  20. data/app/services/foreman_ansible/fact_parser.rb +21 -1
  21. data/app/services/foreman_ansible/import_roles_and_variables_error_notification.rb +31 -0
  22. data/app/services/foreman_ansible/import_roles_and_variables_success_notification.rb +26 -0
  23. data/app/services/foreman_ansible/inventory_creator.rb +3 -7
  24. data/app/services/foreman_ansible/roles_importer.rb +3 -2
  25. data/app/services/foreman_ansible/ui_roles_importer.rb +2 -2
  26. data/app/services/foreman_ansible/variables_importer.rb +32 -2
  27. data/app/views/ansible_roles/import.html.erb +10 -50
  28. data/app/views/ansible_variables/index.html.erb +1 -2
  29. data/app/views/api/v2/ansible_roles/sync.json.rabl +5 -0
  30. data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +1 -2
  31. data/app/views/foreman_ansible/config_reports/_ansible.html.erb +13 -6
  32. data/app/views/foreman_ansible/job_templates/ansible_collections_-_install_from_galaxy.erb +28 -0
  33. data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +44 -0
  34. data/config/routes.rb +5 -4
  35. data/db/migrate/20210120150019_add_position_to_ansible_role.rb +27 -0
  36. data/db/seeds.d/100_common_parameters.rb +7 -0
  37. data/db/seeds.d/90_notification_blueprints.rb +19 -1
  38. data/lib/foreman_ansible/engine.rb +1 -0
  39. data/lib/foreman_ansible/register.rb +8 -7
  40. data/lib/foreman_ansible/version.rb +1 -1
  41. data/locale/ca/LC_MESSAGES/foreman_ansible.mo +0 -0
  42. data/locale/ca/foreman_ansible.po +1 -1
  43. data/locale/cs_CZ/LC_MESSAGES/foreman_ansible.mo +0 -0
  44. data/locale/cs_CZ/foreman_ansible.po +1 -1
  45. data/locale/de/LC_MESSAGES/foreman_ansible.mo +0 -0
  46. data/locale/de/foreman_ansible.po +1 -1
  47. data/locale/en/LC_MESSAGES/foreman_ansible.mo +0 -0
  48. data/locale/en/foreman_ansible.po +1 -1
  49. data/locale/en_GB/LC_MESSAGES/foreman_ansible.mo +0 -0
  50. data/locale/en_GB/foreman_ansible.po +1 -1
  51. data/locale/es/LC_MESSAGES/foreman_ansible.mo +0 -0
  52. data/locale/es/foreman_ansible.po +1 -1
  53. data/locale/fr/LC_MESSAGES/foreman_ansible.mo +0 -0
  54. data/locale/fr/foreman_ansible.po +1 -1
  55. data/locale/gl/LC_MESSAGES/foreman_ansible.mo +0 -0
  56. data/locale/gl/foreman_ansible.po +1 -1
  57. data/locale/it/LC_MESSAGES/foreman_ansible.mo +0 -0
  58. data/locale/it/foreman_ansible.po +1 -1
  59. data/locale/ja/LC_MESSAGES/foreman_ansible.mo +0 -0
  60. data/locale/ja/foreman_ansible.po +1 -1
  61. data/locale/ko/LC_MESSAGES/foreman_ansible.mo +0 -0
  62. data/locale/ko/foreman_ansible.po +1 -1
  63. data/locale/nl_NL/LC_MESSAGES/foreman_ansible.mo +0 -0
  64. data/locale/nl_NL/foreman_ansible.po +1 -1
  65. data/locale/pl/LC_MESSAGES/foreman_ansible.mo +0 -0
  66. data/locale/pl/foreman_ansible.po +1 -1
  67. data/locale/pt_BR/LC_MESSAGES/foreman_ansible.mo +0 -0
  68. data/locale/pt_BR/foreman_ansible.po +1 -1
  69. data/locale/ru/LC_MESSAGES/foreman_ansible.mo +0 -0
  70. data/locale/ru/foreman_ansible.po +1 -1
  71. data/locale/sv_SE/LC_MESSAGES/foreman_ansible.mo +0 -0
  72. data/locale/sv_SE/foreman_ansible.po +1 -1
  73. data/locale/zh_CN/LC_MESSAGES/foreman_ansible.mo +0 -0
  74. data/locale/zh_CN/foreman_ansible.po +1 -1
  75. data/locale/zh_TW/LC_MESSAGES/foreman_ansible.mo +0 -0
  76. data/locale/zh_TW/foreman_ansible.po +1 -1
  77. data/test/factories/ansible_roles.rb +12 -0
  78. data/test/factories/host_ansible_enhancements.rb +23 -0
  79. data/test/foreman_ansible/helpers/ansible_roles_helper_test.rb +45 -0
  80. data/test/functional/ansible_variables_controller_test.rb +0 -15
  81. data/test/functional/api/v2/ansible_roles_controller_test.rb +23 -0
  82. data/test/functional/api/v2/hostgroups_controller_test.rb +5 -4
  83. data/test/functional/api/v2/hosts_controller_test.rb +9 -8
  84. data/test/functional/hosts_controller_test.rb +10 -6
  85. data/test/unit/concerns/host_managed_extensions_test.rb +17 -3
  86. data/test/unit/concerns/hostgroup_extensions_test.rb +13 -7
  87. data/test/unit/host_ansible_role_test.rb +2 -1
  88. data/test/unit/hostgroup_ansible_role_test.rb +15 -1
  89. data/test/unit/ignore_roles_test.rb +43 -0
  90. data/test/unit/import_roles_and_variables.rb +60 -0
  91. data/test/unit/services/api_roles_importer_test.rb +22 -5
  92. data/test/unit/services/fact_parser_test.rb +16 -0
  93. data/test/unit/services/inventory_creator_test.rb +15 -7
  94. data/test/unit/services/ui_roles_importer_test.rb +2 -2
  95. data/webpack/__mocks__/foremanReact/common/helpers.js +13 -0
  96. data/webpack/__mocks__/foremanReact/components/common/forms/OrderableSelect/helpers.js +5 -0
  97. data/webpack/__mocks__/foremanReact/redux/API.js +7 -0
  98. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js +178 -0
  99. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.scss +9 -0
  100. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js +39 -0
  101. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesConstants.js +4 -0
  102. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesHelpers.js +11 -0
  103. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesHelpers.test.js +50 -0
  104. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +39 -0
  105. data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +177 -0
  106. data/webpack/components/AnsibleRolesAndVariables/index.js +31 -0
  107. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +14 -18
  108. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +1 -1
  109. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +6 -0
  110. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +1 -2
  111. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +13 -8
  112. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +8 -28
  113. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +1 -0
  114. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +2 -0
  115. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +0 -8
  116. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +2 -15
  117. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +4 -9
  118. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +8 -97
  119. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +5 -30
  120. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +5 -2
  121. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.js +43 -0
  122. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.test.js +19 -0
  123. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +63 -51
  124. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +3 -0
  125. data/webpack/components/AnsibleRolesSwitcher/components/OrderedRolesTooltip.js +23 -0
  126. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRoleInputs.test.js.snap +51 -0
  127. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +28 -28
  128. data/webpack/components/AnsibleRolesSwitcher/index.js +3 -7
  129. data/webpack/index.js +6 -0
  130. metadata +62 -16
  131. data/app/views/ansible_variables/import.html.erb +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d95899e15050cbf3f25d75a8f3c9bc5a3059a9dd0ffa90f4690ce84cf49d3408
4
- data.tar.gz: 466754ac90d1e80046fca70ca8db372e90d2b61a0d26a726f0807f7e81227728
3
+ metadata.gz: 4a67f34724383faf6ead25e0d28e47d86b30d817839e3d9e3e6ef0531f9a4c5a
4
+ data.tar.gz: e758ebdaa34fe47e84aac20c5cd12af9013cad2d17810b73f894a7b6177e570b
5
5
  SHA512:
6
- metadata.gz: 9f79b560e9e01e8719c6e705ff5fef6a9f9e7b91bc9ec1b9b79c81750b572c4de6929d2ab07049caefdf4f555a5087c31eb76543d52b87622038107a1e02ea63
7
- data.tar.gz: 357b61ffdb94b61a37ecf87afba07f7e0c2158d4af14d39b701fb31152803692a8feaac09294bb2bc8c0ae8fe8d9daa66eb8eb6f0869c4901315dca688f06dab
6
+ metadata.gz: 0a3f9e4fe92c5325908b61e9542e4a99c4256f1c9b0b66f58873e73c8fa3b90194d39a054c2857060edc37ebd214b2186d8dced6078950f936ec8e9ae4b5fde4
7
+ data.tar.gz: 82aab4e76eedc22109debf0c1a60bc316c512677749dff6b1a53a4357c66d16dee37260fdc53ce643b362fcbc253a5ad6b3c8ff9636c736faee22ad229f821b7
@@ -4,7 +4,7 @@
4
4
  class AnsibleRolesController < ::ApplicationController
5
5
  include Foreman::Controller::AutoCompleteSearch
6
6
  include ForemanAnsible::Concerns::ImportControllerHelper
7
-
7
+ include ::ForemanAnsible::AnsibleRolesDataPreparations
8
8
  def index
9
9
  @ansible_roles = resource_base.search_for(params[:search],
10
10
  :order => params[:order]).
@@ -22,18 +22,21 @@ class AnsibleRolesController < ::ApplicationController
22
22
 
23
23
  def import
24
24
  changed = @importer.import!
25
- if changed.values.all?(&:empty?)
25
+ @rows = prepare_ansible_import_rows(changed, @variables_importer)
26
+ if @rows.empty?
26
27
  success no_changed_roles_message
27
28
  redirect_to ansible_roles_path
28
29
  else
29
- render :locals => { :changed => changed }
30
+ render
30
31
  end
31
32
  end
32
33
 
33
34
  def confirm_import
34
- @importer.finish_import(params[:changed]&.to_unsafe_h)
35
- success _('Import of roles successfully finished.')
36
- redirect_to ansible_roles_path
35
+ job = SyncRolesAndVariables.perform_later(params['changed'].to_unsafe_h, @proxy)
36
+ task = ForemanTasks::Task.find_by(external_id: job.provider_job_id)
37
+ render json: {
38
+ task: task
39
+ }, status: :ok
37
40
  end
38
41
 
39
42
  private
@@ -44,10 +47,11 @@ class AnsibleRolesController < ::ApplicationController
44
47
 
45
48
  def create_importer
46
49
  @importer = ForemanAnsible::UiRolesImporter.new(@proxy)
50
+ @variables_importer = ForemanAnsible::VariablesImporter.new(@proxy)
47
51
  end
48
52
 
49
53
  def no_changed_roles_message
50
- return _('No changes in roles detected.') if @proxy.blank?
51
- _('No changes in roles detected on %s.') % @proxy.name
54
+ return _('No added or removed roles nor variables.') if @proxy.blank?
55
+ _('No added or removed roles nor variables detected on %s.') % @proxy.name
52
56
  end
53
57
  end
@@ -104,4 +104,8 @@ class AnsibleVariablesController < ::LookupKeysController
104
104
  end
105
105
  @smart_proxy
106
106
  end
107
+
108
+ def controller_permission
109
+ 'ansible_variables'
110
+ end
107
111
  end
@@ -5,6 +5,7 @@ module Api
5
5
  # API controller for Ansible Roles
6
6
  class AnsibleRolesController < ::Api::V2::BaseController
7
7
  include ::Api::Version2
8
+ include ::ForemanAnsible::AnsibleRolesDataPreparations
8
9
 
9
10
  resource_description do
10
11
  api_version 'v2'
@@ -12,8 +13,8 @@ module Api
12
13
  end
13
14
 
14
15
  before_action :find_resource, :only => [:show, :destroy]
15
- before_action :find_proxy, :only => [:import, :obsolete, :fetch]
16
- before_action :create_importer, :only => [:import, :obsolete, :fetch]
16
+ before_action :find_proxy, :only => [:import, :obsolete, :fetch, :sync]
17
+ before_action :create_importer, :only => [:import, :obsolete, :fetch, :sync]
17
18
 
18
19
  api :GET, '/ansible_roles/:id', N_('Show role')
19
20
  param :id, :identifier, :required => true
@@ -32,28 +33,46 @@ module Api
32
33
  process_response @ansible_role.destroy
33
34
  end
34
35
 
35
- api :PUT, '/ansible_roles/import', N_('Import Ansible roles')
36
+ api :PUT, '/ansible_roles/import', N_('DEPRECATED: Import Ansible roles'), deprecated: true
36
37
  param :proxy_id, :identifier, :required => true, :desc => N_('Smart Proxy to import from')
37
- param :role_names, Array, N_('Ansible role names to import')
38
+ param :role_names, Array, N_('Ansible role names to be imported')
38
39
  def import
39
- @imported = @importer.import!(role_names)
40
+ Foreman::Deprecation.api_deprecation_warning(_('Use sync instead, to sync roles from Smart Proxy with Ansible feature enabled'))
41
+ new_roles = @roles_importer.import_role_names['new']
42
+ if role_names.present?
43
+ new_roles.select! do |role|
44
+ role_names.include?(role.name)
45
+ end
46
+ end
47
+ new_roles.map(&:save)
48
+ @imported = new_roles
49
+ end
50
+
51
+ api :PUT, '/ansible_roles/sync', N_('Sync Ansible roles')
52
+ param :proxy_id, :identifier, :required => true, :desc => N_('Smart Proxy to sync from')
53
+ param :role_names, Array, N_('Ansible role names to be synced')
54
+ def sync
55
+ params = @importer.import!(role_names)
56
+ if params['changed'].present?
57
+ @task = @importer.confirm_sync(params)
58
+ else
59
+ render_message _('No changes detected in specified Ansible Roles and their variables')
60
+ end
40
61
  end
41
62
 
42
- api :PUT, '/ansible_roles/obsolete', N_('Obsolete Ansible roles')
63
+ api :PUT, '/ansible_roles/obsolete', N_('DEPRECATED: Obsolete Ansible roles'), deprecated: true
43
64
  param :proxy_id, :identifier, N_('Smart Proxy to import from')
44
65
  def obsolete
66
+ Foreman::Deprecation.api_deprecation_warning(_('Use sync instead, to sync roles from Smart Proxy with Ansible feature enabled'))
45
67
  @obsoleted = @importer.obsolete!
46
68
  end
47
69
 
48
70
  api :GET, '/ansible_roles/fetch',
49
- N_('Fetch Ansible roles available to be imported')
71
+ N_('Fetch Ansible roles available to be synced')
50
72
  param :proxy_id, :identifier, N_('Smart Proxy to fetch from'),
51
73
  :required => true
52
74
  def fetch
53
- fetched = []
54
- @importer.fetch!.each do |role_name|
55
- fetched << { :name => role_name }
56
- end
75
+ fetched = prepare_ansible_import_rows(@roles_importer.import!, @variables_importer, false)
57
76
  respond_to do |format|
58
77
  format.json do
59
78
  render :json => { :results => { :ansible_roles => fetched } }
@@ -79,6 +98,8 @@ module Api
79
98
  # rubocop:enable Layout/DotPosition
80
99
 
81
100
  def create_importer
101
+ @roles_importer = ForemanAnsible::UiRolesImporter.new(@proxy)
102
+ @variables_importer = ForemanAnsible::VariablesImporter.new(@proxy)
82
103
  @importer = ForemanAnsible::ApiRolesImporter.new(@proxy)
83
104
  end
84
105
  end
@@ -69,20 +69,22 @@ module Api
69
69
  end
70
70
 
71
71
  api :PUT, '/ansible_variables/import',
72
- N_('Import Ansible variables. This will only import variables '\
73
- 'for already existing roles, it will not import any new roles')
72
+ N_('DEPRECATED: Import Ansible variables. This will only import variables '\
73
+ 'for already existing roles, it will not import any new roles'), deprecated: true
74
74
  param :proxy_id, :identifier, N_('Smart Proxy to import from'), :required => true
75
75
  def import
76
+ Foreman::Deprecation.api_deprecation_warning(_('Use sync instead, to sync roles from Smart Proxy with Ansible feature enabled'))
76
77
  new_variables = @importer.import_variable_names([])[:new]
77
78
  new_variables.map(&:save)
78
79
  @imported = new_variables
79
80
  end
80
81
 
81
82
  api :PUT, '/ansible_variables/obsolete',
82
- N_('Obsolete Ansible variables. This will only obsolete variables '\
83
- 'for already existing roles, it will not delete any old roles')
83
+ N_('DEPRECATED: Obsolete Ansible variables. This will only obsolete variables '\
84
+ 'for already existing roles, it will not delete any old roles'), deprecated: true
84
85
  param :proxy_id, :identifier, N_('Smart Proxy to import from'), :required => true
85
86
  def obsolete
87
+ Foreman::Deprecation.api_deprecation_warning(_('Use sync instead, to sync roles from Smart Proxy with Ansible feature enabled'))
86
88
  old_variables = @importer.import_variable_names([])[:obsolete]
87
89
  old_variables.map(&:destroy)
88
90
  @obsoleted = old_variables
@@ -9,15 +9,15 @@ module ForemanAnsible
9
9
  included do
10
10
  # rubocop:disable Rails/LexicallyScopedActionFilter
11
11
  before_action :find_resource, :only => [:destroy]
12
- before_action :find_proxy, :only => [:import]
13
- before_action :create_importer, :only => [:import, :confirm_import]
12
+ before_action :find_proxy, :only => [:import, :import_variables, :confirm_import]
13
+ before_action :create_importer, :only => [:import, :confirm_import, :import_variables, :confirm_import]
14
14
  before_action :default_order, :only => [:index]
15
15
  # rubocop:enable Rails/LexicallyScopedActionFilter
16
16
  end
17
17
 
18
18
  def find_proxy
19
19
  return nil unless params[:proxy]
20
- @proxy = SmartProxy.authorized(:view_smart_proxies).find(params[:proxy])
20
+ @proxy = SmartProxy.find(params[:proxy])
21
21
  end
22
22
  end
23
23
  end
@@ -19,6 +19,14 @@ module ForemanAnsible
19
19
  name
20
20
  end
21
21
 
22
+ def ansible_run_in_check_mode?(log)
23
+ log.message&.value == 'check_mode_enabled' if check_mode_log?(log)
24
+ end
25
+
26
+ def check_mode_log?(log)
27
+ log.source&.value == 'check_mode'
28
+ end
29
+
22
30
  def ansible_module_args(log)
23
31
  report_json_viewer module_invocations parsed_message_json(log)
24
32
  end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAnsible
4
+ module AnsibleRolesDataPreparations
5
+ VARIABLE_ACTION_NAMES = { 'new' => _('Add'), 'obsolete' => _('Remove'), 'update' => _('Update') }.freeze
6
+ ROLE_ACTION_NAMES = { 'new' => _('Import Role'), 'obsolete' => _('Remove Role'), 'old' => _('Update Role Variables') }.freeze
7
+
8
+ def variable_action_name(kind)
9
+ VARIABLE_ACTION_NAMES[kind]
10
+ end
11
+
12
+ def role_action_name(kind)
13
+ ROLE_ACTION_NAMES[kind]
14
+ end
15
+
16
+ def get_old_roles_variables(imported_variables, role)
17
+ variables = { 'new' => [], 'obsolete' => [], 'update' => [] }
18
+ imported_variables.each do |kind, temp_variables|
19
+ temp_variables.each do |temp_variable|
20
+ variables[kind].append(temp_variable.key) if temp_variable.ansible_role_id == role.id
21
+ end
22
+ end
23
+ variables
24
+ end
25
+
26
+ def variables_to_s(variables)
27
+ str = ''
28
+ variables.each do |action, temp_variables|
29
+ str += "#{variable_action_name action}: #{temp_variables.size}, " unless temp_variables.empty?
30
+ end
31
+ str[0..-3]
32
+ end
33
+
34
+ def get_roles_variables(imported_variables, variables_importer, kind, role)
35
+ if kind == 'new'
36
+ variables = { 'new' => variables_importer.get_variables_names(role.name) }
37
+ elsif kind == 'obsolete'
38
+ variables = { 'obsolete' => role.ansible_variables.map(&:key) }
39
+ elsif kind == 'old'
40
+ variables = get_old_roles_variables(imported_variables, role)
41
+ end
42
+ variables_to_s(variables)
43
+ end
44
+
45
+ def excluded_roles
46
+ Setting.convert_array_to_regexp(Setting[:ansible_roles_to_ignore])
47
+ end
48
+
49
+ def role_match_excluded_roles(role_name)
50
+ match = role_name.match(excluded_roles)
51
+ match.to_s.empty? ? nil : match
52
+ end
53
+
54
+ def prepare_api_row(role, kind, variables)
55
+ {
56
+ name: role.name,
57
+ id: role.id,
58
+ role_action: role_action_name(kind),
59
+ variables: variables,
60
+ hosts_count: kind == 'obsolete' ? role.hosts.count : '',
61
+ hostgroup_count: kind == 'obsolete' ? role.hostgroups.count : '',
62
+ kind: kind
63
+ }
64
+ end
65
+
66
+ def prepare_ui_row(role, kind, variables)
67
+ { cells: [
68
+ role.name,
69
+ role_action_name(kind),
70
+ variables,
71
+ kind == 'obsolete' ? role.hosts.count : '',
72
+ kind == 'obsolete' ? role.hostgroups.count : ''
73
+ ],
74
+ role: role, kind: kind, id: role.name }
75
+ end
76
+
77
+ def prepare_ansible_import_rows(changed, variables_importer, is_ui = true)
78
+ rows = []
79
+ changed.each do |kind, roles|
80
+ imported_variables = variables_importer.import_variable_names(roles)
81
+ roles.each do |role|
82
+ next if role_match_excluded_roles(role.name)
83
+ variables = get_roles_variables(imported_variables, variables_importer, kind, role)
84
+ next if variables.empty? && kind['old']
85
+ if is_ui
86
+ rows.append(prepare_ui_row(role, kind, variables))
87
+ else
88
+ rows.append(prepare_api_row(role, kind, variables))
89
+ end
90
+ end
91
+ end
92
+ rows
93
+ end
94
+ end
95
+ end
@@ -35,8 +35,27 @@ module ForemanAnsible
35
35
  _('%s ago') % time_ago_in_words(role.updated_at)
36
36
  end
37
37
 
38
+ def role_attributes_for_roles_switcher(form_object)
39
+ inherited_role_ids = form_object.inherited_ansible_roles.map(&:id)
40
+ if form_object.is_a?(Hostgroup)
41
+ assoc_roles = form_object.hostgroup_ansible_roles
42
+ assoc_key = :hostgroup_ansible_role_id
43
+ else
44
+ assoc_roles = form_object.host_ansible_roles
45
+ assoc_key = :host_ansible_role_id
46
+ end
47
+ own_roles_attrs = model_roles_attrs(assoc_roles.reject { |ar| inherited_role_ids.include?(ar.ansible_role_id) }, assoc_key)
48
+ roles_attrs(form_object.inherited_ansible_roles) + own_roles_attrs
49
+ end
50
+
38
51
  def roles_attrs(roles)
39
- roles.map { |item| { :id => item.id, :name => item.name } }
52
+ roles.map { |item| { id: item.id, name: item.name } }
53
+ end
54
+
55
+ private
56
+
57
+ def model_roles_attrs(associated_roles, assoc_key)
58
+ associated_roles.map { |item| { id: item.ansible_role_id, name: item.ansible_role.name, position: item.position }.merge(assoc_key => item.id) }
40
59
  end
41
60
  end
42
61
  end
@@ -0,0 +1,20 @@
1
+ class SyncRolesAndVariables < ::ApplicationJob
2
+ queue_as :default
3
+
4
+ def perform(changed, proxy)
5
+ roles_importer = ForemanAnsible::UiRolesImporter.new(proxy)
6
+ variables_importer = ForemanAnsible::VariablesImporter.new(proxy)
7
+ roles_importer.finish_import(changed)
8
+ variables_importer.import_variables_roles(changed) if changed['new'] || changed['old']
9
+ task = ForemanTasks::Task.where(:external_id => @provider_job_id)[0]
10
+ ForemanAnsible::ImportRolesAndVariablesSuccessNotification.deliver!(task)
11
+ rescue StandardError => e
12
+ task = ForemanTasks::Task.where(:external_id => @provider_job_id)[0]
13
+ notification = ForemanAnsible::ImportRolesAndVariablesErrorNotification.new(e, task)
14
+ notification.deliver!
15
+ end
16
+
17
+ def humanized_name
18
+ _('Import roles And Variables')
19
+ end
20
+ end
@@ -8,9 +8,12 @@ module ForemanAnsible
8
8
  base.instance_eval do
9
9
  include ::ForemanAnsible::Concerns::JobInvocationHelper
10
10
 
11
- has_many :host_ansible_roles, :foreign_key => :host_id
12
- has_many :ansible_roles, :through => :host_ansible_roles,
13
- :dependent => :destroy
11
+ has_many :host_ansible_roles, -> { order('host_ansible_roles.position ASC') }, :foreign_key => :host_id
12
+ accepts_nested_attributes_for :host_ansible_roles, :allow_destroy => true
13
+ has_many :ansible_roles,
14
+ -> { order('host_ansible_roles.position ASC') },
15
+ :through => :host_ansible_roles,
16
+ :dependent => :destroy
14
17
  scoped_search :relation => :ansible_roles, :on => :name,
15
18
  :complete_value => true, :rename => :ansible_role,
16
19
  :only_explicit => true
@@ -47,7 +50,7 @@ module ForemanAnsible
47
50
  end
48
51
 
49
52
  def all_ansible_roles
50
- (ansible_roles + inherited_ansible_roles).uniq
53
+ (inherited_ansible_roles + ansible_roles).uniq
51
54
  end
52
55
 
53
56
  # Class methods we may need to override or add
@@ -6,9 +6,12 @@ module ForemanAnsible
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- has_many :hostgroup_ansible_roles, :foreign_key => :hostgroup_id
10
- has_many :ansible_roles, :through => :hostgroup_ansible_roles,
11
- :dependent => :destroy
9
+ has_many :hostgroup_ansible_roles, -> { order('hostgroup_ansible_roles.position ASC') }, :foreign_key => :hostgroup_id
10
+ has_many :ansible_roles,
11
+ -> { order('hostgroup_ansible_roles.position ASC') },
12
+ :through => :hostgroup_ansible_roles,
13
+ :dependent => :destroy
14
+ accepts_nested_attributes_for :hostgroup_ansible_roles, :allow_destroy => true
12
15
  audit_associations :ansible_roles
13
16
 
14
17
  def inherited_ansible_roles
@@ -24,14 +27,14 @@ module ForemanAnsible
24
27
  end
25
28
 
26
29
  def host_ansible_roles
27
- hosts.all.includes(:ansible_roles).flat_map(&:ansible_roles)
30
+ hosts.includes(:host_ansible_roles).flat_map(&:ansible_roles)
28
31
  end
29
32
 
30
33
  # includes also roles of all assigned hosts, useful to determine if
31
34
  # at least one host in this hostgroup has some ansible role assigned
32
35
  # either directly or through hostgroup
33
36
  def all_ansible_roles
34
- (ansible_roles + inherited_ansible_roles + host_ansible_roles).uniq
37
+ (inherited_ansible_roles + ansible_roles + host_ansible_roles).uniq
35
38
  end
36
39
  end
37
40
  end
@@ -27,12 +27,14 @@ if defined? ForemanRemoteExecution
27
27
  :remote_execution_command => ansible_command?(
28
28
  template_invocation.template
29
29
  ),
30
- :name => host.name
30
+ :name => host.name,
31
+ :check_mode => host.host_param('ansible_roles_check_mode')
31
32
  )
32
33
  end
33
34
 
34
35
  def secrets(host)
35
36
  {
37
+ :key_passphrase => Setting[:remote_execution_ssh_key_passphrase],
36
38
  'per-host' => {
37
39
  host.name => {
38
40
  'ansible_password' => rex_ssh_password(host),
@@ -4,6 +4,7 @@
4
4
  class HostAnsibleRole < ApplicationRecord
5
5
  belongs_to_host
6
6
  belongs_to :ansible_role
7
+ acts_as_list scope: :host
7
8
 
8
9
  validates :ansible_role_id, :presence => true,
9
10
  :uniqueness => { :scope => :host_id }