foreman_ansible 6.1.0 → 6.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) 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 +42 -56
  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 +7 -4
  13. data/app/models/foreman_ansible/ansible_provider.rb +53 -3
  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 +24 -8
  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_-_ansible_default.erb +4 -0
  35. data/app/views/foreman_ansible/job_templates/ansible_roles_-_install_from_galaxy.erb +1 -1
  36. data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +44 -0
  37. data/config/routes.rb +5 -4
  38. data/db/migrate/20210120150019_add_position_to_ansible_role.rb +27 -0
  39. data/db/seeds.d/100_common_parameters.rb +7 -0
  40. data/db/seeds.d/90_notification_blueprints.rb +19 -1
  41. data/lib/foreman_ansible/engine.rb +1 -1
  42. data/lib/foreman_ansible/register.rb +7 -5
  43. data/lib/foreman_ansible/version.rb +1 -1
  44. data/locale/ca/LC_MESSAGES/foreman_ansible.mo +0 -0
  45. data/locale/ca/foreman_ansible.po +1 -1
  46. data/locale/cs_CZ/LC_MESSAGES/foreman_ansible.mo +0 -0
  47. data/locale/cs_CZ/foreman_ansible.po +1 -1
  48. data/locale/de/LC_MESSAGES/foreman_ansible.mo +0 -0
  49. data/locale/de/foreman_ansible.po +1 -1
  50. data/locale/en/LC_MESSAGES/foreman_ansible.mo +0 -0
  51. data/locale/en/foreman_ansible.po +1 -1
  52. data/locale/en_GB/LC_MESSAGES/foreman_ansible.mo +0 -0
  53. data/locale/en_GB/foreman_ansible.po +1 -1
  54. data/locale/es/LC_MESSAGES/foreman_ansible.mo +0 -0
  55. data/locale/es/foreman_ansible.po +1 -1
  56. data/locale/fr/LC_MESSAGES/foreman_ansible.mo +0 -0
  57. data/locale/fr/foreman_ansible.po +1 -1
  58. data/locale/gl/LC_MESSAGES/foreman_ansible.mo +0 -0
  59. data/locale/gl/foreman_ansible.po +1 -1
  60. data/locale/it/LC_MESSAGES/foreman_ansible.mo +0 -0
  61. data/locale/it/foreman_ansible.po +1 -1
  62. data/locale/ja/LC_MESSAGES/foreman_ansible.mo +0 -0
  63. data/locale/ja/foreman_ansible.po +1 -1
  64. data/locale/ko/LC_MESSAGES/foreman_ansible.mo +0 -0
  65. data/locale/ko/foreman_ansible.po +1 -1
  66. data/locale/nl_NL/LC_MESSAGES/foreman_ansible.mo +0 -0
  67. data/locale/nl_NL/foreman_ansible.po +1 -1
  68. data/locale/pl/LC_MESSAGES/foreman_ansible.mo +0 -0
  69. data/locale/pl/foreman_ansible.po +1 -1
  70. data/locale/pt_BR/LC_MESSAGES/foreman_ansible.mo +0 -0
  71. data/locale/pt_BR/foreman_ansible.po +1 -1
  72. data/locale/ru/LC_MESSAGES/foreman_ansible.mo +0 -0
  73. data/locale/ru/foreman_ansible.po +1 -1
  74. data/locale/sv_SE/LC_MESSAGES/foreman_ansible.mo +0 -0
  75. data/locale/sv_SE/foreman_ansible.po +1 -1
  76. data/locale/zh_CN/LC_MESSAGES/foreman_ansible.mo +0 -0
  77. data/locale/zh_CN/foreman_ansible.po +1 -1
  78. data/locale/zh_TW/LC_MESSAGES/foreman_ansible.mo +0 -0
  79. data/locale/zh_TW/foreman_ansible.po +1 -1
  80. data/package.json +13 -42
  81. data/test/factories/ansible_roles.rb +12 -0
  82. data/test/factories/host_ansible_enhancements.rb +23 -0
  83. data/test/foreman_ansible/helpers/ansible_roles_helper_test.rb +45 -0
  84. data/test/functional/ansible_variables_controller_test.rb +0 -15
  85. data/test/functional/api/v2/ansible_roles_controller_test.rb +23 -0
  86. data/test/functional/api/v2/hostgroups_controller_test.rb +5 -4
  87. data/test/functional/api/v2/hosts_controller_test.rb +9 -8
  88. data/test/functional/hosts_controller_test.rb +10 -6
  89. data/test/unit/ansible_provider_test.rb +1 -1
  90. data/test/unit/concerns/host_managed_extensions_test.rb +17 -3
  91. data/test/unit/concerns/hostgroup_extensions_test.rb +13 -7
  92. data/test/unit/helpers/ansible_reports_helper_test.rb +4 -30
  93. data/test/unit/host_ansible_role_test.rb +2 -1
  94. data/test/unit/hostgroup_ansible_role_test.rb +2 -1
  95. data/test/unit/ignore_roles_test.rb +43 -0
  96. data/test/unit/import_roles_and_variables.rb +60 -0
  97. data/test/unit/services/ansible_variables_importer_test.rb +13 -0
  98. data/test/unit/services/api_roles_importer_test.rb +22 -5
  99. data/test/unit/services/fact_parser_test.rb +16 -0
  100. data/test/unit/services/inventory_creator_test.rb +16 -8
  101. data/test/unit/services/ui_roles_importer_test.rb +2 -2
  102. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +35 -0
  103. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss +6 -0
  104. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js +14 -0
  105. data/webpack/components/AnsibleHostDetail/index.js +6 -0
  106. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js +178 -0
  107. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.scss +9 -0
  108. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js +39 -0
  109. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesConstants.js +4 -0
  110. data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesHelpers.js +11 -0
  111. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesHelpers.test.js +50 -0
  112. data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +39 -0
  113. data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +177 -0
  114. data/webpack/components/AnsibleRolesAndVariables/index.js +31 -0
  115. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +25 -27
  116. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +1 -1
  117. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +20 -14
  118. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +1 -2
  119. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +13 -8
  120. data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +8 -28
  121. data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +1 -0
  122. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +6 -4
  123. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +1 -9
  124. data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +3 -16
  125. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +4 -8
  126. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +8 -97
  127. data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +5 -30
  128. data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +1 -1
  129. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +5 -2
  130. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +1 -1
  131. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.js +43 -0
  132. data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.test.js +19 -0
  133. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +63 -51
  134. data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +4 -1
  135. data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +1 -1
  136. data/webpack/components/AnsibleRolesSwitcher/components/OrderedRolesTooltip.js +23 -0
  137. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +2 -0
  138. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRoleInputs.test.js.snap +51 -0
  139. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +28 -28
  140. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +5 -0
  141. data/webpack/components/AnsibleRolesSwitcher/index.js +4 -8
  142. data/webpack/global_index.js +12 -0
  143. data/webpack/index.js +6 -13
  144. metadata +54 -30
  145. data/app/views/ansible_variables/import.html.erb +0 -56
  146. data/test/unit/lib/foreman_ansible_core/ansible_runner_test.rb +0 -51
  147. data/test/unit/lib/foreman_ansible_core/command_creator_test.rb +0 -64
  148. data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +0 -110
  149. data/webpack/__mocks__/foremanReact/common/I18n.js +0 -1
  150. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
  151. data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +0 -5
  152. data/webpack/test_setup.js +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f0adadc325dd31954f306695e4f6be32b13d6388db0893cfc2685a2bbb53df3
4
- data.tar.gz: 7a3e2bf970e9ebff66219696b5bc4714853b109344d943e8d89d02f45b4b50c0
3
+ metadata.gz: 7372e9f417f4225960801ac1f4acc985cad46ba42c52d56e032606629ad56023
4
+ data.tar.gz: 13e84008911f9e80328edaf319ea4c777394acf4ccd3c7fab1e3e1f72f8021ac
5
5
  SHA512:
6
- metadata.gz: d0ae153aa823b601fccf70886d3e6f036585010467c5df1233bb84c3851ca4fc2b5d83e7f3f4a89c796a38f0e1497c58c550d33777c480b058d5e8eafc9f9195
7
- data.tar.gz: 83f7f0c912b9db4dda3a363690aaf49117581680a1638718410efe9f0c937ba9caae35599c04130ddcc10540a586af57215d279f959abda41aec4a4dd814a76b
6
+ metadata.gz: 757df63ad76072bc4f6ea3440ca66a534318234e6117e9380ba8a8bb5078cceb83b1e668a532a8d96a9bc063b6e393ec10d6a5d8c474b8c866b75358ea5de07f
7
+ data.tar.gz: 67a3b416c2e02d186be7dd48a2de8dde78c6c7279952f3b59deb7fa5d3694761e18b71436bc0a135b68044975b660380063897e6c5e99e1b7a962c977f71c3fe
@@ -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
@@ -4,27 +4,57 @@ module ForemanAnsible
4
4
  # This module takes the config reports stored in Foreman for Ansible and
5
5
  # modifies them to be properly presented in views
6
6
  module AnsibleReportsHelper
7
- ANSIBLE_META_KEYS = %w[
8
- _ansible_parsed _ansible_no_log _ansible_item_result
9
- _ansible_ignore_errors _ansible_verbose_always _ansible_verbose_override
10
- ].freeze
11
- ANSIBLE_HIDDEN_KEYS = %w[
12
- invocation module_args results ansible_facts
13
- stdout stderr
14
- ].freeze
15
-
16
7
  def ansible_module_name(log)
17
8
  source_value = log.source&.value
18
9
  name = source_value.split(':')[0].strip if source_value&.include?(':')
19
10
  name
20
11
  end
21
12
 
22
- def ansible_module_args(log)
23
- report_json_viewer module_invocations parsed_message_json(log)
13
+ def ansible_task_name(log)
14
+ source_value = log.source&.value
15
+ return source_value || no_data_message unless source_value.include? ':'
16
+ name = source_value.split(':')[1].strip if source_value.include?(':')
17
+ name || no_data_message
18
+ end
19
+
20
+ def ansible_run_in_check_mode?(log)
21
+ log.message&.value == 'check_mode_enabled' if check_mode_log?(log)
22
+ end
23
+
24
+ def check_mode_log?(log)
25
+ log.source&.value == 'check_mode'
24
26
  end
25
27
 
26
28
  def ansible_module_message(log)
27
- report_json_viewer hash_with_keys_removed parsed_message_json(log)
29
+ msg_json = parsed_message_json(log)
30
+ module_action = msg_json['module']
31
+ case module_action
32
+ when 'package'
33
+ msg_json['results'].empty? ? msg_json['msg'] : msg_json['results']
34
+ when 'template'
35
+ module_args = msg_json['invocation']['module_args']
36
+ _("Rendered template #{module_args['_original_basename']} to #{msg_json['dest']}")
37
+ when 'service'
38
+ _("Service #{msg_json['name']} #{msg_json['state']} (enabled: #{msg_json['enabled']})")
39
+ when 'group'
40
+ _("User group #{msg_json['name']} #{msg_json['state']}, gid: #{msg_json['gid']}")
41
+ when 'user'
42
+ _("User #{msg_json['name']} #{msg_json['state']}, uid: #{msg_json['uid']}")
43
+ when 'cron'
44
+ module_args = msg_json['invocation']['module_args']
45
+ _("Cron job: #{module_args['minute']} #{module_args['hour']} #{module_args['day']} #{module_args['month']} #{module_args['weekday']} #{module_args['job']} (disabled: #{module_args['disabled']})")
46
+ when 'copy'
47
+ module_args = msg_json['invocation']['module_args']
48
+ _("Copy #{module_args['_original_basename']} to #{msg_json['dest']}")
49
+ when 'command', 'shell'
50
+ msg_json['stdout_lines']
51
+ else
52
+ no_data_message
53
+ end
54
+ end
55
+
56
+ def no_data_message
57
+ _('No additional data')
28
58
  end
29
59
 
30
60
  def ansible_report_origin_icon
@@ -41,52 +71,8 @@ module ForemanAnsible
41
71
  false
42
72
  end
43
73
 
44
- 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)
49
- end
50
-
51
74
  private
52
75
 
53
- def module_invocations(hash)
54
- invocations = []
55
- invocations << hash.delete('invocation')
56
- results = hash.delete('results')
57
- invocations << results
58
- invocations = invocations.compact.flatten.map do |ih|
59
- ih.is_a?(Hash) ? remove_keys(ih) : ih
60
- end
61
- invocations
62
- end
63
-
64
- def pretty_print_hash(hash)
65
- prettyp = JSON.pretty_generate(remove_keys(hash))
66
- prettyp.gsub!(/{\n*/, "\n")
67
- prettyp.gsub!(/},*\n*/, "\n")
68
- prettyp.gsub!(/^(\[|\])/, '')
69
- prettyp.gsub!(/^[\s]*$\n/, '')
70
- paragraph_style = 'white-space:pre;padding: 2em 0'
71
- tag(:p, prettyp, :style => paragraph_style)
72
- end
73
-
74
- def hash_with_keys_removed(hash)
75
- new_hash = remove_keys(hash)
76
- remove_keys(new_hash, ANSIBLE_HIDDEN_KEYS)
77
- end
78
-
79
- def remove_keys(hash, keys = ANSIBLE_META_KEYS)
80
- hash.each do |key, value|
81
- if value.is_a? Array
82
- value.each { |h| remove_keys(h) if h.is_a? Hash }
83
- elsif value.is_a? Hash
84
- remove_keys(value)
85
- end
86
- hash.delete(key) if keys.include? key
87
- end
88
- end
89
-
90
76
  def parsed_message_json(log)
91
77
  JSON.parse(log.message.value)
92
78
  rescue StandardError => e
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAnsible
4
+ module AnsibleRolesDataPreparations
5
+ VARIABLE_ACTION_NAMES = { 'new' => N_('Add'), 'obsolete' => N_('Remove'), 'update' => N_('Update') }.freeze
6
+ ROLE_ACTION_NAMES = { 'new' => N_('Import Role'), 'obsolete' => N_('Remove Role'), 'old' => N_('Update Role Variables') }.freeze
7
+
8
+ def get_variable_action(kind)
9
+ _(VARIABLE_ACTION_NAMES[kind])
10
+ end
11
+
12
+ def get_role_action(kind)
13
+ _(ROLE_ACTION_NAMES[kind])
14
+ end
15
+
16
+ def get_old_roles_variables(imported_variables, role)
17
+ variables = { 'Add' => [], 'Remove' => [], 'Update' => [] }
18
+ imported_variables.each do |kind, temp_variables|
19
+ temp_variables.each do |temp_variable|
20
+ variables[get_variable_action(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 += "#{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 = { 'Add' => variables_importer.get_variables_names(role.name) }
37
+ elsif kind == 'obsolete'
38
+ variables = { 'Remove' => 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, role_action)
55
+ {
56
+ name: role.name,
57
+ id: role.id,
58
+ role_action: role_action,
59
+ variables: variables,
60
+ hosts_count: role_action == 'Remove Role' ? role.hosts.count : '',
61
+ hostgroup_count: role_action == 'Remove Role' ? role.hostgroups.count : '',
62
+ kind: kind
63
+ }
64
+ end
65
+
66
+ def prepare_ui_row(role, kind, variables, role_action)
67
+ { cells: [
68
+ role.name,
69
+ role_action, variables,
70
+ role_action == 'Remove Role' ? role.hosts.count : '',
71
+ role_action == 'Remove Role' ? role.hostgroups.count : ''
72
+ ],
73
+ role: role, kind: kind, id: role.name }
74
+ end
75
+
76
+ def prepare_ansible_import_rows(changed, variables_importer, is_ui = true)
77
+ rows = []
78
+ changed.each do |kind, roles|
79
+ imported_variables = variables_importer.import_variable_names(roles)
80
+ roles.each do |role|
81
+ next if role_match_excluded_roles(role.name)
82
+ variables = get_roles_variables(imported_variables, variables_importer, kind, role)
83
+ next if variables.empty? && kind['old']
84
+ role_action = get_role_action(kind)
85
+ if is_ui
86
+ rows.append(prepare_ui_row(role, kind, variables, role_action))
87
+ else
88
+ rows.append(prepare_api_row(role, kind, variables, role_action))
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