foreman_ansible 6.1.1 → 6.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) 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 +9 -4
  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 +2 -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/operating_system_parser.rb +1 -1
  25. data/app/services/foreman_ansible/roles_importer.rb +3 -2
  26. data/app/services/foreman_ansible/ui_roles_importer.rb +2 -2
  27. data/app/services/foreman_ansible/variables_importer.rb +36 -1
  28. data/app/views/ansible_roles/import.html.erb +10 -50
  29. data/app/views/ansible_variables/index.html.erb +1 -2
  30. data/app/views/api/v2/ansible_roles/sync.json.rabl +5 -0
  31. data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +8 -17
  32. data/app/views/foreman_ansible/config_reports/_ansible.html.erb +13 -6
  33. data/app/views/foreman_ansible/job_templates/ansible_collections_-_install_from_galaxy.erb +28 -0
  34. data/app/views/foreman_ansible/job_templates/ansible_roles_-_install_from_galaxy.erb +1 -1
  35. data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +44 -0
  36. data/config/routes.rb +5 -4
  37. data/db/migrate/20210120150019_add_position_to_ansible_role.rb +27 -0
  38. data/db/seeds.d/100_common_parameters.rb +7 -0
  39. data/db/seeds.d/90_notification_blueprints.rb +19 -1
  40. data/lib/foreman_ansible/engine.rb +1 -0
  41. data/lib/foreman_ansible/register.rb +8 -7
  42. data/lib/foreman_ansible/version.rb +1 -1
  43. data/locale/ca/LC_MESSAGES/foreman_ansible.mo +0 -0
  44. data/locale/ca/foreman_ansible.po +1 -1
  45. data/locale/cs_CZ/LC_MESSAGES/foreman_ansible.mo +0 -0
  46. data/locale/cs_CZ/foreman_ansible.po +1 -1
  47. data/locale/de/LC_MESSAGES/foreman_ansible.mo +0 -0
  48. data/locale/de/foreman_ansible.po +1 -1
  49. data/locale/en/LC_MESSAGES/foreman_ansible.mo +0 -0
  50. data/locale/en/foreman_ansible.po +1 -1
  51. data/locale/en_GB/LC_MESSAGES/foreman_ansible.mo +0 -0
  52. data/locale/en_GB/foreman_ansible.po +1 -1
  53. data/locale/es/LC_MESSAGES/foreman_ansible.mo +0 -0
  54. data/locale/es/foreman_ansible.po +1 -1
  55. data/locale/fr/LC_MESSAGES/foreman_ansible.mo +0 -0
  56. data/locale/fr/foreman_ansible.po +1 -1
  57. data/locale/gl/LC_MESSAGES/foreman_ansible.mo +0 -0
  58. data/locale/gl/foreman_ansible.po +1 -1
  59. data/locale/it/LC_MESSAGES/foreman_ansible.mo +0 -0
  60. data/locale/it/foreman_ansible.po +1 -1
  61. data/locale/ja/LC_MESSAGES/foreman_ansible.mo +0 -0
  62. data/locale/ja/foreman_ansible.po +1 -1
  63. data/locale/ko/LC_MESSAGES/foreman_ansible.mo +0 -0
  64. data/locale/ko/foreman_ansible.po +1 -1
  65. data/locale/nl_NL/LC_MESSAGES/foreman_ansible.mo +0 -0
  66. data/locale/nl_NL/foreman_ansible.po +1 -1
  67. data/locale/pl/LC_MESSAGES/foreman_ansible.mo +0 -0
  68. data/locale/pl/foreman_ansible.po +1 -1
  69. data/locale/pt_BR/LC_MESSAGES/foreman_ansible.mo +0 -0
  70. data/locale/pt_BR/foreman_ansible.po +1 -1
  71. data/locale/ru/LC_MESSAGES/foreman_ansible.mo +0 -0
  72. data/locale/ru/foreman_ansible.po +1 -1
  73. data/locale/sv_SE/LC_MESSAGES/foreman_ansible.mo +0 -0
  74. data/locale/sv_SE/foreman_ansible.po +1 -1
  75. data/locale/zh_CN/LC_MESSAGES/foreman_ansible.mo +0 -0
  76. data/locale/zh_CN/foreman_ansible.po +1 -1
  77. data/locale/zh_TW/LC_MESSAGES/foreman_ansible.mo +0 -0
  78. data/locale/zh_TW/foreman_ansible.po +1 -1
  79. data/package.json +11 -42
  80. data/test/factories/ansible_roles.rb +12 -0
  81. data/test/factories/host_ansible_enhancements.rb +23 -0
  82. data/test/foreman_ansible/helpers/ansible_roles_helper_test.rb +45 -0
  83. data/test/functional/ansible_variables_controller_test.rb +0 -15
  84. data/test/functional/api/v2/ansible_roles_controller_test.rb +23 -0
  85. data/test/functional/api/v2/hostgroups_controller_test.rb +5 -4
  86. data/test/functional/api/v2/hosts_controller_test.rb +9 -8
  87. data/test/functional/hosts_controller_test.rb +10 -6
  88. data/test/unit/concerns/host_managed_extensions_test.rb +17 -3
  89. data/test/unit/concerns/hostgroup_extensions_test.rb +13 -7
  90. data/test/unit/host_ansible_role_test.rb +2 -1
  91. data/test/unit/hostgroup_ansible_role_test.rb +15 -1
  92. data/test/unit/ignore_roles_test.rb +43 -0
  93. data/test/unit/import_roles_and_variables.rb +60 -0
  94. data/test/unit/services/ansible_variables_importer_test.rb +13 -0
  95. data/test/unit/services/api_roles_importer_test.rb +22 -5
  96. data/test/unit/services/fact_parser_test.rb +16 -0
  97. data/test/unit/services/inventory_creator_test.rb +15 -7
  98. data/test/unit/services/ui_roles_importer_test.rb +2 -2
  99. data/webpack/__mocks__/foremanReact/common/helpers.js +13 -0
  100. data/webpack/__mocks__/foremanReact/components/common/forms/OrderableSelect/helpers.js +5 -0
  101. data/webpack/__mocks__/foremanReact/redux/API.js +7 -0
  102. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js +178 -0
  103. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.scss +9 -0
  104. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js +39 -0
  105. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesConstants.js +4 -0
  106. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesHelpers.js +11 -0
  107. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesHelpers.test.js +50 -0
  108. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +39 -0
  109. data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +177 -0
  110. data/webpack/components/AnsibleRolesAndVariables/index.js +31 -0
  111. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +25 -27
  112. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +1 -1
  113. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +20 -14
  114. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +1 -2
  115. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +13 -8
  116. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +8 -28
  117. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +1 -0
  118. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +6 -4
  119. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +1 -9
  120. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +3 -16
  121. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +4 -8
  122. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +8 -97
  123. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +5 -30
  124. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +1 -1
  125. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +5 -2
  126. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +1 -1
  127. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.js +43 -0
  128. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.test.js +19 -0
  129. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +63 -51
  130. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +4 -1
  131. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +1 -1
  132. data/webpack/components/AnsibleRolesSwitcher/components/OrderedRolesTooltip.js +23 -0
  133. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRoleInputs.test.js.snap +51 -0
  134. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +28 -28
  135. data/webpack/components/AnsibleRolesSwitcher/index.js +4 -8
  136. data/webpack/index.js +6 -13
  137. metadata +63 -18
  138. data/app/views/ansible_variables/import.html.erb +0 -56
  139. data/webpack/test_setup.js +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '059c70bd67d597c230eea6135f738afd7c203c27cb1e1d1a7d5b3b88bada984f'
4
- data.tar.gz: 2509eb475c69a745d46f726700a5308ee128823f90aaa8e852067b941797141e
3
+ metadata.gz: 49f289f46429611b1f8d183bab027589b46367fca60323c57e5370848ad12b7a
4
+ data.tar.gz: 887cf57c344a0f2a4baf1ee8fb6ae3be635ac9ab5e3073adf88e797a8eaca51f
5
5
  SHA512:
6
- metadata.gz: 212613afe4068af042fcb9340bddab879afd4c0b7ced2a6748861561cd76ed185609d2582fed69b03af76f7753b83cb5a18923f2d2170480a1deb3e17fb34338
7
- data.tar.gz: 4134c4f15af8a5567ddc319978f5c1538e982bc83923d9ba8a1c45a524fb0d7628f236079d6355c9ab5f5d5ca931a85f1bd1c52673efb2ae2e7f2ed8a21d4b9d
6
+ metadata.gz: 38061c87845fdd6d73817ba6b3e60a6470fb72302f731600fe06360dd7ce5593775dabb71c3d1414fe00ebd5711640250302bd3f5ef831699847d4d3b8987cf5
7
+ data.tar.gz: 9c79bd81e50619cbc49ad5b80a93a9702144b21eed1a39b3d0988e949f594a04e2e9bed73700eb090a4b17eb6580d6996f6b440f3e0a10286f3d7880c4b25617
@@ -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
@@ -42,10 +50,7 @@ module ForemanAnsible
42
50
  end
43
51
 
44
52
  def report_json_viewer(json)
45
- uid = "reportjson-viewer-#{json.object_id}"
46
- viewer = content_tag :div, '', :id => uid
47
- viewer << mount_react_component('ReportJsonViewer',
48
- "##{uid}", json.to_json)
53
+ react_component('ReportJsonViewer', data: json)
49
54
  end
50
55
 
51
56
  private
@@ -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,7 +27,8 @@ 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