foreman_rh_cloud 3.0.19 → 3.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -2
- data/app/controllers/insights_cloud/hits_controller.rb +37 -0
- data/app/controllers/insights_cloud/settings_controller.rb +1 -1
- data/app/controllers/insights_cloud/tasks_controller.rb +1 -2
- data/app/models/inventory_sync/inventory_status.rb +6 -0
- data/app/models/setting/rh_cloud.rb +5 -5
- data/app/services/foreman_rh_cloud/remediations_retriever.rb +78 -0
- data/app/services/foreman_rh_cloud/template_renderer_helper.rb +22 -0
- data/app/views/job_templates/rh_cloud_remediations.erb +14 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20210404000001_change_resolutions.foreman_rh_cloud.rb +10 -0
- data/db/seeds.d/50_job_templates.rb +14 -0
- data/lib/foreman_rh_cloud/engine.rb +13 -1
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/insights_cloud.rb +12 -0
- data/lib/insights_cloud/async/insights_full_sync.rb +16 -6
- data/lib/insights_cloud/async/insights_resolutions_sync.rb +69 -0
- data/lib/insights_cloud/async/insights_rules_sync.rb +13 -17
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +1 -1
- data/lib/tasks/rh_cloud_inventory.rake +1 -1
- data/package.json +1 -1
- data/test/factories/insights_factories.rb +22 -0
- data/test/jobs/insights_full_sync_test.rb +12 -8
- data/test/jobs/insights_resolutions_sync_test.rb +74 -0
- data/test/jobs/insights_rules_sync_test.rb +5 -3
- data/test/jobs/inventory_full_sync_test.rb +1 -1
- data/test/unit/services/foreman_rh_cloud/remediations_retriever_test.rb +49 -0
- data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +28 -0
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/AdvancedSettingsConstants.js +5 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +15 -2
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +13 -2
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -1
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +3 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediateButton.js +59 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationActions.js +12 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +43 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +101 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.scss +9 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +43 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationTableConstants.js +38 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +55 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/index.js +34 -0
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +8 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.scss +5 -0
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +9 -6
- data/webpack/{InsightsCloudSync/Components/InsightsTable/components → common/table}/EmptyState.js +0 -0
- data/webpack/common/table/helpers.js +7 -0
- metadata +33 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a6bf66d7fd1c5302e88b9cd6f28f36c36d9ba8ecfcba3f32e4076c5ba856a05
|
4
|
+
data.tar.gz: d9d67e5ec55ac92e3101544c9e2d7f8f3d8e40112927c70efc23ddb117e8f96b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c241a52fe6d3f028777c0c70cea3cc68a2008cf2392d4dd9608b5332614638dce68baade016fddd46985ddcf6cddfa9638d28a86c6f645147ed52a304063a4a4
|
7
|
+
data.tar.gz: f32f203c82ddc7d4964155ac0afcfa18fc6cd6501df8a9bff9197e6fc03590cd5c71720fb8c512c64c920b503ed01d7a6118f2633e64f36f5a05ffd222af4197
|
data/README.md
CHANGED
@@ -52,7 +52,7 @@ From command-line:
|
|
52
52
|
|
53
53
|
# all organizations
|
54
54
|
/usr/sbin/foreman-rake rh_cloud_insights:sync
|
55
|
-
|
55
|
+
|
56
56
|
# specific organization with id 1
|
57
57
|
export organization_id=1
|
58
58
|
/usr/sbin/foreman-rake rh_cloud_insights:sync
|
@@ -61,6 +61,22 @@ From command-line:
|
|
61
61
|
|
62
62
|
*Todo list here*
|
63
63
|
|
64
|
+
## Design
|
65
|
+
|
66
|
+
### Endpoints
|
67
|
+
|
68
|
+
| purpose | url | ENV setting for the **bold** part
|
69
|
+
| ------------------------------| -------| -----------
|
70
|
+
| Inventory uploads | **https://cert.cloud.redhat.com/api/ingress/v1/upload** | SATELLITE_INVENTORY_UPLOAD_URL
|
71
|
+
| Query inventory hosts list | **https://cloud.redhat.com** /api/inventory/v1/hosts?tags= | SATELLITE_RH_CLOUD_URL
|
72
|
+
| Query insights hits | **https://cloud.redhat.com** /api/insights/v1/export/hits/ | SATELLITE_RH_CLOUD_URL
|
73
|
+
| Query insights rules | **https://cloud.redhat.com** /api/insights/v1/rule/?impacting=true&rule_status=enabled&has_playbook=true&limit=&offset= | SATELLITE_RH_CLOUD_URL
|
74
|
+
| Query insights resolutions | **https://cloud.redhat.com** /api/remediations/v1/resolutions| SATELLITE_RH_CLOUD_URL
|
75
|
+
| Forward insights-client `/static` requests | **https://cloud.redhat.com** /api/static | SATELLITE_RH_CLOUD_URL
|
76
|
+
| Forward insights-client legacy `/platform` requests | **https://cert.cloud.redhat.com** /api | SATELLITE_CERT_RH_CLOUD_URL
|
77
|
+
| Forward insights-client legacy `/redhat_access/r/insights` requests | **https://cert-api.access.redhat.com** /r/insights | SATELLITE_LEGACY_INSIGHTS_URL
|
78
|
+
|
79
|
+
|
64
80
|
## Contributing
|
65
81
|
|
66
82
|
Fork and send a Pull Request. Thanks!
|
@@ -81,4 +97,3 @@ GNU General Public License for more details.
|
|
81
97
|
|
82
98
|
You should have received a copy of the GNU General Public License
|
83
99
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
84
|
-
|
@@ -9,6 +9,7 @@ module InsightsCloud
|
|
9
9
|
hasToken: !Setting[:rh_cloud_token].empty?,
|
10
10
|
hits: hits.map { |hit| hit.attributes.merge(hostname: hit.host&.name, has_playbook: hit.has_playbook?) },
|
11
11
|
itemCount: hits.count,
|
12
|
+
isExperimentalMode: Setting[:lab_features],
|
12
13
|
}, status: :ok
|
13
14
|
end
|
14
15
|
|
@@ -20,6 +21,21 @@ module InsightsCloud
|
|
20
21
|
}, status: :ok
|
21
22
|
end
|
22
23
|
|
24
|
+
def resolutions
|
25
|
+
if remediation_all_selected_param
|
26
|
+
hits = InsightsHit.with_playbook.search_for(params[:query])
|
27
|
+
else
|
28
|
+
hits = resource_base_search_and_page.where(id: remediation_ids_param)
|
29
|
+
end
|
30
|
+
|
31
|
+
hits.preload(:host, rule: :resolutions)
|
32
|
+
|
33
|
+
render json: {
|
34
|
+
hits: hits.map { |hit| hit.attributes.merge(hostname: hit.host&.name, resolutions: hit.rule.resolutions.map(&:attributes), reboot: hit.rule.reboot_required) },
|
35
|
+
itemCount: hits.count,
|
36
|
+
}, status: :ok
|
37
|
+
end
|
38
|
+
|
23
39
|
def model_of_controller
|
24
40
|
::InsightsHit
|
25
41
|
end
|
@@ -32,10 +48,31 @@ module InsightsCloud
|
|
32
48
|
:insights_hits
|
33
49
|
end
|
34
50
|
|
51
|
+
def action_permission
|
52
|
+
case params[:action]
|
53
|
+
when 'resolutions'
|
54
|
+
'view'
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
35
60
|
private
|
36
61
|
|
37
62
|
def host_id_param
|
38
63
|
params.require(:host_id)
|
39
64
|
end
|
65
|
+
|
66
|
+
def remediation_request_params
|
67
|
+
params.permit(remediations: [:hit_id, :remediation_id]).require(:remediations)
|
68
|
+
end
|
69
|
+
|
70
|
+
def remediation_ids_param
|
71
|
+
params.require(:ids).map(&:to_i)
|
72
|
+
end
|
73
|
+
|
74
|
+
def remediation_all_selected_param
|
75
|
+
ActiveModel::Type::Boolean.new.cast(params[:isAllSelected])
|
76
|
+
end
|
40
77
|
end
|
41
78
|
end
|
@@ -13,7 +13,7 @@ module InsightsCloud
|
|
13
13
|
token = Setting::RhCloud.find_by_name("rh_cloud_token")
|
14
14
|
token.value = params.require(:value)
|
15
15
|
token.save!
|
16
|
-
InsightsCloud::Async::InsightsFullSync
|
16
|
+
ForemanTasks.sync_task(InsightsCloud::Async::InsightsFullSync)
|
17
17
|
redirect_to(:controller => "hits", :action => 'index')
|
18
18
|
end
|
19
19
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
module InsightsCloud
|
2
2
|
class TasksController < ::ApplicationController
|
3
3
|
def create
|
4
|
-
|
5
|
-
task = ForemanTasks::Task.find_by(external_id: job.provider_job_id)
|
4
|
+
task = ForemanTasks.async_task(InsightsCloud::Async::InsightsFullSync)
|
6
5
|
|
7
6
|
render json: {
|
8
7
|
task: task,
|
@@ -26,5 +26,11 @@ module InventorySync
|
|
26
26
|
N_('Successfully uploaded to your RH cloud inventory')
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
def to_status(options = {})
|
31
|
+
# this method used to calculate status.
|
32
|
+
# Since the calculation is done externally we should return the previously calculated status
|
33
|
+
status
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
@@ -14,12 +14,12 @@ class Setting::RhCloud < Setting
|
|
14
14
|
def self.default_settings
|
15
15
|
return unless ActiveRecord::Base.connection.table_exists?('settings')
|
16
16
|
[
|
17
|
-
set('allow_auto_inventory_upload', N_('
|
18
|
-
set('allow_auto_insights_sync', N_('
|
19
|
-
set('obfuscate_inventory_hostnames', N_('Obfuscate host names sent to Red Hat cloud'), false, N_('Obfuscate host names')),
|
20
|
-
set('obfuscate_inventory_ips', N_('Obfuscate
|
17
|
+
set('allow_auto_inventory_upload', N_('Enable automatic upload of your host inventory to the Red Hat cloud'), true, N_('Automatic inventory upload')),
|
18
|
+
set('allow_auto_insights_sync', N_('Enable automatic synchronization of Insights recommendations from the Red Hat cloud'), false, N_('Synchronize recommendations Automatically')),
|
19
|
+
set('obfuscate_inventory_hostnames', N_('Obfuscate host names sent to the Red Hat cloud'), false, N_('Obfuscate host names')),
|
20
|
+
set('obfuscate_inventory_ips', N_('Obfuscate ipv4 addresses sent to the Red Hat cloud'), false, N_('Obfuscate host ipv4 addresses')),
|
21
21
|
set('rh_cloud_token', N_('Authentication token to Red Hat cloud services. Used to authenticate requests to cloud APIs'), nil, N_('Red Hat Cloud token'), nil, encrypted: true),
|
22
|
-
set('exclude_installed_packages', N_('Exclude installed packages from Red Hat cloud
|
22
|
+
set('exclude_installed_packages', N_('Exclude installed packages from being uploaded to the Red Hat cloud'), false, N_("Exclude installed Packages")),
|
23
23
|
set('include_parameter_tags', N_('Should import include parameter tags from Foreman?'), false, N_('Include parameters in insights-client reports')),
|
24
24
|
]
|
25
25
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ForemanRhCloud
|
2
|
+
class RemediationsRetriever
|
3
|
+
include CloudAuth
|
4
|
+
|
5
|
+
attr_reader :logger
|
6
|
+
|
7
|
+
def initialize(hit_remediation_pairs, logger: Logger.new(IO::NULL))
|
8
|
+
@hit_remediation_pairs = hit_remediation_pairs
|
9
|
+
@logger = logger
|
10
|
+
|
11
|
+
logger.debug("Querying playbook for #{hit_remediation_pairs}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_playbook
|
15
|
+
response = query_playbook
|
16
|
+
|
17
|
+
logger.debug("Got playbook response: #{response.body}")
|
18
|
+
|
19
|
+
response.body
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def hit_ids
|
25
|
+
@hit_remediation_pairs.map { |pair| pair["hit_id"] }
|
26
|
+
end
|
27
|
+
|
28
|
+
def remediation_ids
|
29
|
+
@hit_remediation_pairs.map { |pair| pair["resolution_id"] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def hits
|
33
|
+
@hits ||= Hash[
|
34
|
+
InsightsHit.joins(:insights_facet).where(id: hit_ids).pluck(:id, 'insights_facets.uuid')
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
def pairs_by_remediation_id
|
39
|
+
@hit_remediation_pairs.group_by { |pair| pair["resolution_id"] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def remediations
|
43
|
+
@remediations ||= Hash[
|
44
|
+
InsightsResolution.where(id: remediation_ids).pluck(:id, :resolution_type, :rule_id).map do |id, resolution_type, rule_id|
|
45
|
+
[id, {resolution_type: resolution_type, rule_id: rule_id}]
|
46
|
+
end
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
def playbook_request
|
51
|
+
{
|
52
|
+
issues: pairs_by_remediation_id.map do |remediation_id, pairs|
|
53
|
+
{
|
54
|
+
resolution: remediations[remediation_id][:resolution_type],
|
55
|
+
id: InsightsCloud.remediation_rule_id(remediations[remediation_id][:rule_id]),
|
56
|
+
systems: pairs.map do |pair|
|
57
|
+
hits[pair["hit_id"]]
|
58
|
+
end,
|
59
|
+
}
|
60
|
+
end,
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def query_playbook
|
65
|
+
RestClient::Request.execute(
|
66
|
+
method: :post,
|
67
|
+
url: InsightsCloud.playbook_url,
|
68
|
+
verify_ssl: ForemanRhCloud.verify_ssl_method,
|
69
|
+
proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
|
70
|
+
headers: {
|
71
|
+
content_type: :json,
|
72
|
+
Authorization: "Bearer #{rh_credentials}",
|
73
|
+
},
|
74
|
+
payload: playbook_request.to_json
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ForemanRhCloud
|
2
|
+
# Macro to fetch remediation playbook from cloud.redhat.com
|
3
|
+
module TemplateRendererHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
extend ApipieDSL::Module
|
6
|
+
|
7
|
+
apipie :class, 'Macros related to Red Hat cloud interface' do
|
8
|
+
name 'RHCloud'
|
9
|
+
sections only: %w[all jobs]
|
10
|
+
end
|
11
|
+
|
12
|
+
apipie :method, 'Returns a playbook generated from Red Hat cloud recommendations' do
|
13
|
+
required :hit_remediation_pairs, String, desc: 'JSON-encoded array of hashes in the form of [{hit_id: 1, remediation_id: 2}, ...]'
|
14
|
+
returns String, desc: 'Playbook generated for the specific recommendations and hosts'
|
15
|
+
end
|
16
|
+
def remediations_playbook(hit_remediation_pairs)
|
17
|
+
hit_remediation_pairs = JSON.parse(hit_remediation_pairs)
|
18
|
+
retriever = ForemanRhCloud::RemediationsRetriever.new(hit_remediation_pairs, logger: template_logger)
|
19
|
+
retriever.create_playbook
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%#
|
2
|
+
kind: job_template
|
3
|
+
name: Run remediations based on Insights recommendations
|
4
|
+
job_category: Red Hat Insights
|
5
|
+
description_format: 'Insights remediations for selected issues'
|
6
|
+
feature: rh_cloud_remediate_hosts
|
7
|
+
template_inputs:
|
8
|
+
- name: hit_remediation_pairs
|
9
|
+
description: Pairs of issues and selected remediation
|
10
|
+
input_type: user
|
11
|
+
required: true
|
12
|
+
provider_type: Ansible
|
13
|
+
%>
|
14
|
+
<%= remediations_playbook(input('hit_remediation_pairs')) %>
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
class ChangeResolutions < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
remove_column :insights_resolutions, :system_type, :integer
|
4
|
+
remove_column :insights_resolutions, :has_playbook, :boolean
|
5
|
+
rename_column :insights_resolutions, :resolution, :description
|
6
|
+
add_column :insights_resolutions, :needs_reboot, :boolean
|
7
|
+
add_column :insights_resolutions, :resolution_risk, :integer
|
8
|
+
add_column :insights_resolutions, :resolution_type, :string
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
organizations = Organization.unscoped.all
|
2
|
+
locations = Location.unscoped.all
|
3
|
+
User.as_anonymous_admin do
|
4
|
+
JobTemplate.without_auditing do
|
5
|
+
Dir[File.join("#{ForemanRhCloud::Engine.root}/app/views/job_templates/**/*.erb")].each do |template|
|
6
|
+
template = JobTemplate.import_raw!(File.read(template),
|
7
|
+
:default => true,
|
8
|
+
:lock => true,
|
9
|
+
:update => true)
|
10
|
+
template.organizations = organizations if template.present?
|
11
|
+
template.locations = locations if template.present?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -48,7 +48,7 @@ module ForemanRhCloud
|
|
48
48
|
:view_insights_hits,
|
49
49
|
{
|
50
50
|
'/foreman_rh_cloud/insights_cloud': [:index], # for bookmarks and later for showing the page
|
51
|
-
'insights_cloud/hits': [:index, :show, :auto_complete_search],
|
51
|
+
'insights_cloud/hits': [:index, :show, :auto_complete_search, :resolutions],
|
52
52
|
'insights_cloud/settings': [:index, :show],
|
53
53
|
'react': [:index],
|
54
54
|
},
|
@@ -87,6 +87,9 @@ module ForemanRhCloud
|
|
87
87
|
id: 'insights',
|
88
88
|
onlyif: proc { |host| host.insights }
|
89
89
|
end
|
90
|
+
|
91
|
+
extend_template_helpers ForemanRhCloud::TemplateRendererHelper
|
92
|
+
allowed_template_helpers :remediations_playbook
|
90
93
|
end
|
91
94
|
|
92
95
|
::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
|
@@ -114,5 +117,14 @@ module ForemanRhCloud
|
|
114
117
|
locale_domain = 'foreman_rh_cloud'
|
115
118
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
116
119
|
end
|
120
|
+
|
121
|
+
config.to_prepare do
|
122
|
+
RemoteExecutionFeature.register(
|
123
|
+
:rh_cloud_remediate_hosts,
|
124
|
+
N_('Apply Insights recommendations'),
|
125
|
+
description: N_('Run remediation playbook generated by Insights'),
|
126
|
+
host_action_button: false
|
127
|
+
)
|
128
|
+
end
|
117
129
|
end
|
118
130
|
end
|
data/lib/insights_cloud.rb
CHANGED
@@ -16,4 +16,16 @@ module InsightsCloud
|
|
16
16
|
def self.rules_url(limit: ForemanRhCloud.query_limit, offset: 0)
|
17
17
|
ForemanRhCloud.base_url + "/api/insights/v1/rule/?impacting=true&rule_status=enabled&has_playbook=true&limit=#{limit}&offset=#{offset}"
|
18
18
|
end
|
19
|
+
|
20
|
+
def self.resolutions_url
|
21
|
+
ForemanRhCloud.base_url + '/api/remediations/v1/resolutions'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.playbook_url
|
25
|
+
ForemanRhCloud.base_url + '/api/remediations/v1/playbook'
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.remediation_rule_id(rule_id)
|
29
|
+
"advisor:#{rule_id}"
|
30
|
+
end
|
19
31
|
end
|
@@ -2,17 +2,19 @@ require 'rest-client'
|
|
2
2
|
|
3
3
|
module InsightsCloud
|
4
4
|
module Async
|
5
|
-
class InsightsFullSync < ::
|
5
|
+
class InsightsFullSync < ::Actions::EntryAction
|
6
6
|
include ::ForemanRhCloud::CloudAuth
|
7
7
|
|
8
|
-
def
|
8
|
+
def plan
|
9
9
|
# This can be turned off when we enable automatic status syncs
|
10
10
|
# This step will query cloud inventory to retrieve inventory uuids for each host
|
11
|
-
|
11
|
+
plan_hosts_sync
|
12
|
+
plan_self
|
13
|
+
plan_rules_sync
|
14
|
+
end
|
12
15
|
|
16
|
+
def run
|
13
17
|
perform_hits_sync
|
14
|
-
|
15
|
-
InsightsRulesSync.perform_later
|
16
18
|
end
|
17
19
|
|
18
20
|
def perform_hits_sync
|
@@ -25,11 +27,19 @@ module InsightsCloud
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def logger
|
28
|
-
|
30
|
+
action_logger
|
29
31
|
end
|
30
32
|
|
31
33
|
private
|
32
34
|
|
35
|
+
def plan_hosts_sync
|
36
|
+
plan_action InventorySync::Async::InventoryHostsSync
|
37
|
+
end
|
38
|
+
|
39
|
+
def plan_rules_sync
|
40
|
+
plan_action InsightsRulesSync
|
41
|
+
end
|
42
|
+
|
33
43
|
def query_insights_hits
|
34
44
|
hits_response = RestClient::Request.execute(
|
35
45
|
method: :get,
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module InsightsCloud
|
4
|
+
module Async
|
5
|
+
class InsightsResolutionsSync < ::Actions::EntryAction
|
6
|
+
include ::ForemanRhCloud::CloudAuth
|
7
|
+
|
8
|
+
RULE_ID_REGEX = /[^:]*:(?<id>.*)/
|
9
|
+
|
10
|
+
def run
|
11
|
+
InsightsResolution.transaction do
|
12
|
+
InsightsResolution.delete_all
|
13
|
+
api_response = query_insights_resolutions(relevant_rules)
|
14
|
+
write_resolutions(api_response)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def logger
|
19
|
+
action_logger
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def query_insights_resolutions(rule_ids)
|
25
|
+
resolutions_response = RestClient::Request.execute(
|
26
|
+
method: :post,
|
27
|
+
url: InsightsCloud.resolutions_url,
|
28
|
+
verify_ssl: ForemanRhCloud.verify_ssl_method,
|
29
|
+
proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
|
30
|
+
headers: {
|
31
|
+
content_type: :json,
|
32
|
+
Authorization: "Bearer #{rh_credentials}",
|
33
|
+
},
|
34
|
+
payload: {
|
35
|
+
issues: rule_ids,
|
36
|
+
}.to_json
|
37
|
+
)
|
38
|
+
|
39
|
+
JSON.parse(resolutions_response)
|
40
|
+
end
|
41
|
+
|
42
|
+
def relevant_rules
|
43
|
+
InsightsRule.all.pluck(:rule_id).map { |id| InsightsCloud.remediation_rule_id(id) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_resolution_hash(rule_id, resolution_hash)
|
47
|
+
{
|
48
|
+
rule_id: rule_id,
|
49
|
+
description: resolution_hash['description'],
|
50
|
+
resolution_type: resolution_hash['id'],
|
51
|
+
needs_reboot: resolution_hash['needs_reboot'],
|
52
|
+
resolution_risk: resolution_hash['resolution_risk'],
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def write_resolutions(response)
|
57
|
+
all_resolutions = response.map do |rule_id, rule_details|
|
58
|
+
rule_details['resolutions'].map { |resolution| to_resolution_hash(to_rule_id(rule_id), resolution) }
|
59
|
+
end.flatten
|
60
|
+
|
61
|
+
InsightsResolution.create(all_resolutions)
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_rule_id(resolution_rule_id)
|
65
|
+
RULE_ID_REGEX.match(resolution_rule_id).named_captures.fetch('id', resolution_rule_id)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|