foreman_rh_cloud 6.0.43 → 6.0.45

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: fb8068bce51d58d6cdf66eb5448db68133fbae198cde25a09be6f07733947653
4
+ data.tar.gz: faf0658dbfbece4a47df461daa7bb2c861c6513bb1cf09a34580fd2cd9aedb53
5
5
  SHA512:
6
- metadata.gz: 39ced1494bc063a49bc6db9917dc067abf9491e5c2f0b1eb5083134dc8cb74ef83cbe4fddabe26cfc2e44204594e3eb48ef23bb5d6c6b987838c3adaacfbc18e
7
- data.tar.gz: a84b6d061179e2d9c5a4ab3ba8031c0d3f949bdfd09fe8701435eb3328f87cd1c252602659fe963bfaf22e20feccd9b7242e9dae381a8ccf3ef4b9833c2f42b9
6
+ metadata.gz: e601daeac30fd710eea4b35eb0a9aa4c1ca4d62fa95307b0df29bf4746ecd723acc432823b164fb8b50b0ba73aeeede2cdfd4f36f7215fc437ceb9fcbfa05aaf
7
+ data.tar.gz: a4bae0cbbf09b01ce22a0f89c0a6bd4133b95e5611ead0aec6b10e1c8bd3527e9d175ca076aa5759d7154426d46df650f34a37f0886bfda204f329f7c5a8384c
@@ -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.45'.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
@@ -0,0 +1,64 @@
1
+ require 'io/console'
2
+
3
+ namespace :rh_cloud do |args|
4
+ desc 'Register Satellite Organization with Hybrid Cloud API. \
5
+ Specify org_id=x replace your organization ID with x. \
6
+ Specify SATELLITE_RH_CLOUD_URL=https://x with the Hybrid Cloud endpoint you are connecting to.'
7
+ task hybridcloud_register: [:environment] do
8
+ include ::ForemanRhCloud::CertAuth
9
+ include ::InsightsCloud::CandlepinCache
10
+
11
+ def logger
12
+ @logger ||= Logger.new(STDOUT)
13
+ end
14
+
15
+ def registrations_url
16
+ logger.warn("Custom url is not set, using the default one: #{ForemanRhCloud.base_url}") if ENV['SATELLITE_RH_CLOUD_URL'].empty?
17
+ ForemanRhCloud.base_url + '/api/identity/certificate/registrations'
18
+ end
19
+
20
+ if ENV['org_id'].nil?
21
+ logger.error('ERROR: org_id needs to be specified.')
22
+ exit(1)
23
+ end
24
+
25
+ @organization = Organization.find_by(id: ENV['org_id'].to_i) # saw this coming in as a string, so making sure it gets passed as an integer.
26
+ @uid = cp_owner_id(@organization)
27
+ @hostname = ForemanRhCloud.foreman_host_name
28
+ logger.error('Organization provided does not have a manifest imported.') + exit(1) if @uid.nil?
29
+
30
+ puts 'Paste your token, output will be hidden.'
31
+ @token = STDIN.noecho(&:gets).chomp
32
+ logger.error('Token was not entered.') + exit(1) if @token.empty?
33
+
34
+ def headers
35
+ {
36
+ Authorization: "Bearer #{@token}"
37
+ }
38
+ end
39
+
40
+ def payload
41
+ {
42
+ "uid": @uid,
43
+ "display_name": "#{@hostname}+#{@organization.label}"
44
+ }
45
+ end
46
+
47
+ def method
48
+ :post
49
+ end
50
+
51
+ begin
52
+ response = execute_cloud_request(
53
+ organization: @organization,
54
+ method: method,
55
+ url: registrations_url,
56
+ headers: headers,
57
+ payload: payload.to_json
58
+ )
59
+ logger.debug(response)
60
+ rescue Exception => ex
61
+ logger.error(ex)
62
+ end
63
+ end
64
+ end
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.45",
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.45
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: 2023-04-11 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
@@ -238,6 +241,7 @@ files:
238
241
  - lib/inventory_sync/async/inventory_self_host_sync.rb
239
242
  - lib/inventory_sync/async/query_inventory_job.rb
240
243
  - lib/tasks/foreman_rh_cloud_tasks.rake
244
+ - lib/tasks/hybrid_cloud.rake
241
245
  - lib/tasks/insights.rake
242
246
  - lib/tasks/rh_cloud_inventory.rake
243
247
  - locale/Makefile
@@ -258,6 +262,7 @@ files:
258
262
  - test/factories/inventory_upload_factories.rb
259
263
  - test/jobs/cloud_connector_announce_task_test.rb
260
264
  - test/jobs/connector_playbook_execution_reporter_task_test.rb
265
+ - test/jobs/exponential_backoff_test.rb
261
266
  - test/jobs/insights_client_status_aging_test.rb
262
267
  - test/jobs/insights_full_sync_test.rb
263
268
  - test/jobs/insights_resolutions_sync_test.rb
@@ -675,7 +680,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
675
680
  - !ruby/object:Gem::Version
676
681
  version: '0'
677
682
  requirements: []
678
- rubygems_version: 3.3.7
683
+ rubygems_version: 3.2.33
679
684
  signing_key:
680
685
  specification_version: 4
681
686
  summary: Summary of ForemanRhCloud.
@@ -693,6 +698,7 @@ test_files:
693
698
  - test/factories/inventory_upload_factories.rb
694
699
  - test/jobs/cloud_connector_announce_task_test.rb
695
700
  - test/jobs/connector_playbook_execution_reporter_task_test.rb
701
+ - test/jobs/exponential_backoff_test.rb
696
702
  - test/jobs/insights_client_status_aging_test.rb
697
703
  - test/jobs/insights_full_sync_test.rb
698
704
  - test/jobs/insights_resolutions_sync_test.rb