foreman_rh_cloud 5.0.34 → 5.0.37
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_settings_controller.rb +0 -1
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +7 -1
- data/app/controllers/insights_cloud/hits_controller.rb +0 -1
- data/app/controllers/insights_cloud/settings_controller.rb +0 -8
- data/app/controllers/insights_cloud/tasks_controller.rb +1 -1
- data/app/models/insights_facet.rb +1 -0
- data/app/models/insights_hit.rb +1 -0
- data/app/models/insights_rule.rb +2 -0
- data/app/models/setting/rh_cloud.rb +1 -2
- data/app/services/foreman_rh_cloud/cert_auth.rb +22 -0
- data/app/services/foreman_rh_cloud/cloud_connector.rb +10 -1
- data/app/services/foreman_rh_cloud/cloud_ping_service.rb +0 -27
- data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +4 -0
- data/app/services/foreman_rh_cloud/remediations_retriever.rb +7 -3
- data/app/services/foreman_rh_cloud/template_renderer_helper.rb +4 -3
- data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +6 -1
- data/app/views/job_templates/cloud_connector.erb +6 -0
- data/app/views/job_templates/rh_cloud_download_playbook.erb +5 -1
- data/config/routes.rb +0 -1
- data/db/migrate/20220321000001_add_unique_to_insights_rules.foreman_rh_cloud.rb +13 -0
- data/lib/foreman_inventory_upload.rb +1 -1
- data/lib/foreman_rh_cloud/engine.rb +14 -11
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +0 -5
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +7 -1
- data/lib/insights_cloud/async/insights_full_sync.rb +40 -24
- data/lib/insights_cloud/async/insights_resolutions_sync.rb +10 -13
- data/lib/insights_cloud/async/insights_rules_sync.rb +27 -19
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +5 -1
- data/lib/insights_cloud.rb +4 -8
- data/lib/inventory_sync/async/host_result.rb +3 -2
- data/lib/inventory_sync/async/inventory_full_sync.rb +3 -3
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +11 -10
- data/lib/inventory_sync/async/inventory_self_host_sync.rb +5 -6
- data/lib/inventory_sync/async/query_inventory_job.rb +40 -12
- data/lib/tasks/insights.rake +1 -1
- data/package.json +1 -1
- data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +0 -1
- data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +16 -0
- data/test/controllers/inventory_upload/cloud_status_controller_test.rb +0 -6
- data/test/jobs/insights_full_sync_test.rb +9 -5
- data/test/jobs/insights_resolutions_sync_test.rb +7 -1
- data/test/jobs/insights_rules_sync_test.rb +8 -4
- data/test/jobs/inventory_full_sync_test.rb +16 -5
- data/test/jobs/inventory_hosts_sync_test.rb +18 -4
- data/test/jobs/inventory_self_host_sync_test.rb +6 -1
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +12 -8
- data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +1 -14
- data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +5 -1
- data/test/unit/services/foreman_rh_cloud/url_remediations_retriever_test.rb +3 -1
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettingsSelectors.js +0 -2
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +1 -10
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +3 -12
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +1 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +0 -4
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/index.js +0 -2
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +0 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/Pagination.js +16 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableSelectors.test.js +0 -2
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableSelectors.test.js.snap +0 -2
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/fixtures.js +0 -1
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +1 -17
- data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +0 -7
- data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +0 -4
- data/webpack/InsightsCloudSync/InsightsCloudSyncHelpers.js +0 -7
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +0 -9
- data/webpack/InsightsCloudSync/index.js +1 -5
- metadata +11 -17
- data/app/services/foreman_rh_cloud/cloud_auth.rb +0 -44
- data/config/package-lock.json +0 -41822
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.scss +0 -5
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Modal.js +0 -63
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/modal.scss +0 -20
- data/webpack/InsightsCloudSync/Components/NoTokenEmptyState.js +0 -79
- data/webpack/InsightsCloudSync/Components/__tests__/NoTokenEmptyState.test.js +0 -19
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b1fcbb6ac1367f8d83a29a6723c9244314b70cd3d8fb675747cdf44ae312a27
|
4
|
+
data.tar.gz: c9adec3a0002212f49e8ab7a30e793431809076e9b204a43725001b0a9e391ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db98fee746e070be33b584993e56479290df9b462ab9277a66f43c3b5c0af37a9ba3a765f66c4d3fc03f114d300b4ce206db3a8228e0417544c9a092f0e25e23
|
7
|
+
data.tar.gz: '09dd3108525df34ef72654cf8f9030af5fc2a6996b806d78b026e56d493b3d49cb5794852733b63dd500102878049e6e4e9f96d16428aa52f55ad8c1c727a610'
|
@@ -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'],
|
@@ -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
|
@@ -49,7 +49,13 @@ module InsightsCloud::Api
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def branch_info
|
52
|
-
|
52
|
+
payload = nil
|
53
|
+
|
54
|
+
User.as_anonymous_admin do
|
55
|
+
payload = ForemanRhCloud::BranchInfo.new.generate(@uuid, @host, @branch_id, request.host).to_json
|
56
|
+
end
|
57
|
+
|
58
|
+
render :json => payload
|
53
59
|
end
|
54
60
|
|
55
61
|
def assign_header(res, cloud_res, header, transform)
|
@@ -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,
|
data/app/models/insights_hit.rb
CHANGED
@@ -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
|
data/app/models/insights_rule.rb
CHANGED
@@ -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{
|
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
|
-
|
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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ForemanRhCloud
|
2
2
|
class RemediationsRetriever
|
3
|
-
include
|
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
|
13
|
-
logger.debug('
|
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 :
|
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
@@ -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
|
@@ -6,15 +6,18 @@ module ForemanRhCloud
|
|
6
6
|
engine_name 'foreman_rh_cloud'
|
7
7
|
|
8
8
|
def self.register_scheduled_task(task_class, cronline)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
ForemanTasks::RecurringLogic.transaction(isolation: :serializable) do
|
10
|
+
return if ForemanTasks::RecurringLogic.joins(:tasks)
|
11
|
+
.merge(ForemanTasks::Task.where(label: task_class.name))
|
12
|
+
.exists?
|
13
|
+
|
14
|
+
User.as_anonymous_admin do
|
15
|
+
recurring_logic = ForemanTasks::RecurringLogic.new_from_cronline(cronline)
|
16
|
+
recurring_logic.save!
|
17
|
+
recurring_logic.start(task_class)
|
18
|
+
end
|
17
19
|
end
|
20
|
+
rescue ActiveRecord::TransactionIsolationError
|
18
21
|
end
|
19
22
|
|
20
23
|
initializer 'foreman_rh_cloud.load_default_settings', :before => :load_config_initializers do
|
@@ -53,7 +56,7 @@ module ForemanRhCloud
|
|
53
56
|
'api/v2/rh_cloud/inventory': [:sync_inventory_status, :download_file, :generate_report, :enable_cloud_connector],
|
54
57
|
'foreman_inventory_upload/uploads': [:enable_cloud_connector],
|
55
58
|
'foreman_inventory_upload/uploads_settings': [:set_advanced_setting],
|
56
|
-
'insights_cloud/settings': [:
|
59
|
+
'insights_cloud/settings': [:update],
|
57
60
|
'insights_cloud/tasks': [:create]
|
58
61
|
)
|
59
62
|
permission(
|
@@ -140,9 +143,9 @@ module ForemanRhCloud
|
|
140
143
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
141
144
|
end
|
142
145
|
|
143
|
-
|
146
|
+
initializer 'foreman_rh_cloud.register_rex_features', :before => :finisher_hook do |_app|
|
144
147
|
# skip database manipulations while tables do not exist, like in migrations
|
145
|
-
if ActiveRecord::Base.connection.data_source_exists?(ForemanTasks::Task.table_name)
|
148
|
+
if ActiveRecord::Base.connection.data_source_exists?(ForemanTasks::Task.table_name)
|
146
149
|
RemoteExecutionFeature.register(
|
147
150
|
:rh_cloud_remediate_hosts,
|
148
151
|
N_('Apply Insights recommendations'),
|
data/lib/foreman_rh_cloud.rb
CHANGED
@@ -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
|
@@ -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::
|
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::
|
7
|
-
|
8
|
-
def plan
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
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
|
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
|
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.
|
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::
|
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
|
-
|
24
|
-
|
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)
|