foreman_ansible 6.0.2 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/ansible_roles_controller.rb +12 -8
- data/app/controllers/ansible_variables_controller.rb +4 -0
- data/app/controllers/api/v2/ansible_inventories_controller.rb +2 -2
- data/app/controllers/api/v2/ansible_roles_controller.rb +32 -11
- data/app/controllers/api/v2/ansible_variables_controller.rb +6 -4
- data/app/controllers/foreman_ansible/concerns/import_controller_helper.rb +3 -3
- data/app/helpers/foreman_ansible/ansible_reports_helper.rb +42 -56
- data/app/helpers/foreman_ansible/ansible_roles_data_preparations.rb +95 -0
- data/app/helpers/foreman_ansible/ansible_roles_helper.rb +20 -1
- data/app/jobs/sync_roles_and_variables.rb +20 -0
- data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +10 -7
- data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +19 -4
- data/app/models/foreman_ansible/ansible_provider.rb +52 -2
- data/app/models/host_ansible_role.rb +1 -0
- data/app/models/hostgroup_ansible_role.rb +1 -0
- data/app/models/setting/ansible.rb +9 -0
- data/app/services/foreman_ansible/ansible_report_importer.rb +4 -0
- data/app/services/foreman_ansible/ansible_report_scanner.rb +15 -1
- data/app/services/foreman_ansible/api_roles_importer.rb +23 -11
- data/app/services/foreman_ansible/fact_parser.rb +21 -1
- data/app/services/foreman_ansible/import_roles_and_variables_error_notification.rb +31 -0
- data/app/services/foreman_ansible/import_roles_and_variables_success_notification.rb +26 -0
- data/app/services/foreman_ansible/inventory_creator.rb +3 -7
- data/app/services/foreman_ansible/operating_system_parser.rb +8 -2
- data/app/services/foreman_ansible/roles_importer.rb +3 -2
- data/app/services/foreman_ansible/ui_roles_importer.rb +2 -2
- data/app/services/foreman_ansible/variables_importer.rb +36 -1
- data/app/views/ansible_roles/import.html.erb +10 -50
- data/app/views/ansible_variables/index.html.erb +1 -2
- data/app/views/api/v2/ansible_roles/sync.json.rabl +5 -0
- data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +8 -17
- data/app/views/foreman_ansible/config_reports/_ansible.html.erb +24 -8
- data/app/views/foreman_ansible/job_templates/ansible_collections_-_install_from_galaxy.erb +28 -0
- data/app/views/foreman_ansible/job_templates/ansible_roles_-_ansible_default.erb +4 -0
- data/app/views/foreman_ansible/job_templates/ansible_roles_-_install_from_galaxy.erb +1 -1
- data/app/views/foreman_ansible/job_templates/capsule_upgrade_-_ansible_default.erb +2 -3
- data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +44 -0
- data/config/routes.rb +5 -4
- data/db/migrate/20210120150019_add_position_to_ansible_role.rb +27 -0
- data/db/seeds.d/100_common_parameters.rb +7 -0
- data/db/seeds.d/90_notification_blueprints.rb +19 -1
- data/lib/foreman_ansible/engine.rb +1 -1
- data/lib/foreman_ansible/register.rb +7 -5
- data/lib/foreman_ansible/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/ca/foreman_ansible.po +1 -1
- data/locale/cs_CZ/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/cs_CZ/foreman_ansible.po +1 -1
- data/locale/de/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/de/foreman_ansible.po +1 -1
- data/locale/en/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/en/foreman_ansible.po +1 -1
- data/locale/en_GB/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/en_GB/foreman_ansible.po +1 -1
- data/locale/es/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/es/foreman_ansible.po +1 -1
- data/locale/fr/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/fr/foreman_ansible.po +1 -1
- data/locale/gl/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/gl/foreman_ansible.po +1 -1
- data/locale/it/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/it/foreman_ansible.po +1 -1
- data/locale/ja/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/ja/foreman_ansible.po +1 -1
- data/locale/ko/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/ko/foreman_ansible.po +1 -1
- data/locale/nl_NL/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/nl_NL/foreman_ansible.po +1 -1
- data/locale/pl/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/pl/foreman_ansible.po +1 -1
- data/locale/pt_BR/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/pt_BR/foreman_ansible.po +1 -1
- data/locale/ru/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/ru/foreman_ansible.po +1 -1
- data/locale/sv_SE/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/sv_SE/foreman_ansible.po +1 -1
- data/locale/zh_CN/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/zh_CN/foreman_ansible.po +1 -1
- data/locale/zh_TW/LC_MESSAGES/foreman_ansible.mo +0 -0
- data/locale/zh_TW/foreman_ansible.po +1 -1
- data/package.json +13 -42
- data/test/factories/ansible_roles.rb +12 -0
- data/test/factories/host_ansible_enhancements.rb +23 -0
- data/test/foreman_ansible/helpers/ansible_roles_helper_test.rb +45 -0
- data/test/functional/ansible_variables_controller_test.rb +0 -15
- data/test/functional/api/v2/ansible_roles_controller_test.rb +23 -0
- data/test/functional/api/v2/hostgroups_controller_test.rb +5 -4
- data/test/functional/api/v2/hosts_controller_test.rb +9 -8
- data/test/functional/hosts_controller_test.rb +10 -6
- data/test/unit/concerns/host_managed_extensions_test.rb +17 -3
- data/test/unit/concerns/hostgroup_extensions_test.rb +13 -7
- data/test/unit/helpers/ansible_reports_helper_test.rb +4 -30
- data/test/unit/host_ansible_role_test.rb +2 -1
- data/test/unit/hostgroup_ansible_role_test.rb +2 -1
- data/test/unit/ignore_roles_test.rb +43 -0
- data/test/unit/import_roles_and_variables.rb +60 -0
- data/test/unit/services/ansible_variables_importer_test.rb +13 -0
- data/test/unit/services/api_roles_importer_test.rb +22 -5
- data/test/unit/services/fact_parser_test.rb +16 -0
- data/test/unit/services/inventory_creator_test.rb +15 -7
- data/test/unit/services/ui_roles_importer_test.rb +2 -2
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +35 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss +6 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js +14 -0
- data/webpack/components/AnsibleHostDetail/index.js +6 -0
- data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js +178 -0
- data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.scss +9 -0
- data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js +39 -0
- data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesConstants.js +4 -0
- data/webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesHelpers.js +11 -0
- data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesHelpers.test.js +50 -0
- data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +39 -0
- data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +177 -0
- data/webpack/components/AnsibleRolesAndVariables/index.js +31 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +25 -27
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +1 -1
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +20 -14
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +1 -2
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +13 -8
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +8 -28
- data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +1 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +6 -4
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +1 -9
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +3 -16
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +4 -8
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +8 -97
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +5 -30
- data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +1 -1
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +5 -2
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +1 -1
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.js +43 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleInputs.test.js +19 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +63 -51
- data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +4 -1
- data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +1 -1
- data/webpack/components/AnsibleRolesSwitcher/components/OrderedRolesTooltip.js +23 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +2 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRoleInputs.test.js.snap +51 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +28 -28
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +5 -0
- data/webpack/components/AnsibleRolesSwitcher/index.js +4 -8
- data/webpack/global_index.js +12 -0
- data/webpack/index.js +6 -13
- metadata +54 -30
- data/app/views/ansible_variables/import.html.erb +0 -56
- data/test/unit/lib/foreman_ansible_core/ansible_runner_test.rb +0 -51
- data/test/unit/lib/foreman_ansible_core/command_creator_test.rb +0 -64
- data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +0 -110
- data/webpack/__mocks__/foremanReact/common/I18n.js +0 -1
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +0 -5
- data/webpack/test_setup.js +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05c975cb77fe5add41b7281dfa1c2451bb22a09ab5dc6251ab06fd4d00b834e2
|
|
4
|
+
data.tar.gz: 86613f4be767b5af80a06f83b9e13f8f030cd80bc362d866323111b61a0b23a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc27695cef374e8b709ddc3c3882056587cbf975ac7d497c1fec5aaa1885f85bcb3677c2c7fd3f2602f529cba0a6736017703f6d7ca413eb5f2ed7a6de112a94
|
|
7
|
+
data.tar.gz: ba0c5f9b94a51b7328cc0df73bfcc0f47831b1004b275be935fa73a83ae9c6f12b81086071ebe69292c8aa5ad436c5389a6a6f1ac457720bcefe034b456c0ec8
|
|
@@ -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
|
-
|
|
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
|
|
30
|
+
render
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def confirm_import
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
51
|
-
_('No
|
|
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
|
|
@@ -72,8 +72,8 @@ module Api
|
|
|
72
72
|
process_resource_error(:resource => @ansible_inventory)
|
|
73
73
|
end
|
|
74
74
|
rescue StandardError => e
|
|
75
|
-
render_error
|
|
76
|
-
|
|
75
|
+
render_error :custom_error, :status => :unprocessable_entity,
|
|
76
|
+
:locals => { :message => _("Scheduling Report template failed for: #{e.message}") }
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def action_permission
|
|
@@ -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
|
|
38
|
+
param :role_names, Array, N_('Ansible role names to be imported')
|
|
38
39
|
def import
|
|
39
|
-
|
|
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
|
|
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.
|
|
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
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
content_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| { :
|
|
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
|