foreman_rh_cloud 5.0.35 → 5.0.38

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +1 -1
  3. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +0 -7
  4. data/app/controllers/foreman_inventory_upload/uploads_settings_controller.rb +0 -1
  5. data/app/controllers/insights_cloud/hits_controller.rb +0 -1
  6. data/app/controllers/insights_cloud/settings_controller.rb +0 -8
  7. data/app/controllers/insights_cloud/tasks_controller.rb +1 -1
  8. data/app/models/insights_facet.rb +1 -0
  9. data/app/models/insights_hit.rb +1 -0
  10. data/app/models/insights_rule.rb +2 -0
  11. data/app/models/setting/rh_cloud.rb +1 -2
  12. data/app/services/foreman_rh_cloud/cert_auth.rb +22 -0
  13. data/app/services/foreman_rh_cloud/cloud_connector.rb +10 -1
  14. data/app/services/foreman_rh_cloud/cloud_ping_service.rb +0 -27
  15. data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +4 -0
  16. data/app/services/foreman_rh_cloud/remediations_retriever.rb +7 -3
  17. data/app/services/foreman_rh_cloud/template_renderer_helper.rb +4 -3
  18. data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +6 -1
  19. data/app/views/job_templates/cloud_connector.erb +6 -0
  20. data/app/views/job_templates/rh_cloud_download_playbook.erb +5 -1
  21. data/config/routes.rb +0 -1
  22. data/db/migrate/20220321000001_add_unique_to_insights_rules.foreman_rh_cloud.rb +13 -0
  23. data/lib/foreman_inventory_upload.rb +1 -1
  24. data/lib/foreman_rh_cloud/engine.rb +1 -1
  25. data/lib/foreman_rh_cloud/version.rb +1 -1
  26. data/lib/foreman_rh_cloud.rb +0 -5
  27. data/lib/insights_cloud/async/cloud_connector_announce_task.rb +44 -0
  28. data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +7 -1
  29. data/lib/insights_cloud/async/insights_full_sync.rb +40 -24
  30. data/lib/insights_cloud/async/insights_resolutions_sync.rb +10 -13
  31. data/lib/insights_cloud/async/insights_rules_sync.rb +27 -19
  32. data/lib/insights_cloud/async/insights_scheduled_sync.rb +1 -1
  33. data/lib/insights_cloud.rb +4 -8
  34. data/lib/inventory_sync/async/host_result.rb +3 -2
  35. data/lib/inventory_sync/async/inventory_full_sync.rb +3 -3
  36. data/lib/inventory_sync/async/inventory_hosts_sync.rb +11 -10
  37. data/lib/inventory_sync/async/inventory_self_host_sync.rb +5 -6
  38. data/lib/inventory_sync/async/query_inventory_job.rb +40 -12
  39. data/lib/tasks/insights.rake +1 -1
  40. data/package.json +6 -6
  41. data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +0 -1
  42. data/test/controllers/inventory_upload/cloud_status_controller_test.rb +0 -6
  43. data/test/jobs/cloud_connector_announce_task_test.rb +125 -0
  44. data/test/jobs/insights_full_sync_test.rb +9 -5
  45. data/test/jobs/insights_resolutions_sync_test.rb +7 -1
  46. data/test/jobs/insights_rules_sync_test.rb +8 -4
  47. data/test/jobs/inventory_full_sync_test.rb +16 -5
  48. data/test/jobs/inventory_hosts_sync_test.rb +18 -4
  49. data/test/jobs/inventory_self_host_sync_test.rb +6 -1
  50. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +0 -1
  51. data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +1 -14
  52. data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +5 -1
  53. data/test/unit/services/foreman_rh_cloud/url_remediations_retriever_test.rb +3 -1
  54. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettingsSelectors.js +0 -2
  55. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +1 -10
  56. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +3 -12
  57. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +1 -1
  58. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +0 -4
  59. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/index.js +0 -2
  60. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +0 -3
  61. data/webpack/InsightsCloudSync/Components/InsightsTable/Pagination.js +16 -0
  62. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableSelectors.test.js +0 -2
  63. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableSelectors.test.js.snap +0 -2
  64. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/fixtures.js +0 -1
  65. data/webpack/InsightsCloudSync/InsightsCloudSync.js +1 -17
  66. data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +0 -7
  67. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +0 -4
  68. data/webpack/InsightsCloudSync/InsightsCloudSyncHelpers.js +0 -7
  69. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +0 -9
  70. data/webpack/InsightsCloudSync/index.js +1 -5
  71. metadata +7 -9
  72. data/app/services/foreman_rh_cloud/cloud_auth.rb +0 -44
  73. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.scss +0 -5
  74. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Modal.js +0 -63
  75. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/modal.scss +0 -20
  76. data/webpack/InsightsCloudSync/Components/NoTokenEmptyState.js +0 -79
  77. data/webpack/InsightsCloudSync/Components/__tests__/NoTokenEmptyState.test.js +0 -19
  78. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +0 -225
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 437d70d98a43e88f7835426bf1a8ae7995a2b759038e3a5908dc41e122544ed1
4
- data.tar.gz: a655276cda12b06662db3670019747c518e9204c22ca8ad3591024945dd48fb8
3
+ metadata.gz: 7bb7932e40d6ef999b5266897539d444e9ab7a38606e6f66dff58fb568d70fdc
4
+ data.tar.gz: f6e6a8ae8ddfb3544fbe31c807f9917fe7aa2d5d1d05014055528bb193290109
5
5
  SHA512:
6
- metadata.gz: 3d59ebbe9a845efd88c9d70f1d44ff9ebae7e5faabd947c3ba3d48e5f22435c97052be363839805208b381fea29f643a35ef241f2ff0ae462d1720d6ff5fd538
7
- data.tar.gz: f7d94f184cbeba9d50b6e8a83d71db08a3c6417972b6d51b6ca247558a4769a6f17fbfdae37f9e4f5efe2a73a8095885a44e109d2b736fbc1d824f9e68528fe1
6
+ metadata.gz: dcc37dffd7f108e1687b671ea0f5b157644c6a9576310d917daafefd4011ad01ccced6d48941823873a3da076ab20da2db33fe2c463cc0e962f69a79ea565400
7
+ data.tar.gz: 72f7a08cc3f30d0bddaaf63e0198df2761a40153c7185d1e30328a1c00b9496e7ce33b34ceec44ecf69989ab570001173524cfc49e5a9e127a540bf4684f9d02
@@ -40,7 +40,6 @@ module Api::V2::RhCloud
40
40
  end
41
41
 
42
42
  def handle_run_playbook_request
43
- logger.error("API token is not set, unable to fetch data from the cloud") && return if Setting[:rh_cloud_token].empty?
44
43
  logger.error("Playbook URL is not valid: #{content}") && return unless valid_url?(content)
45
44
  logger.error("Reporting URL is not valid: #{metadata['return_url']}") && return unless valid_url?(metadata['return_url'])
46
45
 
@@ -60,6 +59,7 @@ module Api::V2::RhCloud
60
59
  host_ids,
61
60
  {
62
61
  playbook_url: content,
62
+ organization_id: org_id,
63
63
  report_url: metadata['return_url'],
64
64
  report_interval: metadata['response_interval'].to_i,
65
65
  correlation_id: metadata['correlation_id'],
@@ -18,13 +18,6 @@ module ForemanInventoryUpload
18
18
  end
19
19
 
20
20
  def enable_cloud_connector
21
- Organization.unscoped.each do |org|
22
- presence = ForemanRhCloud::CloudPresence.new(org, logger)
23
- presence.announce_to_sources
24
- rescue StandardError => ex
25
- logger.warn(ex)
26
- end
27
-
28
21
  cloud_connector = ForemanRhCloud::CloudConnector.new
29
22
  render json: cloud_connector.install.to_json
30
23
  end
@@ -7,7 +7,6 @@ module ForemanInventoryUpload
7
7
  ipsObfuscationEnabled: Setting[:obfuscate_inventory_ips],
8
8
  excludePackagesEnabled: Setting[:exclude_installed_packages],
9
9
  CloudConnectorStatus: ForemanInventoryUpload::UploadsSettingsController.cloud_connector_status,
10
- cloudToken: !Setting[:rh_cloud_token].empty?,
11
10
  lastSyncTask: last_successful_inventory_sync_task,
12
11
  }, status: :ok
13
12
  end
@@ -6,7 +6,6 @@ module InsightsCloud
6
6
  hits = resource_base_search_and_page.preload(:host, :rule)
7
7
 
8
8
  render json: {
9
- hasToken: !Setting[:rh_cloud_token].empty?,
10
9
  hits: hits.map { |hit| hit.attributes.merge(hostname: hit.host&.name, has_playbook: hit.has_playbook?, host_uuid: hit.host_uuid) },
11
10
  itemCount: hits.count,
12
11
  }, status: :ok
@@ -9,14 +9,6 @@ module InsightsCloud
9
9
  render_setting(:insightsSyncEnabled, :allow_auto_insights_sync)
10
10
  end
11
11
 
12
- def save_token_and_sync
13
- token = Setting::RhCloud.find_by_name("rh_cloud_token")
14
- token.value = params.require(:value)
15
- token.save!
16
- ForemanTasks.sync_task(InsightsCloud::Async::InsightsFullSync)
17
- redirect_to(:controller => "hits", :action => 'index')
18
- end
19
-
20
12
  private
21
13
 
22
14
  def render_setting(node_name, setting)
@@ -1,7 +1,7 @@
1
1
  module InsightsCloud
2
2
  class TasksController < ::ApplicationController
3
3
  def create
4
- task = ForemanTasks.async_task(InsightsCloud::Async::InsightsFullSync)
4
+ task = ForemanTasks.async_task(InsightsCloud::Async::InsightsFullSync, Organization.authorized)
5
5
 
6
6
  render json: {
7
7
  task: task,
@@ -4,4 +4,5 @@ class InsightsFacet < HostFacets::Base
4
4
  primary_key: :host_id,
5
5
  class_name: 'InsightsHit',
6
6
  dependent: :destroy
7
+ scope :for_organizations, ->(organization_ids) { joins(:host).where(hosts: { organization_id: organization_ids}) }
7
8
  end
@@ -8,6 +8,7 @@ class InsightsHit < ApplicationRecord
8
8
  has_one :rule, class_name: 'InsightsRule', foreign_key: 'rule_id', primary_key: 'rule_id'
9
9
 
10
10
  scope :with_playbook, -> { joins(:rule) }
11
+ scope :for_organizations, ->(organization_ids) { joins(:host).where(hosts: { organization_id: organization_ids}) }
11
12
 
12
13
  scoped_search on: :title, complete_value: true
13
14
  scoped_search on: :total_risk, complete_value: true
@@ -1,3 +1,5 @@
1
1
  class InsightsRule < ApplicationRecord
2
2
  has_many :resolutions, class_name: 'InsightsResolution', dependent: :destroy, foreign_key: 'rule_id', primary_key: 'rule_id', inverse_of: :rule
3
+
4
+ has_many :hits, class_name: 'InsightsHit', foreign_key: 'rule_id', primary_key: 'rule_id', inverse_of: :rule
3
5
  end
@@ -1,5 +1,5 @@
1
1
  class Setting::RhCloud < Setting
2
- ::Setting::BLANK_ATTRS.concat %w{rh_cloud_token rhc_instance_id}
2
+ ::Setting::BLANK_ATTRS.concat %w{rhc_instance_id}
3
3
 
4
4
  def self.load_defaults
5
5
  return false unless table_exists?
@@ -17,7 +17,6 @@ class Setting::RhCloud < Setting
17
17
  set('allow_auto_insights_sync', N_('Enable automatic synchronization of Insights recommendations from the Red Hat cloud'), false, N_('Synchronize recommendations Automatically')),
18
18
  set('obfuscate_inventory_hostnames', N_('Obfuscate host names sent to the Red Hat cloud'), false, N_('Obfuscate host names')),
19
19
  set('obfuscate_inventory_ips', N_('Obfuscate ipv4 addresses sent to the Red Hat cloud'), false, N_('Obfuscate host ipv4 addresses')),
20
- 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),
21
20
  set('exclude_installed_packages', N_('Exclude installed packages from being uploaded to the Red Hat cloud'), false, N_("Exclude installed Packages")),
22
21
  set('include_parameter_tags', N_('Should import include parameter tags from Foreman?'), false, N_('Include parameters in insights-client reports')),
23
22
  set('rhc_instance_id', N_('RHC daemon id'), nil, N_('ID of the RHC(Yggdrasil) daemon')),
@@ -0,0 +1,22 @@
1
+ module ForemanRhCloud
2
+ module CertAuth
3
+ extend ActiveSupport::Concern
4
+
5
+ include CloudRequest
6
+ include InsightsCloud::CandlepinCache
7
+
8
+ def cert_auth_available?(organization)
9
+ !!candlepin_id_cert(organization)
10
+ end
11
+
12
+ def execute_cloud_request(params)
13
+ certs = candlepin_id_cert(params.delete(:organization))
14
+ final_params = {
15
+ ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
16
+ ssl_client_key: OpenSSL::PKey::RSA.new(certs[:key]),
17
+ }.deep_merge(params)
18
+
19
+ super(final_params)
20
+ end
21
+ end
22
+ end
@@ -12,11 +12,20 @@ module ForemanRhCloud
12
12
  target_host = foreman_host
13
13
  composer = nil
14
14
 
15
+ input = {
16
+ :satellite_cloud_connector_user => service_user.login,
17
+ :satellite_cloud_connector_password => token_value,
18
+ }
19
+
20
+ if (http_proxy = ForemanRhCloud.proxy_setting(logger: Foreman::Logging.logger('app')))
21
+ input[:satellite_cloud_connector_http_proxy] = http_proxy
22
+ end
23
+
15
24
  Taxonomy.as_taxonomy(target_host.organization, target_host.location) do
16
25
  composer = ::JobInvocationComposer.for_feature(
17
26
  CLOUD_CONNECTOR_FEATURE,
18
27
  [target_host.id],
19
- {:satellite_cloud_connector_user => service_user.login, :satellite_cloud_connector_password => token_value}
28
+ input
20
29
  )
21
30
  composer.trigger!
22
31
  end
@@ -2,28 +2,6 @@ require 'rest-client'
2
2
 
3
3
  module ForemanRhCloud
4
4
  class CloudPingService
5
- class TokenPing
6
- include ForemanRhCloud::CloudAuth
7
-
8
- attr_accessor :logger
9
-
10
- def initialize(logger)
11
- @logger = logger
12
- end
13
-
14
- def ping
15
- execute_cloud_request(
16
- method: :get,
17
- url: ForemanRhCloud.base_url + "/api/inventory/v1/hosts?per_page=1",
18
- headers: {
19
- content_type: :json,
20
- }
21
- )
22
- rescue StandardError => ex
23
- ex
24
- end
25
- end
26
-
27
5
  class CertPing
28
6
  include ForemanRhCloud::CloudRequest
29
7
  include InsightsCloud::CandlepinCache
@@ -62,12 +40,7 @@ module ForemanRhCloud
62
40
  end
63
41
 
64
42
  def ping
65
- token_response = TokenPing.new(@logger).ping
66
43
  {
67
- token_auth: {
68
- success: token_response.is_a?(RestClient::Response),
69
- error: (token_response.is_a?(Exception) ? token_response.inspect : nil),
70
- },
71
44
  cert_auth: Hash[
72
45
  @organizations.map do |org|
73
46
  cert_response = CertPing.new(org, @logger).ping
@@ -63,5 +63,9 @@ module ForemanRhCloud
63
63
  def method
64
64
  :post
65
65
  end
66
+
67
+ def organization
68
+ InsightsHit.find(@hit_remediation_pairs.first['hit_id']).host.organization
69
+ end
66
70
  end
67
71
  end
@@ -1,6 +1,6 @@
1
1
  module ForemanRhCloud
2
2
  class RemediationsRetriever
3
- include CloudAuth
3
+ include CertAuth
4
4
 
5
5
  attr_reader :logger
6
6
 
@@ -9,8 +9,8 @@ module ForemanRhCloud
9
9
  end
10
10
 
11
11
  def create_playbook
12
- unless cloud_auth_available?
13
- logger.debug('Cloud authentication is not available, cannot continue')
12
+ unless cert_auth_available?(organization)
13
+ logger.debug('Manifest is not available, cannot continue')
14
14
  return
15
15
  end
16
16
 
@@ -25,6 +25,7 @@ module ForemanRhCloud
25
25
 
26
26
  def query_playbook
27
27
  execute_cloud_request(
28
+ organization: organization,
28
29
  method: method,
29
30
  url: playbook_url,
30
31
  headers: headers,
@@ -47,5 +48,8 @@ module ForemanRhCloud
47
48
  def method
48
49
  :get
49
50
  end
51
+
52
+ def organization
53
+ end
50
54
  end
51
55
  end
@@ -20,11 +20,12 @@ module ForemanRhCloud
20
20
  end
21
21
 
22
22
  apipie :method, 'Returns a Red Hat remediation playbook compiled on console.redhat.com' do
23
- required :remediation_path, String, desc: ''
23
+ required :playbook_url, String, desc: 'URL of the playbook on console.redhat.com'
24
+ required :organization_id, Integer, desc: 'Id of the organization that owns the playbook'
24
25
  returns String, desc: 'Playbook downloaded from the cloud'
25
26
  end
26
- def download_rh_playbook(playbook_url)
27
- retriever = ForemanRhCloud::UrlRemediationsRetriever.new(url: playbook_url, logger: template_logger)
27
+ def download_rh_playbook(playbook_url, organization_id)
28
+ retriever = ForemanRhCloud::UrlRemediationsRetriever.new(url: playbook_url, organization_id: organization_id, logger: template_logger)
28
29
 
29
30
  cached("rh_playbook_#{playbook_url}") do
30
31
  retriever.create_playbook
@@ -2,12 +2,13 @@ module ForemanRhCloud
2
2
  class UrlRemediationsRetriever < RemediationsRetriever
3
3
  attr_reader :url, :payload, :headers
4
4
 
5
- def initialize(url:, payload: '', headers: {}, logger: Logger.new(IO::NULL))
5
+ def initialize(url:, organization_id:, payload: '', headers: {}, logger: Logger.new(IO::NULL))
6
6
  super(logger: logger)
7
7
 
8
8
  @url = url
9
9
  @payload = payload
10
10
  @headers = headers
11
+ @organization_id = organization_id
11
12
  end
12
13
 
13
14
  private
@@ -33,5 +34,9 @@ module ForemanRhCloud
33
34
  def method
34
35
  :get
35
36
  end
37
+
38
+ def organization
39
+ Organization.find(@organization_id)
40
+ end
36
41
  end
37
42
  end
@@ -14,6 +14,12 @@ template_inputs:
14
14
  advanced: false
15
15
  value_type: plain
16
16
  hidden_value: true
17
+ - name: satellite_cloud_connector_http_proxy
18
+ required: false
19
+ input_type: user
20
+ advanced: true
21
+ value_type: plain
22
+ hidden_value: false
17
23
  model: JobTemplate
18
24
  job_category: Maintenance Operations
19
25
  description_format: "%{template_name}"
@@ -9,6 +9,10 @@ template_inputs:
9
9
  description: URL of the playbook to run
10
10
  input_type: user
11
11
  required: true
12
+ - name: organization_id
13
+ description: Id of the organization that owns the playbook
14
+ input_type: user
15
+ required: true
12
16
  - name: report_url
13
17
  description: URL for calling the report callback
14
18
  input_type: user
@@ -23,4 +27,4 @@ template_inputs:
23
27
  required: true
24
28
  provider_type: Ansible
25
29
  %>
26
- <%= download_rh_playbook(input('playbook_url')) %>
30
+ <%= download_rh_playbook(input('playbook_url'), input('organization_id')) %>
data/config/routes.rb CHANGED
@@ -25,7 +25,6 @@ Rails.application.routes.draw do
25
25
  end
26
26
  end
27
27
  match 'hits/:host_id', to: 'hits#show', via: :get
28
- post 'save_token_and_sync', to: 'settings#save_token_and_sync'
29
28
  end
30
29
 
31
30
  namespace :foreman_rh_cloud do
@@ -0,0 +1,13 @@
1
+ class AddUniqueToInsightsRules < ActiveRecord::Migration[5.2]
2
+ def change
3
+ begin
4
+ # remove old index
5
+ remove_index :insights_rules, [:rule_id]
6
+ rescue ArgumentError
7
+ # noop, if the index is not there, it's OK.
8
+ end
9
+
10
+ # add unique constraint
11
+ add_index :insights_rules, [:rule_id], unique: true
12
+ end
13
+ end
@@ -71,7 +71,7 @@ module ForemanInventoryUpload
71
71
  end
72
72
 
73
73
  def self.inventory_base_url
74
- ForemanRhCloud.base_url + "/api/inventory/v1/hosts"
74
+ ForemanRhCloud.cert_base_url + "/api/inventory/v1/hosts"
75
75
  end
76
76
 
77
77
  def self.inventory_export_url
@@ -56,7 +56,7 @@ module ForemanRhCloud
56
56
  'api/v2/rh_cloud/inventory': [:sync_inventory_status, :download_file, :generate_report, :enable_cloud_connector],
57
57
  'foreman_inventory_upload/uploads': [:enable_cloud_connector],
58
58
  'foreman_inventory_upload/uploads_settings': [:set_advanced_setting],
59
- 'insights_cloud/settings': [:save_token_and_sync, :update],
59
+ 'insights_cloud/settings': [:update],
60
60
  'insights_cloud/tasks': [:create]
61
61
  )
62
62
  permission(
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '5.0.35'.freeze
2
+ VERSION = '5.0.38'.freeze
3
3
  end
@@ -16,11 +16,6 @@ module ForemanRhCloud
16
16
  @legacy_insights_url ||= ENV['SATELLITE_LEGACY_INSIGHTS_URL'] || 'https://cert-api.access.redhat.com'
17
17
  end
18
18
 
19
- def self.authentication_url
20
- # https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
21
- @authentication_url ||= ENV['SATELLITE_RH_CLOUD_SSO_URL'] || 'https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token'
22
- end
23
-
24
19
  def self.verify_ssl_method
25
20
  @verify_ssl_method ||= ENV['SATELLITE_RH_CLOUD_URL'] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
26
21
  end
@@ -0,0 +1,44 @@
1
+ module InsightsCloud
2
+ module Async
3
+ class CloudConnectorAnnounceTask < ::Actions::EntryAction
4
+ def self.subscribe
5
+ Actions::RemoteExecution::RunHostsJob
6
+ end
7
+
8
+ def self.connector_feature_id
9
+ @connector_feature_id ||= RemoteExecutionFeature.feature!(ForemanRhCloud::CloudConnector::CLOUD_CONNECTOR_FEATURE).id
10
+ end
11
+
12
+ def plan(job_invocation)
13
+ return unless connector_playbook_job?(job_invocation)
14
+
15
+ plan_self
16
+ end
17
+
18
+ def finalize
19
+ Organization.unscoped.each do |org|
20
+ presence = ForemanRhCloud::CloudPresence.new(org, logger)
21
+ presence.announce_to_sources
22
+ rescue StandardError => ex
23
+ logger.warn(ex)
24
+ end
25
+ end
26
+
27
+ def rescue_strategy_for_self
28
+ Dynflow::Action::Rescue::Skip
29
+ end
30
+
31
+ def connector_playbook_job?(job_invocation)
32
+ job_invocation&.remote_execution_feature_id == connector_feature_id
33
+ end
34
+
35
+ def connector_feature_id
36
+ self.class.connector_feature_id
37
+ end
38
+
39
+ def logger
40
+ action_logger
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,7 +2,7 @@ module InsightsCloud
2
2
  module Async
3
3
  class ConnectorPlaybookExecutionReporterTask < ::Actions::EntryAction
4
4
  include Dynflow::Action::Polling
5
- include ForemanRhCloud::CloudAuth
5
+ include ForemanRhCloud::CertAuth
6
6
 
7
7
  def self.subscribe
8
8
  Actions::RemoteExecution::RunHostsJob
@@ -23,6 +23,7 @@ module InsightsCloud
23
23
  correlation_id = invocation_inputs['correlation_id']
24
24
 
25
25
  plan_self(
26
+ current_org_id: job_invocation.targeted_hosts.first.organization_id,
26
27
  report_url: report_url,
27
28
  report_interval: report_interval,
28
29
  job_invocation_id: job_invocation.id,
@@ -159,6 +160,7 @@ module InsightsCloud
159
160
 
160
161
  def send_report(report)
161
162
  execute_cloud_request(
163
+ organization: current_org,
162
164
  method: :post,
163
165
  url: report_url,
164
166
  content_type: 'application/vnd.redhat.playbook-sat.v3+jsonl',
@@ -188,6 +190,10 @@ module InsightsCloud
188
190
  def logger
189
191
  action_logger
190
192
  end
193
+
194
+ def current_org
195
+ Organization.find(input[:current_org_id])
196
+ end
191
197
  end
192
198
  end
193
199
  end
@@ -3,37 +3,48 @@ require 'rest-client'
3
3
  module InsightsCloud
4
4
  module Async
5
5
  class InsightsFullSync < ::Actions::EntryAction
6
- include ::ForemanRhCloud::CloudAuth
7
-
8
- def plan
9
- unless cloud_auth_available?
10
- logger.debug('Cloud authentication is not available, skipping insights sync')
11
- return
6
+ include ::ForemanRhCloud::CertAuth
7
+
8
+ def plan(organizations)
9
+ organizations = organizations.select do |organization|
10
+ if cert_auth_available?(organization)
11
+ true
12
+ else
13
+ logger.debug("Certificate is not available for org: #{organization.name}, skipping insights sync")
14
+ false
15
+ end
12
16
  end
13
17
 
14
18
  sequence do
15
19
  # This can be turned off when we enable automatic status syncs
16
20
  # This step will query cloud inventory to retrieve inventory uuids for each host
17
- plan_hosts_sync
18
- plan_self
21
+ plan_hosts_sync(organizations)
22
+ plan_self(organization_ids: organizations.map(&:id))
19
23
  concurrence do
20
- plan_rules_sync
24
+ plan_rules_sync(organizations)
21
25
  plan_notifications
22
26
  end
23
27
  end
24
28
  end
25
29
 
26
30
  def run
27
- perform_hits_sync
31
+ organizations.each do |organization|
32
+ unless cert_auth_available?(organization)
33
+ logger.debug("Certificate is not available for org: #{organization.name}, skipping insights sync")
34
+ next
35
+ end
36
+
37
+ perform_hits_sync(organization)
38
+ end
28
39
  end
29
40
 
30
- def perform_hits_sync
31
- hits = query_insights_hits
41
+ def perform_hits_sync(organization)
42
+ hits = query_insights_hits(organization)
32
43
 
33
44
  uuids = hits.map { |hit| hit['uuid'] }
34
- setup_host_ids(uuids)
45
+ setup_host_ids(uuids, organization)
35
46
 
36
- replace_hits_data(hits)
47
+ replace_hits_data(hits, organization)
37
48
  end
38
49
 
39
50
  def logger
@@ -42,20 +53,21 @@ module InsightsCloud
42
53
 
43
54
  private
44
55
 
45
- def plan_hosts_sync
46
- plan_action InventorySync::Async::InventoryHostsSync
56
+ def plan_hosts_sync(organizations)
57
+ plan_action(InventorySync::Async::InventoryHostsSync, organizations)
47
58
  end
48
59
 
49
- def plan_rules_sync
50
- plan_action InsightsRulesSync
60
+ def plan_rules_sync(organizations)
61
+ plan_action(InsightsRulesSync, organizations)
51
62
  end
52
63
 
53
64
  def plan_notifications
54
65
  plan_action InsightsGenerateNotifications
55
66
  end
56
67
 
57
- def query_insights_hits
68
+ def query_insights_hits(organization)
58
69
  hits_response = execute_cloud_request(
70
+ organization: organization,
59
71
  method: :get,
60
72
  url: InsightsCloud.hits_export_url
61
73
  )
@@ -72,9 +84,9 @@ module InsightsCloud
72
84
  JSON.parse(rules_response)
73
85
  end
74
86
 
75
- def setup_host_ids(uuids)
87
+ def setup_host_ids(uuids, organization)
76
88
  @host_ids = Hash[
77
- InsightsFacet.where(uuid: uuids).pluck(:uuid, :host_id)
89
+ InsightsFacet.for_organizations(organization.id).where(uuid: uuids).pluck(:uuid, :host_id)
78
90
  ]
79
91
  end
80
92
 
@@ -82,11 +94,11 @@ module InsightsCloud
82
94
  @host_ids[uuid]
83
95
  end
84
96
 
85
- def replace_hits_data(hits)
97
+ def replace_hits_data(hits, organization)
86
98
  InsightsHit.transaction do
87
99
  # Reset hit counters to 0, they will be recreated later
88
- InsightsFacet.unscoped.update_all(hits_count: 0)
89
- InsightsHit.delete_all
100
+ InsightsFacet.for_organizations(organization.id).update_all(hits_count: 0)
101
+ InsightsHit.for_organizations(organization.id).delete_all
90
102
  InsightsHit.create(hits.map { |hits_hash| to_model_hash(hits_hash) }.compact)
91
103
  end
92
104
  end
@@ -122,6 +134,10 @@ module InsightsCloud
122
134
  def rescue_strategy_for_self
123
135
  Dynflow::Action::Rescue::Fail
124
136
  end
137
+
138
+ def organizations
139
+ @organizations ||= Organization.where(id: input[:organization_ids])
140
+ end
125
141
  end
126
142
  end
127
143
  end
@@ -3,25 +3,20 @@ require 'rest-client'
3
3
  module InsightsCloud
4
4
  module Async
5
5
  class InsightsResolutionsSync < ::Actions::EntryAction
6
- include ::ForemanRhCloud::CloudAuth
6
+ include ::ForemanRhCloud::CertAuth
7
7
 
8
8
  RULE_ID_REGEX = /[^:]*:(?<id>.*)/
9
9
 
10
- def plan
11
- unless cloud_auth_available?
12
- logger.debug('Cloud authentication is not available, skipping resolutions sync')
13
- return
14
- end
15
-
16
- plan_self
17
- end
18
-
19
10
  def run
20
11
  InsightsResolution.transaction do
21
12
  InsightsResolution.delete_all
22
13
  rule_ids = relevant_rules
23
- api_response = query_insights_resolutions(rule_ids) unless rule_ids.empty?
24
- write_resolutions(api_response) if api_response
14
+ Organization.all.each do |organization|
15
+ next if !cert_auth_available?(organization) || organization.manifest_expired?
16
+ api_response = query_insights_resolutions(rule_ids, organization) unless rule_ids.empty?
17
+ written_rules = write_resolutions(api_response) if api_response
18
+ rule_ids -= Array(written_rules)
19
+ end
25
20
  end
26
21
  end
27
22
 
@@ -31,8 +26,9 @@ module InsightsCloud
31
26
 
32
27
  private
33
28
 
34
- def query_insights_resolutions(rule_ids)
29
+ def query_insights_resolutions(rule_ids, organization)
35
30
  resolutions_response = execute_cloud_request(
31
+ organization: organization,
36
32
  method: :post,
37
33
  url: InsightsCloud.resolutions_url,
38
34
  headers: {
@@ -66,6 +62,7 @@ module InsightsCloud
66
62
  end.flatten
67
63
 
68
64
  InsightsResolution.create(all_resolutions)
65
+ response.keys
69
66
  end
70
67
 
71
68
  def to_rule_id(resolution_rule_id)