foreman_rh_cloud 3.0.19 → 4.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -5
  3. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +17 -7
  4. data/app/controllers/insights_cloud/hits_controller.rb +37 -0
  5. data/app/controllers/insights_cloud/settings_controller.rb +1 -1
  6. data/app/controllers/insights_cloud/tasks_controller.rb +1 -2
  7. data/app/models/insights_client_report_status.rb +58 -0
  8. data/app/models/inventory_sync/inventory_status.rb +6 -0
  9. data/app/models/setting/rh_cloud.rb +5 -5
  10. data/app/services/foreman_rh_cloud/cloud_auth.rb +12 -0
  11. data/app/services/foreman_rh_cloud/cloud_connector.rb +1 -1
  12. data/app/services/foreman_rh_cloud/cloud_request.rb +14 -0
  13. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -6
  14. data/app/services/foreman_rh_cloud/remediations_retriever.rb +75 -0
  15. data/app/services/foreman_rh_cloud/template_renderer_helper.rb +22 -0
  16. data/app/subscribers/foreman_rh_cloud/insights_subscriber.rb +9 -0
  17. data/app/views/job_templates/rh_cloud_remediations.erb +14 -0
  18. data/config/routes.rb +1 -0
  19. data/db/migrate/20210404000001_change_resolutions.foreman_rh_cloud.rb +10 -0
  20. data/db/seeds.d/179_ui_notifications.rb +11 -0
  21. data/db/seeds.d/50_job_templates.rb +14 -0
  22. data/lib/foreman_inventory_upload.rb +5 -1
  23. data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +8 -2
  24. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +19 -0
  25. data/lib/foreman_inventory_upload/generators/queries.rb +3 -2
  26. data/lib/foreman_inventory_upload/generators/slice.rb +6 -6
  27. data/lib/foreman_inventory_upload/generators/tags.rb +8 -6
  28. data/lib/foreman_rh_cloud.rb +18 -0
  29. data/lib/foreman_rh_cloud/engine.rb +36 -2
  30. data/lib/foreman_rh_cloud/version.rb +1 -1
  31. data/lib/insights_cloud.rb +12 -0
  32. data/lib/insights_cloud/async/insights_full_sync.rb +31 -22
  33. data/lib/insights_cloud/async/insights_generate_notifications.rb +58 -0
  34. data/lib/insights_cloud/async/insights_resolutions_sync.rb +66 -0
  35. data/lib/insights_cloud/async/insights_rules_sync.rb +15 -24
  36. data/lib/insights_cloud/async/insights_scheduled_sync.rb +1 -1
  37. data/lib/inventory_sync/async/inventory_full_sync.rb +2 -1
  38. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +25 -0
  39. data/lib/inventory_sync/async/query_inventory_job.rb +1 -4
  40. data/lib/tasks/insights.rake +4 -12
  41. data/lib/tasks/rh_cloud_inventory.rake +18 -4
  42. data/package.json +1 -1
  43. data/test/factories/insights_factories.rb +22 -0
  44. data/test/factories/inventory_upload_factories.rb +1 -1
  45. data/test/jobs/insights_full_sync_test.rb +17 -8
  46. data/test/jobs/insights_resolutions_sync_test.rb +77 -0
  47. data/test/jobs/insights_rules_sync_test.rb +8 -3
  48. data/test/jobs/inventory_full_sync_test.rb +4 -1
  49. data/test/models/insights_client_report_status_test.rb +77 -0
  50. data/test/test_plugin_helper.rb +0 -1
  51. data/test/unit/rh_cloud_http_proxy_test.rb +4 -4
  52. data/test/unit/services/foreman_rh_cloud/remediations_retriever_test.rb +49 -0
  53. data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +28 -0
  54. data/test/unit/slice_generator_test.rb +66 -29
  55. data/test/unit/tags_generator_test.rb +10 -0
  56. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.js +1 -1
  57. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/__snapshots__/FullScreenModal.test.js.snap +1 -1
  58. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/fullScreenModal.scss +14 -16
  59. data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/AdvancedSettingsConstants.js +5 -3
  60. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +15 -2
  61. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +13 -2
  62. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +28 -63
  63. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +2 -3
  64. data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.js +1 -1
  65. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/Terminal.test.js +1 -1
  66. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/__snapshots__/Terminal.test.js.snap +2 -2
  67. data/webpack/ForemanInventoryUpload/Components/Terminal/terminal.scss +25 -27
  68. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -1
  69. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +19 -19
  70. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +3 -0
  71. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +14 -14
  72. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediateButton.js +59 -0
  73. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationActions.js +12 -0
  74. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +43 -0
  75. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +101 -0
  76. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.scss +9 -0
  77. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +43 -0
  78. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationTableConstants.js +38 -0
  79. data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +55 -0
  80. data/webpack/InsightsCloudSync/Components/RemediationModal/index.js +34 -0
  81. data/webpack/InsightsCloudSync/InsightsCloudSync.js +11 -3
  82. data/webpack/InsightsCloudSync/InsightsCloudSync.scss +5 -0
  83. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +44 -20
  84. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +2 -0
  85. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +9 -6
  86. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +11 -7
  87. data/webpack/common/ForemanTasks/ForemanTasksActions.js +64 -0
  88. data/webpack/common/ForemanTasks/ForemanTasksHelpers.js +7 -0
  89. data/webpack/common/ForemanTasks/index.js +1 -0
  90. data/webpack/{InsightsCloudSync/Components/InsightsTable/components → common/table}/EmptyState.js +0 -0
  91. data/webpack/common/table/helpers.js +7 -0
  92. metadata +38 -4
@@ -0,0 +1,9 @@
1
+ module ForemanRhCloud
2
+ class InsightsSubscriber < ::Foreman::BaseSubscriber
3
+ def call(*args)
4
+ host = args.first.payload[:object]
5
+ host_status = host.get_status(InsightsClientReportStatus)
6
+ host_status.update(status: host_status.to_status)
7
+ end
8
+ end
9
+ 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
@@ -19,6 +19,7 @@ Rails.application.routes.draw do
19
19
  resources :hits, except: %i[show] do
20
20
  collection do
21
21
  get 'auto_complete_search'
22
+ get 'resolutions', to: 'hits#resolutions'
22
23
  end
23
24
  end
24
25
  match 'hits/:host_id', to: 'hits#show', via: :get
@@ -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,11 @@
1
+ blueprints = [
2
+ {
3
+ group: N_('Red Hat Insights'),
4
+ name: 'insights_satellite_hits',
5
+ message: N_('Satellite server has %{hits_count} recommendations by Red Hat'),
6
+ level: 'warning',
7
+ },
8
+ ]
9
+
10
+ blueprints.each { |blueprint| UINotifications::Seed.new(blueprint).configure }
11
+
@@ -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
@@ -57,10 +57,14 @@ module ForemanInventoryUpload
57
57
  end
58
58
 
59
59
  def self.slice_size
60
- # for testing set ENV to 'https://ci.cloud.redhat.com/api/ingress/v1/upload'
61
60
  @slice_size ||= (ENV['SATELLITE_INVENTORY_SLICE_SIZE'] || '1000').to_i
62
61
  end
63
62
 
63
+ def self.max_org_size
64
+ # Set max amount of hosts per organization for automatic uploads
65
+ @max_org_size ||= (ENV['SATELLITE_INVENTORY_MAX_ORG_SIZE'] || 150_000).to_i
66
+ end
67
+
64
68
  def self.ensure_folder(folder)
65
69
  FileUtils.mkdir_p(folder)
66
70
  folder
@@ -13,8 +13,14 @@ module ForemanInventoryUpload
13
13
  organizations = Organization.unscoped.all
14
14
 
15
15
  organizations.map do |organization|
16
- GenerateReportJob.perform_later(ForemanInventoryUpload.generated_reports_folder, organization.id)
17
- end
16
+ total_hosts = ForemanInventoryUpload::Generators::Queries.for_org(organization.id, use_batches: false).count
17
+
18
+ if total_hosts <= ForemanInventoryUpload.max_org_size
19
+ GenerateReportJob.perform_later(ForemanInventoryUpload.generated_reports_folder, organization.id)
20
+ else
21
+ logger.info("Skipping automatic uploads for organization #{organization.name}, too many hosts (#{total_hosts}/#{ForemanInventoryUpload.max_org_size})")
22
+ end
23
+ end.compact
18
24
  ensure
19
25
  self.class.set(:wait => 24.hours).perform_later
20
26
  end
@@ -10,6 +10,8 @@ module ForemanInventoryUpload
10
10
  CLOUD_AZURE = 'azure'
11
11
  CLOUD_ALIBABA = 'alibaba'
12
12
 
13
+ UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
14
+
13
15
  def fact_value(host, fact_name)
14
16
  value_record = host.fact_values.find do |fact_value|
15
17
  fact_value.fact_name_id == ForemanInventoryUpload::Generators::Queries.fact_names[fact_name]
@@ -104,6 +106,23 @@ module ForemanInventoryUpload
104
106
  def obfuscate_ip(ip, ips_dict)
105
107
  "10.230.230.#{ips_dict.count + 1}"
106
108
  end
109
+
110
+ def bios_uuid(host)
111
+ value = fact_value(host, 'dmi::system::uuid') || ''
112
+ uuid_value(value)
113
+ end
114
+
115
+ def uuid_value(value)
116
+ uuid_match = UUID_REGEX.match(value)
117
+ uuid_match&.to_s
118
+ end
119
+
120
+ def uuid_value!(value)
121
+ uuid = uuid_value(value)
122
+ raise Foreman::Exception.new(N_('Value %{value} is not a valid UUID') % {value: value}) if value && uuid.empty?
123
+
124
+ uuid
125
+ end
107
126
  end
108
127
  end
109
128
  end
@@ -49,8 +49,9 @@ module ForemanInventoryUpload
49
49
  for_org(org_ids)
50
50
  end
51
51
 
52
- def self.for_org(organization_id)
53
- for_slice(Host.unscoped.where(organization_id: organization_id)).in_batches(of: ForemanInventoryUpload.slice_size)
52
+ def self.for_org(organization_id, use_batches: true)
53
+ base_query = for_slice(Host.unscoped.where(organization_id: organization_id))
54
+ use_batches ? base_query.in_batches(of: ForemanInventoryUpload.slice_size) : base_query
54
55
  end
55
56
 
56
57
  def self.organizations_for_user(portal_user)
@@ -25,7 +25,7 @@ module ForemanInventoryUpload
25
25
 
26
26
  def report_slice(hosts_batch)
27
27
  @stream.object do
28
- @stream.simple_field('report_slice_id', @slice_id)
28
+ @stream.simple_field('report_slice_id', uuid_value!(@slice_id))
29
29
  @stream.array_field('hosts', :last) do
30
30
  first = true
31
31
  hosts_batch.each do |host|
@@ -45,10 +45,10 @@ module ForemanInventoryUpload
45
45
  @stream.object do
46
46
  @stream.simple_field('fqdn', fqdn(host))
47
47
  @stream.simple_field('account', account_id(host.organization).to_s)
48
- @stream.simple_field('subscription_manager_id', host.subscription_facet&.uuid)
49
- @stream.simple_field('satellite_id', host.subscription_facet&.uuid)
50
- @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
51
- @stream.simple_field('vm_uuid', fact_value(host, 'virt::uuid'))
48
+ @stream.simple_field('subscription_manager_id', uuid_value!(host.subscription_facet&.uuid))
49
+ @stream.simple_field('satellite_id', uuid_value!(host.subscription_facet&.uuid))
50
+ @stream.simple_field('bios_uuid', bios_uuid(host))
51
+ @stream.simple_field('vm_uuid', uuid_value(fact_value(host, 'virt::uuid')))
52
52
  report_ip_addresses(host, host_ips_cache)
53
53
  report_mac_addresses(host)
54
54
  @stream.object_field('system_profile') do
@@ -85,7 +85,7 @@ module ForemanInventoryUpload
85
85
  @stream.object do
86
86
  @stream.simple_field('namespace', namespace)
87
87
  @stream.simple_field('key', key)
88
- @stream.simple_field('value', value, :last)
88
+ @stream.simple_field('value', value.to_s, :last)
89
89
  end
90
90
  @stream.comma unless last
91
91
  end
@@ -6,12 +6,14 @@ module ForemanInventoryUpload
6
6
  end
7
7
 
8
8
  def generate
9
- locations +
10
- hostgroups +
11
- host_collections +
12
- organizations +
13
- content_data +
14
- satellite_server_data
9
+ (
10
+ locations +
11
+ hostgroups +
12
+ host_collections +
13
+ organizations +
14
+ content_data +
15
+ satellite_server_data
16
+ ).reject { |key, value| value.empty? }
15
17
  end
16
18
 
17
19
  def generate_parameters
@@ -38,12 +38,25 @@ module ForemanRhCloud
38
38
  end
39
39
 
40
40
  def self.proxy_setting(logger: Foreman::Logging.logger('background'))
41
+ fix_port(proxy_string(logger: logger))
42
+ end
43
+
44
+ def self.proxy_string(logger: Foreman::Logging.logger('background'))
41
45
  HttpProxy.default_global_content_proxy&.full_url ||
42
46
  ForemanRhCloud.cdn_proxy(logger: logger) ||
43
47
  ForemanRhCloud.global_foreman_proxy ||
44
48
  ''
45
49
  end
46
50
 
51
+ def self.fix_port(uri_string)
52
+ return '' if uri_string.empty?
53
+
54
+ uri = URI(uri_string)
55
+ uri.send(:define_singleton_method, :default_port, -> { nil })
56
+
57
+ uri.to_s
58
+ end
59
+
47
60
  def self.cdn_proxy(logger: Foreman::Logging.logger('app'))
48
61
  proxy_config = SETTINGS[:katello][:cdn_proxy]
49
62
  return nil unless proxy_config
@@ -82,4 +95,9 @@ module ForemanRhCloud
82
95
 
83
96
  transformed_uri.to_s
84
97
  end
98
+
99
+ # For testing purposes we can override the default hostname with an environment variable SATELLITE_RH_CLOUD_FOREMAN_HOST
100
+ def self.foreman_host
101
+ @foreman_host ||= ::Host.unscoped.friendly.find(ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || ::SmartProxy.default_capsule.name)
102
+ end
85
103
  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
  },
@@ -78,7 +78,10 @@ module ForemanRhCloud
78
78
 
79
79
  register_global_js_file 'global'
80
80
 
81
- register_custom_status(InventorySync::InventoryStatus)
81
+ register_custom_status InventorySync::InventoryStatus
82
+ register_custom_status InsightsClientReportStatus
83
+
84
+ subscribe 'host_created.event.foreman', ForemanRhCloud::InsightsSubscriber
82
85
 
83
86
  extend_page 'hosts/show' do |context|
84
87
  context.add_pagelet :main_tabs,
@@ -87,6 +90,9 @@ module ForemanRhCloud
87
90
  id: 'insights',
88
91
  onlyif: proc { |host| host.insights }
89
92
  end
93
+
94
+ extend_template_helpers ForemanRhCloud::TemplateRendererHelper
95
+ allowed_template_helpers :remediations_playbook
90
96
  end
91
97
 
92
98
  ::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
@@ -114,5 +120,33 @@ module ForemanRhCloud
114
120
  locale_domain = 'foreman_rh_cloud'
115
121
  Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
116
122
  end
123
+
124
+ config.to_prepare do
125
+ # skip database manipulations while tables do not exist, like in migrations
126
+ if ActiveRecord::Base.connection.data_source_exists?(ForemanTasks::Task.table_name) &&
127
+
128
+ RemoteExecutionFeature.register(
129
+ :rh_cloud_remediate_hosts,
130
+ N_('Apply Insights recommendations'),
131
+ description: N_('Run remediation playbook generated by Insights'),
132
+ host_action_button: false
133
+ )
134
+ # skip object creation when admin user is not present, for example in test DB
135
+ if User.unscoped.find_by_login(User::ANONYMOUS_ADMIN).present?
136
+ ::ForemanTasks.dynflow.config.on_init(false) do |world|
137
+ unless ForemanTasks::RecurringLogic.joins(:tasks).merge(
138
+ ForemanTasks::Task.where(label: 'InventorySync::Async::InventoryScheduledSync')
139
+ ).exists?
140
+ User.as_anonymous_admin do
141
+ recurring_logic = ForemanTasks::RecurringLogic.new_from_cronline("0 0 * * *")
142
+ recurring_logic.save!
143
+ recurring_logic.start(InventorySync::Async::InventoryScheduledSync)
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+ rescue ActiveRecord::NoDatabaseError
150
+ end
117
151
  end
118
152
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '3.0.19'.freeze
2
+ VERSION = '4.0.22'.freeze
3
3
  end
@@ -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,24 @@ require 'rest-client'
2
2
 
3
3
  module InsightsCloud
4
4
  module Async
5
- class InsightsFullSync < ::ApplicationJob
5
+ class InsightsFullSync < ::Actions::EntryAction
6
6
  include ::ForemanRhCloud::CloudAuth
7
7
 
8
- def perform
9
- # This can be turned off when we enable automatic status syncs
10
- # This step will query cloud inventory to retrieve inventory uuids for each host
11
- ForemanTasks.sync_task(InventorySync::Async::InventoryHostsSync)
8
+ def plan
9
+ sequence do
10
+ # This can be turned off when we enable automatic status syncs
11
+ # This step will query cloud inventory to retrieve inventory uuids for each host
12
+ plan_hosts_sync
13
+ plan_self
14
+ concurrence do
15
+ plan_rules_sync
16
+ plan_notifications
17
+ end
18
+ end
19
+ end
12
20
 
21
+ def run
13
22
  perform_hits_sync
14
-
15
- InsightsRulesSync.perform_later
16
23
  end
17
24
 
18
25
  def perform_hits_sync
@@ -25,34 +32,36 @@ module InsightsCloud
25
32
  end
26
33
 
27
34
  def logger
28
- Foreman::Logging.logger('background')
35
+ action_logger
29
36
  end
30
37
 
31
38
  private
32
39
 
40
+ def plan_hosts_sync
41
+ plan_action InventorySync::Async::InventoryHostsSync
42
+ end
43
+
44
+ def plan_rules_sync
45
+ plan_action InsightsRulesSync
46
+ end
47
+
48
+ def plan_notifications
49
+ plan_action InsightsGenerateNotifications
50
+ end
51
+
33
52
  def query_insights_hits
34
- hits_response = RestClient::Request.execute(
53
+ hits_response = execute_cloud_request(
35
54
  method: :get,
36
- url: InsightsCloud.hits_export_url,
37
- verify_ssl: ForemanRhCloud.verify_ssl_method,
38
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
39
- headers: {
40
- Authorization: "Bearer #{rh_credentials}",
41
- }
55
+ url: InsightsCloud.hits_export_url
42
56
  )
43
57
 
44
58
  JSON.parse(hits_response)
45
59
  end
46
60
 
47
61
  def query_insights_rules
48
- rules_response = RestClient::Request.execute(
62
+ rules_response = execute_cloud_request(
49
63
  method: :get,
50
- url: InsightsCloud.rules_url,
51
- verify_ssl: ForemanRhCloud.verify_ssl_method,
52
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
53
- headers: {
54
- Authorization: "Bearer #{rh_credentials}",
55
- }
64
+ url: InsightsCloud.rules_url
56
65
  )
57
66
 
58
67
  JSON.parse(rules_response)
@@ -0,0 +1,58 @@
1
+ require 'rest-client'
2
+
3
+ module InsightsCloud
4
+ module Async
5
+ class InsightsGenerateNotifications < ::Actions::EntryAction
6
+ # cache blueprint on class level, so it won't be reloaded on subsequent calls
7
+ def self.blueprint
8
+ @blueprint ||= NotificationBlueprint.find_by(name: 'insights_satellite_hits')
9
+ end
10
+
11
+ def run
12
+ add_satellite_notifications
13
+ end
14
+
15
+ def add_satellite_notifications
16
+ hits_count = InsightsHit.where(host_id: foreman_host.id).count
17
+
18
+ # Remove stale notifications
19
+ blueprint.notifications.destroy_all
20
+
21
+ if hits_count > 0
22
+ add_notification(hits_count)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def logger
29
+ action_logger
30
+ end
31
+
32
+ def foreman_host
33
+ ForemanRhCloud.foreman_host
34
+ end
35
+
36
+ def blueprint
37
+ self.class.blueprint
38
+ end
39
+
40
+ def add_notification(hits_count)
41
+ Notification.create!(
42
+ initiator: User.anonymous_admin,
43
+ audience: ::Notification::AUDIENCE_ADMIN,
44
+ message: UINotifications::StringParser.new(blueprint.message, {hits_count: hits_count}).to_s,
45
+ notification_blueprint: blueprint,
46
+ actions: {
47
+ links: [
48
+ {
49
+ href: Rails.application.routes.url_helpers.foreman_rh_cloud_insights_cloud_path(search: "hostname=#{foreman_host.name}"),
50
+ title: _('Fix host'),
51
+ },
52
+ ],
53
+ }
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end