foreman_rh_cloud 6.0.43 → 6.0.44
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/controllers/insights_cloud/api/machine_telemetries_controller.rb +11 -5
- data/db/migrate/20221102110254_fix_rh_cloud_settings_category_to_dsl.rb +7 -0
- data/lib/foreman_inventory_upload/async/delayed_start.rb +51 -0
- data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +12 -9
- data/lib/foreman_inventory_upload/async/shell_process.rb +9 -1
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +3 -1
- data/lib/foreman_rh_cloud/async/exponential_backoff.rb +55 -0
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +4 -0
- data/lib/insights_cloud/async/insights_full_sync.rb +3 -1
- data/lib/insights_cloud/async/insights_resolutions_sync.rb +3 -1
- data/lib/insights_cloud/async/insights_rules_sync.rb +3 -1
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +4 -1
- data/lib/inventory_sync/async/host_result.rb +1 -1
- data/lib/inventory_sync/async/inventory_scheduled_sync.rb +5 -2
- data/lib/inventory_sync/async/query_inventory_job.rb +4 -1
- data/package.json +1 -1
- data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +11 -0
- data/test/jobs/exponential_backoff_test.rb +45 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +4 -1
- data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +4 -1
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +4 -3
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 44056fad5c50d5b78e64b5e13a622818525fd5e8176159462825ae8306cd035f
|
|
4
|
+
data.tar.gz: 6fa455af9f99ea4864c0d813962ecb7fcc9706517daf9459953c378ec547814d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fb003eeadd973880052b4d5d04a682d46938e4805a5bd0aad57ae9c22a0ea5cd05488f8e827838db2c5093d04dd5c91d2cc44332f2472a0e5e76bcf2c78126d
|
|
7
|
+
data.tar.gz: efef456d8ecad910cb36ae64fb82202225733d484a227d6a142e71b145046a5533b626e2349d99d9f257282c03dc026a04de62ff8d436158226dd0f5a7fdcdb8
|
|
@@ -33,10 +33,6 @@ module InsightsCloud::Api
|
|
|
33
33
|
}, status: @cloud_response.code
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
if @cloud_response.headers[:content_disposition]
|
|
37
|
-
return send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
36
|
# Append redhat-specific headers
|
|
41
37
|
@cloud_response.headers.each do |key, value|
|
|
42
38
|
assign_header(response, @cloud_response, key, false) if key.to_s.start_with?('x_rh_')
|
|
@@ -45,7 +41,17 @@ module InsightsCloud::Api
|
|
|
45
41
|
assign_header(response, @cloud_response, :x_resource_count, true)
|
|
46
42
|
headers[Rack::ETAG] = @cloud_response.headers[:etag]
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
if @cloud_response.headers[:content_disposition]
|
|
45
|
+
# If there is a Content-Disposition header, it means we are forwarding binary data, send the raw data with proper
|
|
46
|
+
# content type
|
|
47
|
+
send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
|
|
48
|
+
elsif @cloud_response.headers[:content_type] =~ /zip/
|
|
49
|
+
# if there is no Content-Disposition, but the content type is binary according the content type,
|
|
50
|
+
# forward the request as binry too
|
|
51
|
+
send_data @cloud_response, type: @cloud_response.headers[:content_type]
|
|
52
|
+
else
|
|
53
|
+
render json: @cloud_response, status: @cloud_response.code
|
|
54
|
+
end
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
def branch_info
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module ForemanInventoryUpload
|
|
2
|
+
module Async
|
|
3
|
+
module DelayedStart
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
START_WINDOW = 3.hours.seconds
|
|
7
|
+
|
|
8
|
+
def after_delay(delay = nil, logger: nil, &block)
|
|
9
|
+
logger ||= self.logger if respond_to? :logger
|
|
10
|
+
delay ||= ForemanRhCloud.requests_delay || Random.new.rand(START_WINDOW)
|
|
11
|
+
delay = delay.to_i
|
|
12
|
+
|
|
13
|
+
logger&.debug("planning a delay for #{delay} seconds before the rest of the execution")
|
|
14
|
+
|
|
15
|
+
sequence do
|
|
16
|
+
plan_action(ForemanInventoryUpload::Async::DelayAction, delay)
|
|
17
|
+
concurrence(&block)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def humanized_name
|
|
22
|
+
_('Wait and %s' % super)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class DelayAction < ::Actions::EntryAction
|
|
27
|
+
Wake = Algebrick.atom
|
|
28
|
+
|
|
29
|
+
def plan(delay)
|
|
30
|
+
plan_self(delay: delay)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def run(event = nil)
|
|
34
|
+
case event
|
|
35
|
+
when nil
|
|
36
|
+
action_logger.debug("Going to sleep for #{sleep_seconds} seconds")
|
|
37
|
+
plan_event(Wake, sleep_seconds)
|
|
38
|
+
suspend
|
|
39
|
+
when Wake
|
|
40
|
+
action_logger.debug('Waking up')
|
|
41
|
+
else
|
|
42
|
+
action_logger.debug("DelayAction received unknown event #{event}")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def sleep_seconds
|
|
47
|
+
input[:delay].to_i
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -2,6 +2,7 @@ module ForemanInventoryUpload
|
|
|
2
2
|
module Async
|
|
3
3
|
class GenerateAllReportsJob < ::Actions::EntryAction
|
|
4
4
|
include ::Actions::RecurringAction
|
|
5
|
+
include ForemanInventoryUpload::Async::DelayedStart
|
|
5
6
|
|
|
6
7
|
def plan
|
|
7
8
|
unless Setting[:allow_auto_inventory_upload]
|
|
@@ -12,17 +13,19 @@ module ForemanInventoryUpload
|
|
|
12
13
|
return
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
after_delay do
|
|
17
|
+
organizations = Organization.unscoped.all
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
organizations.map do |organization|
|
|
20
|
+
total_hosts = ForemanInventoryUpload::Generators::Queries.for_org(organization.id, use_batches: false).count
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
if total_hosts <= ForemanInventoryUpload.max_org_size
|
|
23
|
+
plan_generate_report(ForemanInventoryUpload.generated_reports_folder, organization)
|
|
24
|
+
else
|
|
25
|
+
logger.info("Skipping automatic uploads for organization #{organization.name}, too many hosts (#{total_hosts}/#{ForemanInventoryUpload.max_org_size})")
|
|
26
|
+
end
|
|
27
|
+
end.compact
|
|
28
|
+
end
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
def rescue_strategy_for_self
|
|
@@ -4,13 +4,14 @@ module ForemanInventoryUpload
|
|
|
4
4
|
module Async
|
|
5
5
|
class ShellProcess < ::Actions::EntryAction
|
|
6
6
|
include AsyncHelpers
|
|
7
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
7
8
|
|
|
8
9
|
def plan(instance_label, more_inputs = {})
|
|
9
10
|
inputs = more_inputs.merge(instance_label: instance_label)
|
|
10
11
|
plan_self(inputs)
|
|
11
12
|
end
|
|
12
13
|
|
|
13
|
-
def
|
|
14
|
+
def try_execute
|
|
14
15
|
klass_name = self.class.name
|
|
15
16
|
logger.debug("Starting #{klass_name} with label #{instance_label}")
|
|
16
17
|
progress_output do |progress_output|
|
|
@@ -25,6 +26,9 @@ module ForemanInventoryUpload
|
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
28
|
logger.debug("Finished job #{klass_name} with label #{instance_label}")
|
|
29
|
+
|
|
30
|
+
assert_task_status(ProgressOutput.get(instance_label).status)
|
|
31
|
+
done!
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def command
|
|
@@ -58,6 +62,10 @@ module ForemanInventoryUpload
|
|
|
58
62
|
def instance_label
|
|
59
63
|
input[:instance_label]
|
|
60
64
|
end
|
|
65
|
+
|
|
66
|
+
def assert_task_status(status)
|
|
67
|
+
raise Foreman::Exception.new('Process exited with an unknown status: %{status}', status: status) unless status.match?(/pid \d+ exit 0/)
|
|
68
|
+
end
|
|
61
69
|
end
|
|
62
70
|
end
|
|
63
71
|
end
|
|
@@ -12,11 +12,12 @@ module ForemanInventoryUpload
|
|
|
12
12
|
super(label, filename: filename, organization_id: organization_id)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
15
|
+
def try_execute
|
|
16
16
|
if content_disconnected?
|
|
17
17
|
progress_output do |progress_output|
|
|
18
18
|
progress_output.write_line('Upload was stopped since disconnected mode setting is enabled for content on this instance.')
|
|
19
19
|
progress_output.status = "Task aborted, exit 1"
|
|
20
|
+
done!
|
|
20
21
|
end
|
|
21
22
|
return
|
|
22
23
|
end
|
|
@@ -26,6 +27,7 @@ module ForemanInventoryUpload
|
|
|
26
27
|
progress_output do |progress_output|
|
|
27
28
|
progress_output.write_line("Skipping organization #{organization}, no candlepin certificate defined.")
|
|
28
29
|
progress_output.status = "Task aborted, exit 1"
|
|
30
|
+
done!
|
|
29
31
|
end
|
|
30
32
|
return
|
|
31
33
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module ForemanRhCloud
|
|
2
|
+
module Async
|
|
3
|
+
module ExponentialBackoff
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include Dynflow::Action::Polling
|
|
6
|
+
|
|
7
|
+
# Use each interval once
|
|
8
|
+
def attempts_before_next_interval
|
|
9
|
+
1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# define poll intervals in the following way: [1/10..1, 1..10, 10..100] e.t.c.
|
|
13
|
+
# total count of intervals would be the amount of poll retries.
|
|
14
|
+
def poll_intervals
|
|
15
|
+
(1..poll_max_retries).map do |i|
|
|
16
|
+
base = 10**i
|
|
17
|
+
random_interval(base)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def done!
|
|
22
|
+
@done = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def done?
|
|
26
|
+
@done
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def invoke_external_task
|
|
30
|
+
# Call the polling method from task's framework
|
|
31
|
+
poll_external_task_with_rescue
|
|
32
|
+
# supress unexpected task output serialization
|
|
33
|
+
{}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def poll_external_task
|
|
37
|
+
try_execute
|
|
38
|
+
# supress unexpected task output serialization
|
|
39
|
+
{}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# override this method in the consumng class
|
|
43
|
+
# This is the action that we expect to retry in case of an exception.
|
|
44
|
+
def try_execute
|
|
45
|
+
raise NotImplementedError
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def random_interval(base)
|
|
51
|
+
Random.new.rand(base..10 * base)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/foreman_rh_cloud.rb
CHANGED
|
@@ -120,4 +120,8 @@ module ForemanRhCloud
|
|
|
120
120
|
def self.cloud_url_validator
|
|
121
121
|
@cloud_url_validator ||= Regexp.new(ENV['SATELLITE_RH_CLOUD_VALIDATOR'] || 'redhat.com$')
|
|
122
122
|
end
|
|
123
|
+
|
|
124
|
+
def self.requests_delay
|
|
125
|
+
@requests_delay ||= ENV['SATELLITE_RH_CLOUD_REQUESTS_DELAY']
|
|
126
|
+
end
|
|
123
127
|
end
|
|
@@ -5,6 +5,7 @@ module InsightsCloud
|
|
|
5
5
|
module Async
|
|
6
6
|
class InsightsFullSync < ::Actions::EntryAction
|
|
7
7
|
include ::ForemanRhCloud::CertAuth
|
|
8
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
8
9
|
|
|
9
10
|
def plan(organizations)
|
|
10
11
|
organizations = organizations.select do |organization|
|
|
@@ -28,7 +29,7 @@ module InsightsCloud
|
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
def
|
|
32
|
+
def try_execute
|
|
32
33
|
organizations.each do |organization|
|
|
33
34
|
unless cert_auth_available?(organization)
|
|
34
35
|
logger.debug("Certificate is not available for org: #{organization.name}, skipping insights sync")
|
|
@@ -37,6 +38,7 @@ module InsightsCloud
|
|
|
37
38
|
|
|
38
39
|
perform_hits_sync(organization)
|
|
39
40
|
end
|
|
41
|
+
done!
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def perform_hits_sync(organization)
|
|
@@ -4,10 +4,11 @@ module InsightsCloud
|
|
|
4
4
|
module Async
|
|
5
5
|
class InsightsResolutionsSync < ::Actions::EntryAction
|
|
6
6
|
include ::ForemanRhCloud::CertAuth
|
|
7
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
7
8
|
|
|
8
9
|
RULE_ID_REGEX = /[^:]*:(?<id>.*)/
|
|
9
10
|
|
|
10
|
-
def
|
|
11
|
+
def try_execute
|
|
11
12
|
InsightsResolution.transaction do
|
|
12
13
|
InsightsResolution.delete_all
|
|
13
14
|
rule_ids = relevant_rules
|
|
@@ -18,6 +19,7 @@ module InsightsCloud
|
|
|
18
19
|
rule_ids -= Array(written_rules)
|
|
19
20
|
end
|
|
20
21
|
end
|
|
22
|
+
done!
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def logger
|
|
@@ -4,6 +4,7 @@ module InsightsCloud
|
|
|
4
4
|
module Async
|
|
5
5
|
class InsightsRulesSync < ::Actions::EntryAction
|
|
6
6
|
include ::ForemanRhCloud::CertAuth
|
|
7
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
7
8
|
|
|
8
9
|
def plan(organizations)
|
|
9
10
|
# since the tasks are not connected, we need to force sequence execution here
|
|
@@ -18,7 +19,7 @@ module InsightsCloud
|
|
|
18
19
|
plan_action InsightsResolutionsSync
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
+
def try_execute
|
|
22
23
|
offset = 0
|
|
23
24
|
InsightsRule.transaction do
|
|
24
25
|
organizations.each do |organization|
|
|
@@ -36,6 +37,7 @@ module InsightsCloud
|
|
|
36
37
|
# Remove all rules that do not have hits associated with them
|
|
37
38
|
cleanup_rules
|
|
38
39
|
end
|
|
40
|
+
done!
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def logger
|
|
@@ -2,6 +2,7 @@ module InsightsCloud
|
|
|
2
2
|
module Async
|
|
3
3
|
class InsightsScheduledSync < ::Actions::EntryAction
|
|
4
4
|
include ::Actions::RecurringAction
|
|
5
|
+
include ForemanInventoryUpload::Async::DelayedStart
|
|
5
6
|
|
|
6
7
|
def plan
|
|
7
8
|
unless Setting[:allow_auto_insights_sync]
|
|
@@ -12,7 +13,9 @@ module InsightsCloud
|
|
|
12
13
|
return
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
after_delay do
|
|
17
|
+
plan_full_sync
|
|
18
|
+
end
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
def plan_full_sync
|
|
@@ -11,7 +11,7 @@ module InventorySync
|
|
|
11
11
|
@per_page = result['per_page']
|
|
12
12
|
@sub_ids = result["results"].map { |host| host['subscription_manager_id'] }
|
|
13
13
|
@uuid_by_sub_id = Hash[result["results"].map { |host| [host['subscription_manager_id'], host['id']] }]
|
|
14
|
-
@uuid_by_fqdn = Hash[result["results"].map { |host| [host['fqdn']
|
|
14
|
+
@uuid_by_fqdn = Hash[result["results"].map { |host| [host['fqdn']&.downcase, host['id']] }]
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def status_hashes
|
|
@@ -2,6 +2,7 @@ module InventorySync
|
|
|
2
2
|
module Async
|
|
3
3
|
class InventoryScheduledSync < ::Actions::EntryAction
|
|
4
4
|
include ::Actions::RecurringAction
|
|
5
|
+
include ForemanInventoryUpload::Async::DelayedStart
|
|
5
6
|
|
|
6
7
|
def plan
|
|
7
8
|
unless Setting[:allow_auto_inventory_upload]
|
|
@@ -12,8 +13,10 @@ module InventorySync
|
|
|
12
13
|
return
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
after_delay do
|
|
17
|
+
Organization.unscoped.each do |org|
|
|
18
|
+
plan_org_sync(org)
|
|
19
|
+
end
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
|
|
@@ -5,6 +5,7 @@ module InventorySync
|
|
|
5
5
|
class QueryInventoryJob < ::Actions::EntryAction
|
|
6
6
|
include ActiveSupport::Callbacks
|
|
7
7
|
include ::ForemanRhCloud::CertAuth
|
|
8
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
8
9
|
|
|
9
10
|
define_callbacks :iteration, :step
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ module InventorySync
|
|
|
18
19
|
plan_self(actual_params)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
+
def try_execute
|
|
22
23
|
run_callbacks :iteration do
|
|
23
24
|
organizations.each do |organization|
|
|
24
25
|
if !cert_auth_available?(organization) || organization.manifest_expired?
|
|
@@ -43,6 +44,8 @@ module InventorySync
|
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
end
|
|
47
|
+
# declare the action as finished to stop iterations
|
|
48
|
+
done!
|
|
46
49
|
end
|
|
47
50
|
|
|
48
51
|
private
|
data/package.json
CHANGED
|
@@ -72,6 +72,17 @@ module InsightsCloud::Api
|
|
|
72
72
|
assert_equal etag, @response.headers[Rack::ETAG]
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
test "should set content type header to response from cloud" do
|
|
76
|
+
req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org')
|
|
77
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
|
78
|
+
net_http_resp[:content_type] = 'application/zip'
|
|
79
|
+
res = RestClient::Response.create(@body, net_http_resp, req)
|
|
80
|
+
::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:forward_request).returns(res)
|
|
81
|
+
|
|
82
|
+
get :forward_request, params: { "path" => "static/v1/release/insights-core.egg" }
|
|
83
|
+
assert_equal net_http_resp[:content_type], @response.headers['Content-Type']
|
|
84
|
+
end
|
|
85
|
+
|
|
75
86
|
test "should handle failed authentication to cloud" do
|
|
76
87
|
net_http_resp = Net::HTTPResponse.new(1.0, 401, "Unauthorized")
|
|
77
88
|
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'test_plugin_helper'
|
|
2
|
+
require 'foreman_tasks/test_helpers'
|
|
3
|
+
|
|
4
|
+
class ExponentialBackoffTest < ActiveSupport::TestCase
|
|
5
|
+
include ForemanTasks::TestHelpers::WithInThreadExecutor
|
|
6
|
+
|
|
7
|
+
class TestAction < ::Actions::EntryAction
|
|
8
|
+
include ::ForemanRhCloud::Async::ExponentialBackoff
|
|
9
|
+
|
|
10
|
+
def try_execute
|
|
11
|
+
action_callback&.call(self)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# define a method to execute code inside the class context.
|
|
15
|
+
def action_callback(instance)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test 'executes an action once' do
|
|
20
|
+
TestAction.any_instance.expects(:action_callback).returns(->(instance) { instance.done! })
|
|
21
|
+
|
|
22
|
+
ForemanTasks.sync_task(TestAction)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'fails after a single excution if done was called' do
|
|
26
|
+
TestAction.any_instance.expects(:action_callback).returns(
|
|
27
|
+
lambda do |instance|
|
|
28
|
+
instance.done!
|
|
29
|
+
raise ::Foreman::Exception('Foo')
|
|
30
|
+
end)
|
|
31
|
+
|
|
32
|
+
ForemanTasks.sync_task(TestAction)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test 'executes the task three times before failing it' do
|
|
36
|
+
# speed up the execution
|
|
37
|
+
TestAction.any_instance.stubs(:poll_intervals).returns([0, 0, 0])
|
|
38
|
+
|
|
39
|
+
TestAction.any_instance.expects(:action_callback).raises(::Foreman::Exception.new('Foo')).times(3)
|
|
40
|
+
|
|
41
|
+
ForemanTasks.sync_task(TestAction)
|
|
42
|
+
rescue ForemanTasks::TaskError => ex
|
|
43
|
+
assert ex.aggregated_message =~ /Foo/
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -31,6 +31,7 @@ const InsightsTable = ({
|
|
|
31
31
|
error,
|
|
32
32
|
isAllSelected,
|
|
33
33
|
hideHost,
|
|
34
|
+
hostname,
|
|
34
35
|
}) => {
|
|
35
36
|
const { perPage: appPerPage } = useForemanSettings();
|
|
36
37
|
const perPage = urlPerPage || appPerPage;
|
|
@@ -40,7 +41,7 @@ const InsightsTable = ({
|
|
|
40
41
|
// acts as componentDidMount
|
|
41
42
|
useEffect(() => {
|
|
42
43
|
fetchInsights({ page, perPage, query, sortBy, sortOrder });
|
|
43
|
-
}, []);
|
|
44
|
+
}, [hostname]);
|
|
44
45
|
|
|
45
46
|
useEffect(() => {
|
|
46
47
|
setRows(
|
|
@@ -104,6 +105,7 @@ InsightsTable.propTypes = {
|
|
|
104
105
|
error: PropTypes.string,
|
|
105
106
|
isAllSelected: PropTypes.bool,
|
|
106
107
|
hideHost: PropTypes.bool,
|
|
108
|
+
hostname: PropTypes.string,
|
|
107
109
|
};
|
|
108
110
|
|
|
109
111
|
InsightsTable.defaultProps = {
|
|
@@ -118,6 +120,7 @@ InsightsTable.defaultProps = {
|
|
|
118
120
|
error: '',
|
|
119
121
|
isAllSelected: false,
|
|
120
122
|
hideHost: false,
|
|
123
|
+
hostname: '',
|
|
121
124
|
};
|
|
122
125
|
|
|
123
126
|
export default InsightsTable;
|
|
@@ -121,6 +121,7 @@ const InsightsTotalRiskCard = ({ hostDetails: { id } }) => {
|
|
|
121
121
|
dropdownItems={[
|
|
122
122
|
<DropdownItem
|
|
123
123
|
key="insights-tab"
|
|
124
|
+
ouiaId="insights-tab-dropdown-item"
|
|
124
125
|
onClick={() => hashHistory.push(`/Insights`)}
|
|
125
126
|
>
|
|
126
127
|
{__('View all recommendations')}
|
|
@@ -131,7 +132,9 @@ const InsightsTotalRiskCard = ({ hostDetails: { id } }) => {
|
|
|
131
132
|
status={status}
|
|
132
133
|
emptyState={
|
|
133
134
|
<Bullseye>
|
|
134
|
-
<Title headingLevel="h4">
|
|
135
|
+
<Title ouiaId="no-results-title" headingLevel="h4">
|
|
136
|
+
{__('No results found')}
|
|
137
|
+
</Title>
|
|
135
138
|
</Bullseye>
|
|
136
139
|
}
|
|
137
140
|
>
|
|
@@ -36,7 +36,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
36
36
|
router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
|
|
37
37
|
|
|
38
38
|
const dropdownItems = [
|
|
39
|
-
<DropdownItem key="insights-link">
|
|
39
|
+
<DropdownItem key="insights-link" ouiaId="insights-link">
|
|
40
40
|
<a onClick={onSatInsightsClick}>{__('Go to Satellite Insights page')}</a>
|
|
41
41
|
</DropdownItem>,
|
|
42
42
|
];
|
|
@@ -44,7 +44,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
44
44
|
if (hits.length) {
|
|
45
45
|
const { host_uuid: uuid } = hits[0];
|
|
46
46
|
dropdownItems.push(
|
|
47
|
-
<DropdownItem key="insights-advisor-link">
|
|
47
|
+
<DropdownItem key="insights-advisor-link" ouiaId="insights-advisor-link">
|
|
48
48
|
<a
|
|
49
49
|
href={redHatAdvisorSystems(uuid)}
|
|
50
50
|
target="_blank"
|
|
@@ -71,6 +71,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
71
71
|
<RemediationModal />
|
|
72
72
|
<Dropdown
|
|
73
73
|
className="insights-dropdown"
|
|
74
|
+
ouiaId="insights-dropdown"
|
|
74
75
|
onSelect={() => setIsDropdownOpen(false)}
|
|
75
76
|
toggle={
|
|
76
77
|
<KebabToggle onToggle={isOpen => setIsDropdownOpen(isOpen)} />
|
|
@@ -81,7 +82,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
81
82
|
/>
|
|
82
83
|
</GridItem>
|
|
83
84
|
<GridItem span={3}>
|
|
84
|
-
<Pagination variant="top" isCompact />
|
|
85
|
+
<Pagination ouiaId="insights-pagination" variant="top" isCompact />
|
|
85
86
|
</GridItem>
|
|
86
87
|
<GridItem>
|
|
87
88
|
<InsightsTable hideHost hostname={hostName} />
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_rh_cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.
|
|
4
|
+
version: 6.0.44
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Red Hat Cloud team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-12-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: katello
|
|
@@ -197,10 +197,12 @@ files:
|
|
|
197
197
|
- db/migrate/20210720000001_remove_old_insights_statuses.foreman_rh_cloud.rb
|
|
198
198
|
- db/migrate/20211027000001_create_task_output.foreman_rh_cloud.rb
|
|
199
199
|
- db/migrate/20220321000001_add_unique_to_insights_rules.foreman_rh_cloud.rb
|
|
200
|
+
- db/migrate/20221102110254_fix_rh_cloud_settings_category_to_dsl.rb
|
|
200
201
|
- db/seeds.d/179_ui_notifications.rb
|
|
201
202
|
- db/seeds.d/50_job_templates.rb
|
|
202
203
|
- lib/foreman_inventory_upload.rb
|
|
203
204
|
- lib/foreman_inventory_upload/async/async_helpers.rb
|
|
205
|
+
- lib/foreman_inventory_upload/async/delayed_start.rb
|
|
204
206
|
- lib/foreman_inventory_upload/async/generate_all_reports_job.rb
|
|
205
207
|
- lib/foreman_inventory_upload/async/generate_report_job.rb
|
|
206
208
|
- lib/foreman_inventory_upload/async/progress_output.rb
|
|
@@ -217,6 +219,7 @@ files:
|
|
|
217
219
|
- lib/foreman_inventory_upload/notifications/manifest_import_success_notification_override.rb
|
|
218
220
|
- lib/foreman_inventory_upload/scripts/uploader.sh.erb
|
|
219
221
|
- lib/foreman_rh_cloud.rb
|
|
222
|
+
- lib/foreman_rh_cloud/async/exponential_backoff.rb
|
|
220
223
|
- lib/foreman_rh_cloud/engine.rb
|
|
221
224
|
- lib/foreman_rh_cloud/settings.rb
|
|
222
225
|
- lib/foreman_rh_cloud/version.rb
|
|
@@ -258,6 +261,7 @@ files:
|
|
|
258
261
|
- test/factories/inventory_upload_factories.rb
|
|
259
262
|
- test/jobs/cloud_connector_announce_task_test.rb
|
|
260
263
|
- test/jobs/connector_playbook_execution_reporter_task_test.rb
|
|
264
|
+
- test/jobs/exponential_backoff_test.rb
|
|
261
265
|
- test/jobs/insights_client_status_aging_test.rb
|
|
262
266
|
- test/jobs/insights_full_sync_test.rb
|
|
263
267
|
- test/jobs/insights_resolutions_sync_test.rb
|
|
@@ -693,6 +697,7 @@ test_files:
|
|
|
693
697
|
- test/factories/inventory_upload_factories.rb
|
|
694
698
|
- test/jobs/cloud_connector_announce_task_test.rb
|
|
695
699
|
- test/jobs/connector_playbook_execution_reporter_task_test.rb
|
|
700
|
+
- test/jobs/exponential_backoff_test.rb
|
|
696
701
|
- test/jobs/insights_client_status_aging_test.rb
|
|
697
702
|
- test/jobs/insights_full_sync_test.rb
|
|
698
703
|
- test/jobs/insights_resolutions_sync_test.rb
|