foreman_rh_cloud 10.0.5 → 10.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfabc05d2ec5effb2a007e85471ba31e9d0067495fcbf52d07bb37b4f3c1a15c
4
- data.tar.gz: c5f0db2ca590193d014d69358882c0abf98adf523158ceec65536391b454ca23
3
+ metadata.gz: 65251fdae0087f5b4a2b1601fa9fb40ac63874fb48280614de3efb7fb2807e11
4
+ data.tar.gz: 654748bf9d1270e27118968d2b7ab8dfa99b133087312006f8cea4a745e94543
5
5
  SHA512:
6
- metadata.gz: fd794c63904449ceb0f7b4b2d02de6e8b97cdde7745c24a5d6a02d52047fc036d3b995e11bca5aa0cf241a8b2def0f6efda15e810cd2dfdb9a5060e1cfe984bf
7
- data.tar.gz: 73d24b976d3a00150696e403d5bd5f134faa1c60ca8b75063a0ac12e57da85427c6a301faf96d502e736f515c60e6bb6b25627c056909698b3fe9fac17751da7
6
+ metadata.gz: da7ed0469f82a183a824b52a72fc6c85885fea0491bef66b4a473eeb113a6b80aba0b719e91d928ab9dc2b658ebf632f2cb80babaf918002a5f44dd54565ab46
7
+ data.tar.gz: e8c36cf6761e02085bc28c925095b9581eb5f94718bab25ed7bf083bb8d1cb79c33f3a95249a051379aef29ab38ea623b38e8df194bccdb659ad2a183ef7b5b7
data/README.md CHANGED
@@ -15,7 +15,7 @@ for how to install Foreman plugins
15
15
 
16
16
  #### Inventory upload
17
17
 
18
- In UI: Configure -> Inventory Upload -> Restart
18
+ In UI: Insights -> Inventory Upload -> select the organization -> Generate and upload report
19
19
 
20
20
  From command-line:
21
21
 
@@ -38,7 +38,7 @@ From command-line:
38
38
 
39
39
  #### Fetch hosts remediation data
40
40
 
41
- In UI: Configure -> Insights -> Sync now
41
+ In UI: Insights -> Recommendations -> Sync recommendations (under the vertical ellipsis)
42
42
 
43
43
  From command-line:
44
44
 
@@ -46,7 +46,7 @@ From command-line:
46
46
 
47
47
  #### Synchronize inventory status
48
48
 
49
- In UI: Configure -> Inventory Upload -> Sync inventory status
49
+ In UI: Insights -> Inventory Upload -> Sync all inventory status
50
50
 
51
51
  From command-line:
52
52
 
@@ -16,29 +16,41 @@ module InsightsCloud::Api
16
16
  # The method that "proxies" requests over to Cloud
17
17
  def forward_request
18
18
  certs = candlepin_id_cert @organization
19
- @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
19
+ begin
20
+ @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
21
+ rescue RestClient::Exceptions::Timeout => e
22
+ response_obj = e.response.presence || e.exception
23
+ return render json: { message: response_obj.to_s, error: response_obj.to_s }, status: :gateway_timeout
24
+ rescue RestClient::Unauthorized => e
25
+ logger.warn("Forwarding request auth error: #{e}")
26
+ message = 'Authentication to the Insights Service failed.'
27
+ return render json: { message: message, error: message }, status: :unauthorized
28
+ rescue RestClient::NotModified => e
29
+ logger.info("Forwarding request not modified: #{e}")
30
+ message = 'Cloud request not modified'
31
+ return render json: { message: message, error: message }, status: :not_modified
32
+ rescue RestClient::ExceptionWithResponse => e
33
+ response_obj = e.response.presence || e.exception
34
+ code = response_obj.try(:code) || response_obj.try(:http_code) || 500
35
+ message = 'Cloud request failed'
20
36
 
21
- return render json: { message: @cloud_response.to_s }, status: :gateway_timeout if @cloud_response.is_a?(RestClient::Exceptions::OpenTimeout)
22
-
23
- if @cloud_response.code == 401
24
- return render json: {
25
- :message => 'Authentication to the Insights Service failed.',
26
- :headers => {},
27
- }, status: :bad_gateway
28
- end
29
-
30
- if @cloud_response.code >= 300
31
37
  return render json: {
32
- :message => 'Cloud request failed',
38
+ :message => message,
39
+ :error => response_obj.to_s,
33
40
  :headers => {},
34
- :response => @cloud_response,
35
- }, status: @cloud_response.code
41
+ :response => response_obj,
42
+ }, status: code
43
+ rescue StandardError => e
44
+ # Catch any other exceptions here, such as Errno::ECONNREFUSED
45
+ logger.warn("Cloud request failed with exception: #{e}")
46
+ return render json: { error: e.to_s }, status: :bad_gateway
36
47
  end
37
48
 
38
49
  # Append redhat-specific headers
39
50
  @cloud_response.headers.each do |key, value|
40
51
  assign_header(response, @cloud_response, key, false) if key.to_s.start_with?('x_rh_')
41
52
  end
53
+
42
54
  # Append general headers
43
55
  assign_header(response, @cloud_response, :x_resource_count, true)
44
56
  headers[Rack::ETAG] = @cloud_response.headers[:etag]
@@ -48,8 +60,8 @@ module InsightsCloud::Api
48
60
  # content type
49
61
  send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
50
62
  elsif @cloud_response.headers[:content_type] =~ /zip/
51
- # if there is no Content-Disposition, but the content type is binary according the content type,
52
- # forward the request as binry too
63
+ # If there is no Content-Disposition, but the content type is binary according to Content-Type, send the raw data
64
+ # with proper content type
53
65
  send_data @cloud_response, type: @cloud_response.headers[:content_type]
54
66
  else
55
67
  render json: @cloud_response, status: @cloud_response.code
@@ -13,9 +13,15 @@ module ForemanRhCloud
13
13
  logger.debug("Response headers for request url #{final_params[:url]} are: #{response.headers}")
14
14
 
15
15
  response
16
- rescue RestClient::Exception => ex
17
- logger.debug("Failed response with code #{ex.http_code} headers for request url #{final_params[:url]} are: #{ex.http_headers} and body: #{ex.http_body}")
18
- raise ex
16
+ rescue RestClient::Exceptions::Timeout => ex
17
+ logger.debug("Timeout exception raised for request url #{final_params[:url]}: #{ex}")
18
+ raise
19
+ rescue RestClient::ExceptionWithResponse => ex
20
+ logger.debug("Response headers for request url #{final_params[:url]} with status code #{ex.http_code} are: #{ex.http_headers} and body: #{ex.http_body}")
21
+ raise
22
+ rescue StandardError => ex
23
+ logger.debug("Exception raised for request url #{final_params[:url]}: #{ex}")
24
+ raise
19
25
  end
20
26
  end
21
27
  end
@@ -17,8 +17,6 @@ module ForemanRhCloud
17
17
  logger.debug("Sending request to: #{request_opts[:url]}")
18
18
 
19
19
  execute_cloud_request(request_opts)
20
- rescue RestClient::ExceptionWithResponse => error_response
21
- error_response.response.presence || error_response.exception
22
20
  end
23
21
 
24
22
  def prepare_request_opts(original_request, forward_payload, forward_params, certs)
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '10.0.5'.freeze
2
+ VERSION = '10.0.7'.freeze
3
3
  end
@@ -9,10 +9,11 @@ module InsightsCloud
9
9
 
10
10
  def plan(organizations)
11
11
  organizations = organizations.select do |organization|
12
- if cert_auth_available?(organization)
12
+ checker = ::Katello::UpstreamConnectionChecker.new(organization)
13
+ if cert_auth_available?(organization) && !organization.manifest_expired? && checker.can_connect?
13
14
  true
14
15
  else
15
- logger.debug("Certificate is not available for org: #{organization.name}, skipping insights sync")
16
+ logger.info("A manifest is not available for org: #{organization.name}, or it has expired, or been deleted. skipping insights sync")
16
17
  false
17
18
  end
18
19
  end
@@ -20,19 +21,23 @@ module InsightsCloud
20
21
  sequence do
21
22
  # This can be turned off when we enable automatic status syncs
22
23
  # This step will query cloud inventory to retrieve inventory uuids for each host
23
- plan_hosts_sync(organizations)
24
- plan_self(organization_ids: organizations.map(&:id))
25
- concurrence do
26
- plan_rules_sync(organizations)
27
- plan_notifications
24
+ valid_organizations = organizations.reject(&:manifest_expired?)
25
+ if valid_organizations.any?
26
+ plan_hosts_sync(organizations)
27
+ plan_self(organization_ids: organizations.map(&:id))
28
+ concurrence do
29
+ plan_rules_sync(organizations)
30
+ plan_notifications
31
+ end
28
32
  end
29
33
  end
30
34
  end
31
35
 
32
36
  def try_execute
33
37
  organizations.each do |organization|
34
- unless cert_auth_available?(organization)
35
- logger.debug("Certificate is not available for org: #{organization.name}, skipping insights sync")
38
+ checker = ::Katello::UpstreamConnectionChecker.new(organization)
39
+ if !cert_auth_available?(organization) && organization.manifest_expired && !checker.can_connect?
40
+ logger.info("A manifest is not available for org: #{organization.name}, or it has expired, or been deleted. skipping insights sync")
36
41
  next
37
42
  end
38
43
 
@@ -13,7 +13,11 @@ module InsightsCloud
13
13
  InsightsResolution.delete_all
14
14
  rule_ids = relevant_rules
15
15
  Organization.all.each do |organization|
16
- next if !cert_auth_available?(organization) || organization.manifest_expired?
16
+ checker = ::Katello::UpstreamConnectionChecker.new(organization)
17
+ if !cert_auth_available?(organization) || organization.manifest_expired? || !checker.can_connect?
18
+ logger.info("A manifest is not available for org: #{organization.name}, or it has expired, or been deleted. skipping resolutions sync")
19
+ next
20
+ end
17
21
  api_response = query_insights_resolutions(rule_ids, organization) unless rule_ids.empty?
18
22
  written_rules = write_resolutions(api_response) if api_response
19
23
  rule_ids -= Array(written_rules)
@@ -1,64 +1,132 @@
1
1
  require 'io/console'
2
+ require 'uri'
2
3
 
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.'
4
+ def logger
5
+ @logger ||= Logger.new(STDOUT)
6
+ end
7
+
8
+ namespace :rh_cloud do
9
+ desc 'Register Satellite Organization with Hybrid Cloud API.'
10
+ # This task registers the Satellite Organization with the Hybrid Cloud API.
11
+ # It requires the user to input their organization ID, Insights URL, and token.
12
+ # The task will then send a POST request to the Hybrid Cloud API to register the organization.
13
+ # The response will be logged, and any errors will be caught and logged as well.
14
+ # The task will exit with an error message if the organization does not have a manifest imported or if the token is not entered.
15
+ # The task will also log a warning if the custom URL is not set and the default one is used.
7
16
  task hybridcloud_register: [:environment] do
8
17
  include ::ForemanRhCloud::CertAuth
9
18
  include ::InsightsCloud::CandlepinCache
10
19
 
11
- def logger
12
- @logger ||= Logger.new(STDOUT)
20
+ def default_registrations_url
21
+ URI.join(ForemanRhCloud.base_url, '/api/identity/certificate/registrations').to_s
13
22
  end
14
23
 
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'
24
+ # Helper method to get the registrations URL, with a warning for default usage
25
+ def registrations_url(custom_url)
26
+ if custom_url.empty?
27
+ logger.warn("Custom url is not set, using the default one: #{default_registrations_url}")
28
+ default_registrations_url
29
+ else
30
+ if URI(custom_url).scheme.nil?
31
+ logger.warn("Custom URL lacks a scheme; prepending https:// prefix.")
32
+ custom_url = "https://" + custom_url
33
+ end
34
+ custom_url
35
+ end
18
36
  end
19
37
 
20
- if ENV['org_id'].nil?
21
- logger.error('ERROR: org_id needs to be specified.')
22
- exit(1)
38
+ def get_organization(user_org_id)
39
+ maybe_organization = Organization.find_by(id: user_org_id)
40
+ if maybe_organization.nil?
41
+ logger.error("Organization with ID '#{user_org_id}' not found.")
42
+ exit(1)
43
+ end
44
+ maybe_organization
23
45
  end
24
46
 
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
- }
47
+ def get_uid(organization)
48
+ maybe_uid = cp_owner_id(organization)
49
+ if maybe_uid.nil?
50
+ logger.error("Organization '#{organization}' does not have a manifest imported.")
51
+ exit(1)
52
+ end
53
+ maybe_uid
38
54
  end
39
55
 
40
- def payload
41
- {
42
- "uid": @uid,
43
- "display_name": "#{@hostname}+#{@organization.label}",
44
- }
56
+ # --- Input Collection ---
57
+ puts "Paste in your organization ID, this can be retrieved with the command: hammer organization list"
58
+ loop do
59
+ input = STDIN.gets.chomp
60
+ if input.match?(/^\d+$/) # Checks if input consists only of digits
61
+ @user_org_id = input.to_i
62
+ break
63
+ else
64
+ puts "Invalid input. Please enter a numeric organization ID."
65
+ end
45
66
  end
46
67
 
47
- def method
48
- :post
68
+ puts "\n" + "-" * 50 + "\n\n"
69
+ puts "Paste in your custom Insights URL. If nothing is entered, the default will be used (#{default_registrations_url})."
70
+ insights_user_input = STDIN.gets.chomp
71
+
72
+ puts "\n" + "-" * 50 + "\n\n"
73
+ puts 'Paste in your Hybrid Cloud API token, output will be hidden.'
74
+ puts 'This token can be retrieved from the Hybrid Cloud console.'
75
+ token = STDIN.noecho(&:gets).chomp
76
+ if token.empty?
77
+ logger.error('Token was not entered.')
78
+ exit(1)
49
79
  end
50
80
 
81
+ # --- Data Preparation ---
82
+
83
+ organization = get_organization(@user_org_id)
84
+ uid = get_uid(organization)
85
+ hostname = ForemanRhCloud.foreman_host_name
86
+ insights_url = registrations_url(insights_user_input)
87
+
88
+ # --- API Request ---
89
+
90
+ headers = {
91
+ Authorization: "Bearer #{token}",
92
+ }
93
+
94
+ payload = {
95
+ 'uid': uid,
96
+ "display_name": "#{hostname}+#{organization.label}",
97
+ }
98
+
51
99
  begin
52
100
  response = execute_cloud_request(
53
- organization: @organization,
54
- method: method,
55
- url: registrations_url,
101
+ organization: organization,
102
+ method: :post,
103
+ url: insights_url,
56
104
  headers: headers,
57
105
  payload: payload.to_json
58
106
  )
59
- logger.debug(response)
107
+ logger.debug("Cloud request completed: status=#{response.code}, body_preview=#{response.body&.slice(0, 200)}")
108
+ rescue RestClient::Unauthorized => _ex
109
+ # Add a more specific rescue for 401 Unauthorized errors
110
+ logger.error('Registration failed: Your token is invalid or unauthorized. Please check your token and try again.')
111
+ # Optionally, you can still log the full debug info if helpful for advanced troubleshooting
112
+ # logger.debug(ex.backtrace.join("\n"))
113
+ exit(1)
114
+ rescue RestClient::ExceptionWithResponse => ex
115
+ # This catches any RestClient exception that has a response (like 400, 403, 404, 500, etc.)
116
+ status_code = begin
117
+ ex.response.code
118
+ rescue StandardError
119
+ "unknown"
120
+ end
121
+ logger.error("Registration failed with HTTP status #{status_code}: #{ex.message}")
122
+ logger.debug("Response body (if available): #{ex.response.body}")
123
+ exit(1)
60
124
  rescue StandardError => ex
61
- logger.error(ex)
125
+ # This is the catch-all for any other unexpected errors
126
+ logger.error("An unexpected error occurred during registration: #{ex.message}")
127
+ exit(1)
62
128
  end
129
+
130
+ logger.info("Satellite Organization '#{organization.label}' (ID: #{@user_org_id}) successfully registered.")
63
131
  end
64
132
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "10.0.5",
3
+ "version": "10.0.7",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -96,13 +96,46 @@ module InsightsCloud::Api
96
96
  assert_equal net_http_resp[:content_type], @response.headers['Content-Type']
97
97
  end
98
98
 
99
+ test "should handle StandardError" do
100
+ error_message = "Connection refused"
101
+ ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:execute_cloud_request).raises(Errno::ECONNREFUSED.new)
102
+
103
+ get :forward_request, params: { "path" => "platform/module-update-router/v1/channel" }
104
+ assert_equal 502, @response.status
105
+ body = JSON.parse(@response.body)
106
+ assert_equal error_message, body['error']
107
+ end
108
+
109
+ test "should handle 304 cloud" do
110
+ net_http_resp = Net::HTTPResponse.new(1.0, 304, "Not Modified")
111
+ res = RestClient::Response.create(@body, net_http_resp, @http_req)
112
+
113
+ ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::NotModified.new(res))
114
+
115
+ get :forward_request, params: { "path" => "platform/module-update-router/v1/channel" }
116
+ assert_equal 304, @response.status
117
+ assert_equal 'Cloud request not modified', JSON.parse(@response.body)['message']
118
+ end
119
+
120
+ test "should handle RestClient::Exceptions::Timeout" do
121
+ timeout_message = "execution expired"
122
+ ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::Exceptions::Timeout.new(timeout_message))
123
+
124
+ get :forward_request, params: { "path" => "platform/module-update-router/v1/channel" }
125
+ assert_equal 504, @response.status
126
+ body = JSON.parse(@response.body)
127
+ assert_equal timeout_message, body['message']
128
+ assert_equal timeout_message, body['error']
129
+ end
130
+
99
131
  test "should handle failed authentication to cloud" do
100
132
  net_http_resp = Net::HTTPResponse.new(1.0, 401, "Unauthorized")
101
133
  res = RestClient::Response.create(@body, net_http_resp, @http_req)
102
- ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:forward_request).returns(res)
134
+
135
+ ::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::Unauthorized.new(res))
103
136
 
104
137
  get :forward_request, params: { "path" => "platform/module-update-router/v1/channel" }
105
- assert_equal 502, @response.status
138
+ assert_equal 401, @response.status
106
139
  assert_equal 'Authentication to the Insights Service failed.', JSON.parse(@response.body)['message']
107
140
  end
108
141
 
@@ -65,6 +65,8 @@ class InsightsFullSyncTest < ActiveSupport::TestCase
65
65
  end
66
66
 
67
67
  test 'Hits data is replaced with data from cloud' do
68
+ Organization.any_instance.stubs(:manifest_expired?).returns(false)
69
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
68
70
  InsightsCloud::Async::InsightsFullSync.any_instance.expects(:query_insights_hits).returns(@hits)
69
71
 
70
72
  InsightsCloud::Async::InsightsFullSync.any_instance.expects(:plan_hosts_sync)
@@ -79,7 +81,31 @@ class InsightsFullSyncTest < ActiveSupport::TestCase
79
81
  assert_equal 1, @host2.insights.hits.count
80
82
  end
81
83
 
84
+ test 'Manifest is expired do not run task steps' do
85
+ Organization.any_instance.stubs(:manifest_expired?).returns(true)
86
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
87
+
88
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:query_insights_hits).never
89
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:plan_hosts_sync).never
90
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:plan_self).never
91
+
92
+ ForemanTasks.sync_task(InsightsCloud::Async::InsightsFullSync, [@host1.organization])
93
+ end
94
+
95
+ test 'Manifest is deleted do not run task steps' do
96
+ Organization.any_instance.stubs(:manifest_expired?).returns(false)
97
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(false)
98
+
99
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:query_insights_hits).never
100
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:plan_hosts_sync).never
101
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:plan_self).never
102
+
103
+ ForemanTasks.sync_task(InsightsCloud::Async::InsightsFullSync, [@host1.organization])
104
+ end
105
+
82
106
  test 'Hits counters are reset correctly' do
107
+ Organization.any_instance.stubs(:manifest_expired?).returns(false)
108
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
83
109
  InsightsCloud::Async::InsightsFullSync.any_instance.expects(:query_insights_hits).returns(@hits).twice
84
110
 
85
111
  InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_hosts_sync)
@@ -97,6 +123,8 @@ class InsightsFullSyncTest < ActiveSupport::TestCase
97
123
  end
98
124
 
99
125
  test 'Hits ignoring non-existent hosts' do
126
+ Organization.any_instance.stubs(:manifest_expired?).returns(false)
127
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
100
128
  hits_json = <<-HITS_JSON
101
129
  [
102
130
  {
@@ -73,6 +73,7 @@ class InsightsResolutionsSyncTest < ActiveSupport::TestCase
73
73
  end
74
74
 
75
75
  test 'Resolutions data is replaced with data from cloud' do
76
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
76
77
  InsightsCloud::Async::InsightsResolutionsSync.any_instance.stubs(:query_insights_resolutions).returns(@resolutions)
77
78
 
78
79
  ForemanTasks.sync_task(InsightsCloud::Async::InsightsResolutionsSync)
@@ -82,7 +83,28 @@ class InsightsResolutionsSyncTest < ActiveSupport::TestCase
82
83
  assert_equal 2, @rule.resolutions.count
83
84
  end
84
85
 
86
+ test 'Manifest is deleted do not run task steps' do
87
+ Organization.any_instance.stubs(:manifest_expired?).returns(false)
88
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(false)
89
+ InsightsCloud::Async::InsightsResolutionsSync.any_instance.expects(:query_insights_resolutions).never
90
+
91
+ ForemanTasks.sync_task(InsightsCloud::Async::InsightsResolutionsSync)
92
+
93
+ assert_equal 0, InsightsResolution.all.count
94
+ end
95
+
96
+ test 'Manifest is expired do not run task steps' do
97
+ Organization.any_instance.stubs(:manifest_expired?).returns(true)
98
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
99
+ InsightsCloud::Async::InsightsResolutionsSync.any_instance.expects(:query_insights_resolutions).never
100
+
101
+ ForemanTasks.sync_task(InsightsCloud::Async::InsightsResolutionsSync)
102
+
103
+ assert_equal 0, InsightsResolution.all.count
104
+ end
105
+
85
106
  test 'Skips pinging the cloud if no rule ids were found' do
107
+ Katello::UpstreamConnectionChecker.any_instance.stubs(:can_connect?).returns(true)
86
108
  InsightsCloud::Async::InsightsResolutionsSync.any_instance.expects(:query_insights_resolutions).never
87
109
  InsightsRule.all.delete_all
88
110
 
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: 10.0.5
4
+ version: 10.0.7
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: 2025-04-07 00:00:00.000000000 Z
11
+ date: 2025-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foreman_ansible