foreman_rh_cloud 12.2.16 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/foreman_rh_cloud/locale/fr/foreman_rh_cloud.js +24 -78
- data/app/assets/javascripts/foreman_rh_cloud/locale/ja/foreman_rh_cloud.js +24 -78
- data/app/assets/javascripts/foreman_rh_cloud/locale/ka/foreman_rh_cloud.js +23 -77
- data/app/assets/javascripts/foreman_rh_cloud/locale/ko/foreman_rh_cloud.js +23 -77
- data/app/assets/javascripts/foreman_rh_cloud/locale/zh_CN/foreman_rh_cloud.js +23 -77
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +3 -5
- data/app/controllers/foreman_inventory_upload/accounts_controller.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +1 -1
- data/app/controllers/insights_cloud/ui_requests_controller.rb +3 -2
- data/app/models/concerns/rh_cloud_host.rb +0 -14
- data/app/models/foreman_rh_cloud/ping.rb +1 -2
- data/app/models/insights_hit.rb +1 -1
- data/app/services/foreman_rh_cloud/cert_auth.rb +3 -13
- data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +1 -3
- data/app/services/foreman_rh_cloud/tags_auth.rb +4 -15
- data/app/views/api/v2/advisor_engine/host_details.json.rabl +3 -1
- data/app/views/api/v2/hosts/insights/base.rabl +2 -3
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +8 -13
- data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +26 -4
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +96 -0
- data/lib/foreman_inventory_upload/generators/fact_helpers.rb +2 -2
- data/lib/foreman_inventory_upload/generators/slice.rb +3 -3
- data/lib/foreman_inventory_upload/scripts/uploader.sh.erb +49 -0
- data/lib/foreman_inventory_upload.rb +6 -6
- data/lib/foreman_rh_cloud/engine.rb +15 -34
- data/lib/foreman_rh_cloud/plugin.rb +13 -20
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +3 -3
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +3 -3
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
- data/lib/tasks/rh_cloud_inventory.rake +31 -14
- data/locale/foreman_rh_cloud.pot +157 -261
- data/locale/fr/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/fr/foreman_rh_cloud.po +26 -79
- data/locale/ja/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ja/foreman_rh_cloud.po +26 -79
- data/locale/ka/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ka/foreman_rh_cloud.po +24 -77
- data/locale/ko/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ko/foreman_rh_cloud.po +25 -78
- data/locale/zh_CN/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/zh_CN/foreman_rh_cloud.po +25 -78
- data/package.json +1 -1
- data/test/controllers/accounts_controller_test.rb +1 -1
- data/test/controllers/insights_cloud/api/advisor_engine_controller_test.rb +1 -28
- data/test/controllers/insights_cloud/ui_requests_controller_test.rb +0 -26
- data/test/controllers/uploads_controller_test.rb +1 -1
- data/test/factories/insights_factories.rb +0 -29
- data/test/jobs/cloud_connector_announce_task_test.rb +2 -3
- data/test/jobs/connector_playbook_execution_reporter_task_test.rb +20 -32
- data/test/jobs/exponential_backoff_test.rb +8 -9
- data/test/jobs/insights_client_status_aging_test.rb +2 -3
- data/test/jobs/insights_full_sync_test.rb +7 -13
- data/test/jobs/insights_resolutions_sync_test.rb +5 -9
- data/test/jobs/insights_rules_sync_test.rb +3 -5
- data/test/jobs/inventory_full_sync_test.rb +5 -9
- data/test/jobs/inventory_hosts_sync_test.rb +6 -11
- data/test/jobs/inventory_scheduled_sync_test.rb +6 -10
- data/test/jobs/inventory_self_host_sync_test.rb +1 -1
- data/test/jobs/remove_insights_hosts_job_test.rb +15 -14
- data/test/jobs/upload_report_job_test.rb +36 -0
- data/test/unit/fact_helpers_test.rb +0 -47
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +0 -14
- data/test/unit/slice_generator_test.rb +0 -57
- data/webpack/ForemanColumnExtensions/index.js +0 -2
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +17 -24
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js +8 -178
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +36 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +1 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +1 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/ToolbarButtons.test.js +51 -69
- data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +1 -1
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +1 -1
- data/webpack/ForemanRhCloudFills.js +2 -6
- data/webpack/ForemanRhCloudHelpers.js +0 -4
- data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +3 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +9 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +4 -24
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +112 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +2 -2
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +0 -10
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +1 -1
- data/webpack/InsightsHostDetailsTab/InsightsTab.scss +0 -4
- data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +23 -59
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +19 -6
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +2 -8
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +4 -105
- data/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js +3 -0
- data/webpack/__tests__/ForemanRhCloudHelpers.test.js +1 -16
- data/webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap +0 -6
- data/webpack/common/Hooks/ConfigHooks.js +16 -3
- metadata +12 -31
- data/app/controllers/concerns/foreman_rh_cloud/registration_manager_extensions.rb +0 -39
- data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +0 -30
- data/lib/foreman_inventory_upload/async/generate_host_report.rb +0 -20
- data/lib/foreman_inventory_upload/async/host_inventory_report_job.rb +0 -39
- data/lib/foreman_inventory_upload/async/single_host_report_job.rb +0 -20
- data/lib/foreman_inventory_upload/async/upload_report_direct_job.rb +0 -200
- data/test/jobs/create_missing_insights_facets_test.rb +0 -151
- data/test/jobs/generate_host_report_test.rb +0 -100
- data/test/jobs/generate_report_job_test.rb +0 -146
- data/test/jobs/host_inventory_report_job_test.rb +0 -244
- data/test/jobs/queue_for_upload_job_test.rb +0 -54
- data/test/jobs/single_host_report_job_test.rb +0 -155
- data/test/jobs/upload_report_direct_job_test.rb +0 -399
- data/test/unit/foreman_rh_cloud_iop_metadata_test.rb +0 -200
- data/test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb +0 -154
- data/test/unit/rh_cloud_host_test.rb +0 -191
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTotalRiskChart.test.js +0 -194
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module ForemanRhCloud
|
|
2
|
-
module RegistrationManagerExtensions
|
|
3
|
-
include ForemanRhCloud::CertAuth
|
|
4
|
-
|
|
5
|
-
def logger
|
|
6
|
-
Rails.logger
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def unregister_host(host, options = {})
|
|
10
|
-
organization_destroy = options.fetch(:organization_destroy, false)
|
|
11
|
-
|
|
12
|
-
# Reload to ensure we have fresh association data
|
|
13
|
-
host.reload
|
|
14
|
-
|
|
15
|
-
# Only delete from HBI in IoP mode (hosted mode uses async job for cleanup)
|
|
16
|
-
hbi_host_destroy(host) if ForemanRhCloud.with_iop_smart_proxy? && !organization_destroy && host.insights_uuid.presence
|
|
17
|
-
host.insights&.destroy!
|
|
18
|
-
super(host, options)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def hbi_host_destroy(host)
|
|
22
|
-
uuid = host.insights_uuid
|
|
23
|
-
logger.debug "Unregistering host #{uuid} from HBI"
|
|
24
|
-
execute_cloud_request(
|
|
25
|
-
organization: host.organization,
|
|
26
|
-
method: :delete,
|
|
27
|
-
url: ForemanInventoryUpload.host_by_id_url(uuid),
|
|
28
|
-
headers: {
|
|
29
|
-
content_type: :json,
|
|
30
|
-
}
|
|
31
|
-
)
|
|
32
|
-
rescue RestClient::NotFound
|
|
33
|
-
Rails.logger.warn(_("Attempted to destroy HBI host %s, but host does not exist in HBI") % uuid)
|
|
34
|
-
rescue StandardError => e
|
|
35
|
-
# TODO: Improve error handling - don't break registration if HBI delete fails
|
|
36
|
-
Rails.logger.error(format(_("Failed to destroy HBI host %s: %s"), uuid, e.message))
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class CreateMissingInsightsFacets < ::Actions::EntryAction
|
|
4
|
-
def plan(organization_id)
|
|
5
|
-
plan_self(organization_id: organization_id)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def run
|
|
9
|
-
organization = ::Organization.find(input[:organization_id])
|
|
10
|
-
hosts_without_facets = ::ForemanInventoryUpload::Generators::Queries.for_org(organization, hosts_query: 'null? insights_uuid')
|
|
11
|
-
facet_count = 0
|
|
12
|
-
hosts_without_facets.each do |batch|
|
|
13
|
-
facets = batch.pluck(:id, 'katello_subscription_facets.uuid').map do |host_id, uuid|
|
|
14
|
-
{
|
|
15
|
-
host_id: host_id,
|
|
16
|
-
uuid: uuid,
|
|
17
|
-
}
|
|
18
|
-
end
|
|
19
|
-
# We don't need to validate the facets here as we create the necessary fields.
|
|
20
|
-
# rubocop:disable Rails/SkipsModelValidations
|
|
21
|
-
InsightsFacet.upsert_all(facets, unique_by: :host_id) unless facets.empty?
|
|
22
|
-
# rubocop:enable Rails/SkipsModelValidations
|
|
23
|
-
facet_count += facets.size
|
|
24
|
-
end
|
|
25
|
-
output[:result] = facet_count.zero? ? _("There were no missing Insights facets") : format(_("Missing Insights facets created: %s"), facet_count)
|
|
26
|
-
Rails.logger.debug output[:result]
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class GenerateHostReport < ::Actions::EntryAction
|
|
4
|
-
def plan(base_folder, organization_id, filter)
|
|
5
|
-
plan_self(
|
|
6
|
-
base_folder: base_folder,
|
|
7
|
-
organization_id: organization_id,
|
|
8
|
-
filter: filter
|
|
9
|
-
)
|
|
10
|
-
input[:target] = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(input[:organization_id], input[:filter]))
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def run
|
|
14
|
-
archived_report_generator = ForemanInventoryUpload::Generators::ArchivedReport.new(input[:target])
|
|
15
|
-
archived_report_generator.render(organization: input[:organization_id], filter: input[:filter])
|
|
16
|
-
output[:result] = "Generated #{input[:target]} for organization id #{input[:organization_id]}"
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class HostInventoryReportJob < ::Actions::EntryAction
|
|
4
|
-
def plan(base_folder, organization_id, hosts_filter = "", upload = true)
|
|
5
|
-
sequence do
|
|
6
|
-
plan_action(
|
|
7
|
-
GenerateHostReport,
|
|
8
|
-
base_folder,
|
|
9
|
-
organization_id,
|
|
10
|
-
hosts_filter
|
|
11
|
-
)
|
|
12
|
-
if upload
|
|
13
|
-
plan_action(
|
|
14
|
-
QueueForUploadJob,
|
|
15
|
-
base_folder,
|
|
16
|
-
ForemanInventoryUpload.facts_archive_name(organization_id, hosts_filter),
|
|
17
|
-
organization_id
|
|
18
|
-
)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
if ForemanRhCloud.with_iop_smart_proxy?
|
|
22
|
-
plan_action(
|
|
23
|
-
CreateMissingInsightsFacets,
|
|
24
|
-
organization_id
|
|
25
|
-
)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def humanized_name
|
|
31
|
-
_("Host inventory report job")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def organization_id
|
|
35
|
-
input[:organization_id]
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module ForemanInventoryUpload
|
|
2
|
-
module Async
|
|
3
|
-
class SingleHostReportJob < HostInventoryReportJob
|
|
4
|
-
def plan(base_folder, organization_id, host_id)
|
|
5
|
-
input[:host_id] = host_id
|
|
6
|
-
super(base_folder, organization_id, "id=#{input[:host_id]}")
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def hostname(host_id)
|
|
10
|
-
host = ::Host.find_by(id: host_id)
|
|
11
|
-
host&.name
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def humanized_name
|
|
15
|
-
hostname_result = hostname(input[:host_id])
|
|
16
|
-
hostname_result.present? ? format(_("Single-host report job for host %s"), hostname_result) : _("Single-host report job")
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
require 'tempfile'
|
|
2
|
-
require 'rest-client'
|
|
3
|
-
|
|
4
|
-
module ForemanInventoryUpload
|
|
5
|
-
module Async
|
|
6
|
-
class UploadReportDirectJob < ::Actions::EntryAction
|
|
7
|
-
include AsyncHelpers
|
|
8
|
-
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
9
|
-
include ::ForemanRhCloud::CloudRequest
|
|
10
|
-
|
|
11
|
-
# Wrapper class to avoid monkey-patching File for multipart uploads
|
|
12
|
-
class FileUpload
|
|
13
|
-
attr_reader :file, :content_type
|
|
14
|
-
|
|
15
|
-
def initialize(file, content_type:)
|
|
16
|
-
@file = file
|
|
17
|
-
@content_type = content_type
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def read(*args)
|
|
21
|
-
@file.read(*args)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def path
|
|
25
|
-
@file.path
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def respond_to_missing?(method_name, include_private = false)
|
|
29
|
-
@file.respond_to?(method_name, include_private) || super
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def method_missing(method_name, *args, &block)
|
|
33
|
-
if @file.respond_to?(method_name)
|
|
34
|
-
@file.send(method_name, *args, &block)
|
|
35
|
-
else
|
|
36
|
-
super
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.output_label(label)
|
|
42
|
-
"upload_for_#{label}"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def plan(filename, organization_id)
|
|
46
|
-
# NOTE: This implementation assumes a single organization will not trigger multiple
|
|
47
|
-
# concurrent uploads. The instance_label is derived from organization_id alone, which
|
|
48
|
-
# means concurrent uploads for the same org would share ProgressOutput storage.
|
|
49
|
-
# This matches the pattern in GenerateReportJob. A full fix for thread-safety
|
|
50
|
-
# requires UI changes to display multiple concurrent tasks per org (tracked for PR #2).
|
|
51
|
-
label = UploadReportDirectJob.output_label(organization_id)
|
|
52
|
-
clear_task_output(label)
|
|
53
|
-
plan_self(
|
|
54
|
-
instance_label: label,
|
|
55
|
-
filename: filename,
|
|
56
|
-
organization_id: organization_id
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def try_execute
|
|
61
|
-
if content_disconnected?
|
|
62
|
-
progress_output do |progress_output|
|
|
63
|
-
progress_output.write_line("Report was not moved and upload was canceled because connection to Insights is not enabled. Report location: #{filename}.")
|
|
64
|
-
progress_output.status = "Task aborted, exit 1"
|
|
65
|
-
done!
|
|
66
|
-
end
|
|
67
|
-
return
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
unless organization.owner_details&.dig('upstreamConsumer', 'idCert')
|
|
71
|
-
logger.info("Skipping organization '#{organization}', no candlepin certificate defined.")
|
|
72
|
-
progress_output do |progress_output|
|
|
73
|
-
progress_output.write_line("Skipping organization #{organization}, no candlepin certificate defined.")
|
|
74
|
-
progress_output.status = "Task aborted, exit 1"
|
|
75
|
-
done!
|
|
76
|
-
end
|
|
77
|
-
return
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
Tempfile.create([organization.name, '.pem']) do |cer_file|
|
|
81
|
-
cer_file.write(certificate[:cert])
|
|
82
|
-
cer_file.write(certificate[:key])
|
|
83
|
-
cer_file.flush
|
|
84
|
-
upload_report(cer_file.path)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
done!
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def upload_report(cer_path)
|
|
91
|
-
progress_output do |progress_output|
|
|
92
|
-
progress_output.write_line("Uploading report for organization #{organization.label}...")
|
|
93
|
-
progress_output.status = "Running upload"
|
|
94
|
-
|
|
95
|
-
begin
|
|
96
|
-
upload_file(cer_path)
|
|
97
|
-
progress_output.write_line("Upload completed successfully")
|
|
98
|
-
move_to_done_folder
|
|
99
|
-
progress_output.write_line("Uploaded file moved to done/ folder")
|
|
100
|
-
progress_output.status = "pid #{Process.pid} exit 0"
|
|
101
|
-
rescue StandardError => e
|
|
102
|
-
progress_output.write_line("Upload failed: #{e.message}")
|
|
103
|
-
progress_output.status = "pid #{Process.pid} exit 1"
|
|
104
|
-
raise
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def upload_file(cer_path)
|
|
110
|
-
cert_content = File.read(cer_path)
|
|
111
|
-
|
|
112
|
-
File.open(filename, 'rb') do |file|
|
|
113
|
-
# Wrap file with FileUpload class for RestClient multipart handling
|
|
114
|
-
# RestClient requires objects with :read, :path, and :content_type methods
|
|
115
|
-
wrapped_file = FileUpload.new(file, content_type: 'application/vnd.redhat.qpc.tar+tgz')
|
|
116
|
-
|
|
117
|
-
response = execute_cloud_request(
|
|
118
|
-
method: :post,
|
|
119
|
-
url: ForemanInventoryUpload.upload_url,
|
|
120
|
-
payload: {
|
|
121
|
-
multipart: true,
|
|
122
|
-
file: wrapped_file,
|
|
123
|
-
},
|
|
124
|
-
headers: {
|
|
125
|
-
'X-Org-Id' => organization.label,
|
|
126
|
-
},
|
|
127
|
-
ssl_client_cert: OpenSSL::X509::Certificate.new(cert_content),
|
|
128
|
-
ssl_client_key: OpenSSL::PKey::RSA.new(cert_content),
|
|
129
|
-
timeout: 600,
|
|
130
|
-
open_timeout: 60
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
logger.debug("Upload response code: #{response.code}")
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def move_to_done_folder
|
|
138
|
-
FileUtils.mkdir_p(ForemanInventoryUpload.done_folder)
|
|
139
|
-
done_file = ForemanInventoryUpload.done_file_path(File.basename(filename))
|
|
140
|
-
FileUtils.mv(filename, done_file)
|
|
141
|
-
logger.debug("Moved #{filename} to #{done_file}")
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def certificate
|
|
145
|
-
ForemanRhCloud.with_iop_smart_proxy? ? foreman_certificate : manifest_certificate
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def manifest_certificate
|
|
149
|
-
candlepin_id_certificate = organization.owner_details['upstreamConsumer']['idCert']
|
|
150
|
-
{
|
|
151
|
-
cert: candlepin_id_certificate['cert'],
|
|
152
|
-
key: candlepin_id_certificate['key'],
|
|
153
|
-
}
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def foreman_certificate
|
|
157
|
-
{
|
|
158
|
-
cert: File.read(Setting[:ssl_certificate]),
|
|
159
|
-
key: File.read(Setting[:ssl_priv_key]),
|
|
160
|
-
}
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def filename
|
|
164
|
-
input[:filename]
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def organization
|
|
168
|
-
Organization.find(input[:organization_id])
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def content_disconnected?
|
|
172
|
-
!Setting[:subscription_connection_enabled]
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def progress_output
|
|
176
|
-
progress_output = ProgressOutput.register(instance_label)
|
|
177
|
-
yield(progress_output)
|
|
178
|
-
ensure
|
|
179
|
-
progress_output.close
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def instance_label
|
|
183
|
-
input[:instance_label]
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def logger
|
|
187
|
-
Foreman::Logging.logger('background')
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def rescue_strategy_for_self
|
|
191
|
-
Dynflow::Action::Rescue::Fail
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def clear_task_output(label)
|
|
195
|
-
TaskOutputLine.where(label: label).delete_all
|
|
196
|
-
TaskOutputStatus.where(label: label).delete_all
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
require 'foreman_tasks/test_helpers'
|
|
3
|
-
|
|
4
|
-
class CreateMissingInsightsFacetsTest < ActiveSupport::TestCase
|
|
5
|
-
include Dynflow::Testing::Factories
|
|
6
|
-
include KatelloCVEHelper
|
|
7
|
-
|
|
8
|
-
setup do
|
|
9
|
-
User.current = User.find_by(login: 'secret_admin')
|
|
10
|
-
@cve = make_cve
|
|
11
|
-
@env = @cve.lifecycle_environment
|
|
12
|
-
@organization = @env.organization
|
|
13
|
-
|
|
14
|
-
# Create a host with subscription facet but no insights facet
|
|
15
|
-
@host_without_facet = FactoryBot.create(
|
|
16
|
-
:host,
|
|
17
|
-
:with_subscription,
|
|
18
|
-
:with_content,
|
|
19
|
-
content_view: @cve.content_view,
|
|
20
|
-
lifecycle_environment: @env,
|
|
21
|
-
organization: @organization
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
# Create a host with both subscription and insights facets
|
|
25
|
-
@host_with_facet = FactoryBot.create(
|
|
26
|
-
:host,
|
|
27
|
-
:with_subscription,
|
|
28
|
-
:with_content,
|
|
29
|
-
content_view: @cve.content_view,
|
|
30
|
-
lifecycle_environment: @env,
|
|
31
|
-
organization: @organization
|
|
32
|
-
)
|
|
33
|
-
@host_with_facet.build_insights(uuid: @host_with_facet.subscription_facet.uuid)
|
|
34
|
-
@host_with_facet.insights.save!
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
test 'creates insights facets for hosts without them' do
|
|
38
|
-
assert_nil @host_without_facet.insights
|
|
39
|
-
|
|
40
|
-
action = create_and_plan_action(
|
|
41
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
42
|
-
@organization.id
|
|
43
|
-
)
|
|
44
|
-
action = run_action(action)
|
|
45
|
-
|
|
46
|
-
@host_without_facet.reload
|
|
47
|
-
assert_not_nil @host_without_facet.insights
|
|
48
|
-
assert_equal @host_without_facet.subscription_facet.uuid, @host_without_facet.insights.uuid
|
|
49
|
-
assert_match(/Missing Insights facets created: 1/, action.output[:result])
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
test 'does not create duplicate facets for hosts that already have them' do
|
|
53
|
-
original_uuid = @host_with_facet.insights.uuid
|
|
54
|
-
original_id = @host_with_facet.insights.id
|
|
55
|
-
|
|
56
|
-
action = create_and_plan_action(
|
|
57
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
58
|
-
@organization.id
|
|
59
|
-
)
|
|
60
|
-
run_action(action)
|
|
61
|
-
|
|
62
|
-
@host_with_facet.reload
|
|
63
|
-
assert_equal original_id, @host_with_facet.insights.id
|
|
64
|
-
assert_equal original_uuid, @host_with_facet.insights.uuid
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
test 'handles organization with no missing facets' do
|
|
68
|
-
# Create insights facet for the host that was missing one
|
|
69
|
-
@host_without_facet.build_insights(uuid: @host_without_facet.subscription_facet.uuid)
|
|
70
|
-
@host_without_facet.insights.save!
|
|
71
|
-
|
|
72
|
-
action = create_and_plan_action(
|
|
73
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
74
|
-
@organization.id
|
|
75
|
-
)
|
|
76
|
-
action = run_action(action)
|
|
77
|
-
|
|
78
|
-
assert_match(/There were no missing Insights facets/, action.output[:result])
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
test 'creates multiple facets when multiple hosts are missing them' do
|
|
82
|
-
# Remove the insights facet from the host that has one
|
|
83
|
-
@host_with_facet.insights.destroy
|
|
84
|
-
@host_with_facet.reload
|
|
85
|
-
|
|
86
|
-
assert_nil @host_without_facet.insights
|
|
87
|
-
assert_nil @host_with_facet.insights
|
|
88
|
-
|
|
89
|
-
action = create_and_plan_action(
|
|
90
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
91
|
-
@organization.id
|
|
92
|
-
)
|
|
93
|
-
action = run_action(action)
|
|
94
|
-
|
|
95
|
-
@host_without_facet.reload
|
|
96
|
-
@host_with_facet.reload
|
|
97
|
-
assert_not_nil @host_without_facet.insights
|
|
98
|
-
assert_not_nil @host_with_facet.insights
|
|
99
|
-
# After the bug fix, the count should correctly show 2 hosts
|
|
100
|
-
assert_match(/Missing Insights facets created: 2/, action.output[:result])
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
test 'logs result message' do
|
|
104
|
-
Rails.logger.expects(:debug).with(regexp_matches(/Missing Insights facets created/))
|
|
105
|
-
|
|
106
|
-
action = create_and_plan_action(
|
|
107
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
108
|
-
@organization.id
|
|
109
|
-
)
|
|
110
|
-
run_action(action)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
test 'correctly counts facets across multiple batches' do
|
|
114
|
-
# Remove existing insights facet
|
|
115
|
-
@host_with_facet.insights.destroy
|
|
116
|
-
@host_with_facet.reload
|
|
117
|
-
|
|
118
|
-
# Stub the batch size to force multiple batches with just 2 hosts
|
|
119
|
-
ForemanInventoryUpload.stubs(:slice_size).returns(1)
|
|
120
|
-
|
|
121
|
-
assert_nil @host_without_facet.insights
|
|
122
|
-
assert_nil @host_with_facet.insights
|
|
123
|
-
|
|
124
|
-
action = create_and_plan_action(
|
|
125
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
126
|
-
@organization.id
|
|
127
|
-
)
|
|
128
|
-
action = run_action(action)
|
|
129
|
-
|
|
130
|
-
@host_without_facet.reload
|
|
131
|
-
@host_with_facet.reload
|
|
132
|
-
assert_not_nil @host_without_facet.insights
|
|
133
|
-
assert_not_nil @host_with_facet.insights
|
|
134
|
-
# Count should be 2 even though processed in 2 separate batches
|
|
135
|
-
assert_match(/Missing Insights facets created: 2/, action.output[:result])
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
test 'handles error when InsightsFacet.upsert_all fails' do
|
|
139
|
-
# Stub upsert_all to raise an exception
|
|
140
|
-
InsightsFacet.stubs(:upsert_all).raises(StandardError.new('upsert failed'))
|
|
141
|
-
|
|
142
|
-
action = create_and_plan_action(
|
|
143
|
-
ForemanInventoryUpload::Async::CreateMissingInsightsFacets,
|
|
144
|
-
@organization.id
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
assert_raises(StandardError) do
|
|
148
|
-
run_action(action)
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
require 'test_plugin_helper'
|
|
2
|
-
require 'foreman_tasks/test_helpers'
|
|
3
|
-
|
|
4
|
-
class GenerateHostReportTest < ActiveSupport::TestCase
|
|
5
|
-
include Dynflow::Testing::Factories
|
|
6
|
-
include FolderIsolation
|
|
7
|
-
|
|
8
|
-
let(:organization) { FactoryBot.create(:organization) }
|
|
9
|
-
let(:base_folder) { @tmpdir }
|
|
10
|
-
let(:filter) { '' }
|
|
11
|
-
|
|
12
|
-
setup do
|
|
13
|
-
# Stub the ArchivedReport generator
|
|
14
|
-
@mock_generator = mock('archived_report_generator')
|
|
15
|
-
@mock_generator.stubs(:render)
|
|
16
|
-
ForemanInventoryUpload::Generators::ArchivedReport.stubs(:new).returns(@mock_generator)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
test 'plan sets target path correctly' do
|
|
20
|
-
expected_archive_name = ForemanInventoryUpload.facts_archive_name(organization.id, filter)
|
|
21
|
-
expected_target = File.join(base_folder, expected_archive_name)
|
|
22
|
-
|
|
23
|
-
action = create_and_plan_action(
|
|
24
|
-
ForemanInventoryUpload::Async::GenerateHostReport,
|
|
25
|
-
base_folder,
|
|
26
|
-
organization.id,
|
|
27
|
-
filter
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
assert_equal expected_target, action.input[:target]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
test 'run generates report archive' do
|
|
34
|
-
expected_target = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(organization.id, filter))
|
|
35
|
-
|
|
36
|
-
ForemanInventoryUpload::Generators::ArchivedReport.expects(:new).with(expected_target).returns(@mock_generator)
|
|
37
|
-
@mock_generator.expects(:render).with(organization: organization.id, filter: filter)
|
|
38
|
-
|
|
39
|
-
action = create_and_plan_action(
|
|
40
|
-
ForemanInventoryUpload::Async::GenerateHostReport,
|
|
41
|
-
base_folder,
|
|
42
|
-
organization.id,
|
|
43
|
-
filter
|
|
44
|
-
)
|
|
45
|
-
action = run_action(action)
|
|
46
|
-
|
|
47
|
-
assert_match(/Generated #{Regexp.escape(expected_target)} for organization id #{organization.id}/, action.output[:result])
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
test 'generates report with filter' do
|
|
51
|
-
filter_value = 'id=123'
|
|
52
|
-
expected_target = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(organization.id, filter_value))
|
|
53
|
-
|
|
54
|
-
ForemanInventoryUpload::Generators::ArchivedReport.expects(:new).with(expected_target).returns(@mock_generator)
|
|
55
|
-
@mock_generator.expects(:render).with(organization: organization.id, filter: filter_value)
|
|
56
|
-
|
|
57
|
-
action = create_and_plan_action(
|
|
58
|
-
ForemanInventoryUpload::Async::GenerateHostReport,
|
|
59
|
-
base_folder,
|
|
60
|
-
organization.id,
|
|
61
|
-
filter_value
|
|
62
|
-
)
|
|
63
|
-
action = run_action(action)
|
|
64
|
-
|
|
65
|
-
assert_match(/organization id #{organization.id}/, action.output[:result])
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
test 'stores organization_id and filter in input' do
|
|
69
|
-
filter_value = 'name~test'
|
|
70
|
-
|
|
71
|
-
action = create_and_plan_action(
|
|
72
|
-
ForemanInventoryUpload::Async::GenerateHostReport,
|
|
73
|
-
base_folder,
|
|
74
|
-
organization.id,
|
|
75
|
-
filter_value
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
assert_equal organization.id, action.input[:organization_id]
|
|
79
|
-
assert_equal filter_value, action.input[:filter]
|
|
80
|
-
assert_equal base_folder, action.input[:base_folder]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
test 'handles ArchivedReport generator failure' do
|
|
84
|
-
expected_target = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(organization.id, filter))
|
|
85
|
-
|
|
86
|
-
ForemanInventoryUpload::Generators::ArchivedReport.expects(:new).with(expected_target).returns(@mock_generator)
|
|
87
|
-
@mock_generator.expects(:render).with(organization: organization.id, filter: filter).raises(StandardError.new('Report generation failed'))
|
|
88
|
-
|
|
89
|
-
action = create_and_plan_action(
|
|
90
|
-
ForemanInventoryUpload::Async::GenerateHostReport,
|
|
91
|
-
base_folder,
|
|
92
|
-
organization.id,
|
|
93
|
-
filter
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
assert_raises(StandardError) do
|
|
97
|
-
run_action(action)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|