foreman_rh_cloud 6.0.43 → 6.0.44

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f9180080890adb316306a32a93c88fd86153d3ddf3acc9d5182831a325b35ca4
4
- data.tar.gz: 6a6d744fda10894d04f630e48b1c27a9bc87d4d6ac6af6324e3c2644b69e6948
3
+ metadata.gz: 44056fad5c50d5b78e64b5e13a622818525fd5e8176159462825ae8306cd035f
4
+ data.tar.gz: 6fa455af9f99ea4864c0d813962ecb7fcc9706517daf9459953c378ec547814d
5
5
  SHA512:
6
- metadata.gz: 39ced1494bc063a49bc6db9917dc067abf9491e5c2f0b1eb5083134dc8cb74ef83cbe4fddabe26cfc2e44204594e3eb48ef23bb5d6c6b987838c3adaacfbc18e
7
- data.tar.gz: a84b6d061179e2d9c5a4ab3ba8031c0d3f949bdfd09fe8701435eb3328f87cd1c252602659fe963bfaf22e20feccd9b7242e9dae381a8ccf3ef4b9833c2f42b9
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
- render json: @cloud_response, status: @cloud_response.code
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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FixRhCloudSettingsCategoryToDsl < ActiveRecord::Migration[6.0]
4
+ def up
5
+ Setting.where(category: 'Setting::RhCloud').update_all(category: 'Setting')
6
+ end
7
+ end
@@ -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
- organizations = Organization.unscoped.all
16
+ after_delay do
17
+ organizations = Organization.unscoped.all
16
18
 
17
- organizations.map do |organization|
18
- total_hosts = ForemanInventoryUpload::Generators::Queries.for_org(organization.id, use_batches: false).count
19
+ organizations.map do |organization|
20
+ total_hosts = ForemanInventoryUpload::Generators::Queries.for_org(organization.id, use_batches: false).count
19
21
 
20
- if total_hosts <= ForemanInventoryUpload.max_org_size
21
- plan_generate_report(ForemanInventoryUpload.generated_reports_folder, organization)
22
- else
23
- logger.info("Skipping automatic uploads for organization #{organization.name}, too many hosts (#{total_hosts}/#{ForemanInventoryUpload.max_org_size})")
24
- end
25
- end.compact
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 run
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 run
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
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '6.0.43'.freeze
2
+ VERSION = '6.0.44'.freeze
3
3
  end
@@ -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 run
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 run
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 run
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
- plan_full_sync
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'].downcase, host['id']] }]
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
- Organization.unscoped.each do |org|
16
- plan_org_sync(org)
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 run
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "6.0.43",
3
+ "version": "6.0.44",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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"> {__('No results found')} </Title>
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.43
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-09-15 00:00:00.000000000 Z
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