foreman_rh_cloud 12.1.3 → 12.1.5
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/README.md +3 -5
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +33 -0
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -2
- data/app/controllers/insights_cloud/ui_requests_controller.rb +99 -0
- data/app/services/foreman_rh_cloud/cert_auth.rb +9 -1
- data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +12 -13
- data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +116 -0
- data/app/services/foreman_rh_cloud/tags_auth.rb +55 -0
- data/app/views/api/v2/hosts/insights/base.rabl +6 -0
- data/config/routes.rb +2 -0
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +11 -5
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +15 -4
- data/lib/foreman_inventory_upload/generators/archived_report.rb +2 -2
- data/lib/foreman_inventory_upload/generators/fact_helpers.rb +65 -13
- data/lib/foreman_inventory_upload/generators/queries.rb +7 -5
- data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
- data/lib/foreman_inventory_upload.rb +2 -2
- data/lib/foreman_rh_cloud/engine.rb +5 -3
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/insights_cloud.rb +8 -0
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
- data/lib/tasks/rh_cloud_inventory.rake +3 -2
- data/package.json +5 -1
- data/test/controllers/insights_cloud/ui_requests_controller_test.rb +169 -0
- data/test/unit/archived_report_generator_test.rb +1 -1
- data/test/unit/fact_helpers_test.rb +267 -2
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +20 -3
- data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +176 -0
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +29 -0
- data/test/unit/slice_generator_test.rb +69 -10
- data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +30 -10
- data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +18 -11
- data/webpack/CVEsHostDetailsTab/index.js +2 -2
- data/webpack/ForemanColumnExtensions/index.js +51 -0
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +1 -0
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +8 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +4 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +3 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +3 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +10 -4
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +6 -6
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +1 -0
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +3 -0
- data/webpack/ForemanRhCloudFills.js +6 -3
- data/webpack/ForemanRhCloudPages.js +6 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +2 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +1 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +3 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +12 -2
- data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -0
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +6 -1
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +21 -0
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js +20 -0
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +45 -0
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +28 -0
- data/webpack/common/DropdownToggle.js +1 -0
- data/webpack/common/ScalprumModule/ScalprumContext.js +63 -0
- data/webpack/common/Switcher/SwitcherPF4.js +1 -0
- data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
- data/webpack/common/Switcher/index.js +1 -0
- data/webpack/global_index.js +3 -0
- metadata +19 -4
- data/webpack/InsightsVulnerability/InsightsVulnerability.js +0 -13
- data/webpack/InsightsVulnerability/InsightsVulnerability.test.js +0 -18
@@ -57,17 +57,39 @@ module ForemanInventoryUpload
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def obfuscate_hostname?(host)
|
60
|
+
# Returns true if hostname obfuscation should be applied for a given host, based on hierarchy:
|
61
|
+
# 1. Global setting for hostname obfuscation.
|
62
|
+
return true if Setting[:obfuscate_inventory_hostnames]
|
63
|
+
|
60
64
|
insights_client_setting = fact_value(host, 'insights_client::obfuscate_hostname_enabled')
|
61
65
|
insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
|
62
|
-
return insights_client_setting unless insights_client_setting.nil?
|
63
66
|
|
64
|
-
|
67
|
+
# 2. host fact reported by insights_client
|
68
|
+
# 3. if neither of the above, don't obfuscate.
|
69
|
+
insights_client_setting.nil? ? false : insights_client_setting
|
65
70
|
end
|
66
71
|
|
67
72
|
def fqdn(host)
|
68
|
-
|
69
|
-
|
70
|
-
|
73
|
+
if obfuscate_hostname?(host)
|
74
|
+
# If obfuscation is enabled, attempt to retrieve an already obfuscated hostname
|
75
|
+
# from the 'insights_client::obfuscated_hostname' fact.
|
76
|
+
# Example format of `parsed_insights_array`:
|
77
|
+
# [{"original"=>"host.example.com", "obfuscated"=>"0dd449d0a027.example.com"},
|
78
|
+
# {"original"=>"satellite.example.com", "obfuscated"=>"host2.example.com"}]
|
79
|
+
begin
|
80
|
+
parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_hostname') || '[]')
|
81
|
+
rescue JSON::ParserError
|
82
|
+
parsed_insights_array = []
|
83
|
+
end
|
84
|
+
# Obfuscate using the following hierarchy:
|
85
|
+
# 1. the obfuscated_hostname fact sent by insights_client
|
86
|
+
parsed_insights_item = parsed_insights_array.find { |item| item['original'] == host.fqdn }
|
87
|
+
# 2. our own helper method
|
88
|
+
parsed_insights_item&.[]('obfuscated') || obfuscate_fqdn(host.fqdn)
|
89
|
+
else
|
90
|
+
# If hostname obfuscation is not enabled for this host, return the host's original FQDN.
|
91
|
+
host.fqdn
|
92
|
+
end
|
71
93
|
end
|
72
94
|
|
73
95
|
def obfuscate_fqdn(fqdn)
|
@@ -75,35 +97,65 @@ module ForemanInventoryUpload
|
|
75
97
|
end
|
76
98
|
|
77
99
|
def obfuscate_ips?(host)
|
78
|
-
|
79
|
-
|
80
|
-
return
|
100
|
+
# Returns true if IP obfuscation should be applied for a given host, based on hierarchy:
|
101
|
+
# 1. Global setting for IP obfuscation.
|
102
|
+
return true if Setting[:obfuscate_inventory_ips]
|
81
103
|
|
82
|
-
|
104
|
+
insights_client_ipv4_setting = fact_value(host, 'insights_client::obfuscate_ipv4_enabled')
|
105
|
+
insights_client_ipv6_setting = fact_value(host, 'insights_client::obfuscate_ipv6_enabled')
|
106
|
+
|
107
|
+
cast_ipv4_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv4_setting)
|
108
|
+
cast_ipv6_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv6_setting)
|
109
|
+
|
110
|
+
# 2. The host's IPv4 or IPv6 obfuscation fact value is true
|
111
|
+
# 3. If neither of the above, don't obfuscate.
|
112
|
+
cast_ipv4_setting || cast_ipv6_setting || false
|
83
113
|
end
|
84
114
|
|
85
115
|
def host_ips(host)
|
116
|
+
# Determines and returns the IP addresses associated with a host, applying obfuscation if enabled.
|
117
|
+
|
118
|
+
# If IP obfuscation is enabled for the host return a representation of obfuscated IP addresses.
|
86
119
|
return obfuscated_ips(host) if obfuscate_ips?(host)
|
87
120
|
|
88
|
-
#
|
121
|
+
# If IP obfuscation is NOT needed, return a special kind of Hash.
|
122
|
+
# where when you try to access a key in it
|
123
|
+
# if the key doesn't exist, it simply returns the key itself.
|
124
|
+
# This is useful because it means if you try to get an IP from this hash,
|
125
|
+
# you'll just get the original IP back. It allows the calling code to
|
126
|
+
# use the same interface whether obfuscation is applied or not.
|
89
127
|
Hash.new { |h, k| k }
|
90
128
|
end
|
91
129
|
|
92
130
|
def obfuscated_ips(host)
|
93
|
-
|
131
|
+
# Example format of `parsed_insights_array`:
|
132
|
+
# [{"original": "192.168.1.10", "obfuscated": "10.230.230.1"},
|
133
|
+
# {"original": "192.168.1.11", "obfuscated": "10.230.230.2"}]
|
134
|
+
begin
|
135
|
+
parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_ipv4') || '[]')
|
136
|
+
rescue JSON::ParserError
|
137
|
+
parsed_insights_array = []
|
138
|
+
end
|
94
139
|
|
140
|
+
# Create a new Hash to store the mapping from original IP addresses to their obfuscated versions.
|
141
|
+
# where the 'original' IP is the key and the 'obfuscated' IP is the value.
|
95
142
|
obfuscated_ips = Hash[
|
96
|
-
|
143
|
+
parsed_insights_array.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
|
97
144
|
]
|
98
145
|
|
146
|
+
# Sets a default proc for the obfuscated_ips hash.
|
147
|
+
# When a key is accessed that does not exist in the hash, this proc is called.
|
148
|
+
# It assigns the result of obfuscate_ip(key, hash) to the missing key in the hash.
|
149
|
+
# This ensures that any missing IP address key will be obfuscated and stored automatically.
|
99
150
|
obfuscated_ips.default_proc = proc do |hash, key|
|
100
151
|
hash[key] = obfuscate_ip(key, hash)
|
101
152
|
end
|
102
|
-
|
103
153
|
obfuscated_ips
|
104
154
|
end
|
105
155
|
|
106
156
|
def obfuscate_ip(ip, ips_dict)
|
157
|
+
# Produce a new, unique obfuscated IP that is
|
158
|
+
# numerically one greater than the highest existing obfuscated IP
|
107
159
|
max_obfuscated = ips_dict.values.map { |v| IPAddr.new(v).to_i }.max || IPAddr.new('10.230.230.0').to_i
|
108
160
|
|
109
161
|
IPAddr.new(max_obfuscated + 1, Socket::AF_INET).to_s
|
@@ -26,9 +26,11 @@ module ForemanInventoryUpload
|
|
26
26
|
'dmi::system::product_name',
|
27
27
|
'dmi::chassis::asset_tag',
|
28
28
|
'insights_client::obfuscate_hostname_enabled',
|
29
|
-
'insights_client::
|
30
|
-
'insights_client::
|
31
|
-
'insights_client::
|
29
|
+
'insights_client::obfuscate_ipv4_enabled',
|
30
|
+
'insights_client::obfuscate_ipv6_enabled',
|
31
|
+
'insights_client::obfuscated_ipv4',
|
32
|
+
'insights_client::obfuscated_ipv6',
|
33
|
+
'insights_client::obfuscated_hostname',
|
32
34
|
'insights_id',
|
33
35
|
'conversions::activity',
|
34
36
|
'conversions::packages::0::nevra',
|
@@ -58,8 +60,8 @@ module ForemanInventoryUpload
|
|
58
60
|
)
|
59
61
|
end
|
60
62
|
|
61
|
-
def self.for_org(organization_id, use_batches: true)
|
62
|
-
base_query = for_slice(Host.unscoped.where(organization_id: organization_id))
|
63
|
+
def self.for_org(organization_id, use_batches: true, hosts_query: '')
|
64
|
+
base_query = for_slice(Host.unscoped.where(organization_id: organization_id).search_for(hosts_query))
|
63
65
|
use_batches ? base_query.in_batches(of: ForemanInventoryUpload.slice_size) : base_query
|
64
66
|
end
|
65
67
|
end
|
@@ -190,7 +190,6 @@ module ForemanInventoryUpload
|
|
190
190
|
) { |v| os_release_value(*v) }
|
191
191
|
@stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
|
192
192
|
@stream.simple_field('arch', host.architecture&.name)
|
193
|
-
@stream.simple_field('katello_agent_running', false)
|
194
193
|
@stream.simple_field(
|
195
194
|
'infrastructure_type',
|
196
195
|
ActiveModel::Type::Boolean.new.cast(fact_value(host, 'virt::is_guest')) ? 'virtual' : 'physical'
|
@@ -52,8 +52,8 @@ module ForemanInventoryUpload
|
|
52
52
|
'uploader.sh'
|
53
53
|
end
|
54
54
|
|
55
|
-
def self.facts_archive_name(organization)
|
56
|
-
"report_for_#{organization}.tar.xz"
|
55
|
+
def self.facts_archive_name(organization, filter = nil)
|
56
|
+
"report_for_#{organization}#{filter.empty? ? nil : "[#{filter.to_s.parameterize}]"}.tar.xz"
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.upload_url
|
@@ -84,6 +84,7 @@ module ForemanRhCloud
|
|
84
84
|
'/foreman_rh_cloud/insights_cloud': [:index], # for bookmarks and later for showing the page
|
85
85
|
'insights_cloud/hits': [:index, :show, :auto_complete_search, :resolutions],
|
86
86
|
'insights_cloud/settings': [:index, :show],
|
87
|
+
'insights_cloud/ui_requests': [:forward_request],
|
87
88
|
'react': [:index],
|
88
89
|
},
|
89
90
|
:resource_type => ::InsightsHit.name
|
@@ -114,8 +115,7 @@ module ForemanRhCloud
|
|
114
115
|
caption: N_('Inventory Upload'),
|
115
116
|
url: '/foreman_rh_cloud/inventory_upload',
|
116
117
|
url_hash: { controller: :react, action: :index },
|
117
|
-
parent: :insights_menu
|
118
|
-
if: -> { !ForemanRhCloud.with_local_advisor_engine? }
|
118
|
+
parent: :insights_menu
|
119
119
|
menu :top_menu, :insights_hits, caption: N_('Recommendations'), url: '/foreman_rh_cloud/insights_cloud', url_hash: { controller: :react, action: :index }, parent: :insights_menu
|
120
120
|
menu :top_menu,
|
121
121
|
:insights_vulnerability,
|
@@ -165,6 +165,8 @@ module ForemanRhCloud
|
|
165
165
|
::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
|
166
166
|
|
167
167
|
::Host::Managed.include RhCloudHost
|
168
|
+
|
169
|
+
::Katello::Api::Rhsm::CandlepinDynflowProxyController.include InsightsCloud::PackageProfileUploadExtensions
|
168
170
|
end
|
169
171
|
end
|
170
172
|
|
@@ -198,7 +200,7 @@ module ForemanRhCloud
|
|
198
200
|
RemoteExecutionFeature.register(
|
199
201
|
:rh_cloud_connector_run_playbook,
|
200
202
|
N_('Run RH Cloud playbook'),
|
201
|
-
description: N_('Run playbook
|
203
|
+
description: N_('Run playbook generated by Red Hat remediations app'),
|
202
204
|
host_action_button: false,
|
203
205
|
provided_inputs: ['playbook_url', 'report_url', 'correlation_id', 'report_interval']
|
204
206
|
)
|
data/lib/insights_cloud.rb
CHANGED
@@ -21,6 +21,14 @@ module InsightsCloud
|
|
21
21
|
ForemanRhCloud.cert_base_url + '/api/remediations/v1/playbook'
|
22
22
|
end
|
23
23
|
|
24
|
+
def self.gateway_url
|
25
|
+
ForemanRhCloud.cert_base_url
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.ui_base_url
|
29
|
+
InsightsCloud.gateway_url
|
30
|
+
end
|
31
|
+
|
24
32
|
def self.remediation_rule_id(rule_id)
|
25
33
|
"advisor:#{rule_id}"
|
26
34
|
end
|
@@ -8,6 +8,8 @@ module InventorySync
|
|
8
8
|
set_callback :step, :around, :create_missing_hosts
|
9
9
|
|
10
10
|
def plan(organizations)
|
11
|
+
# Do not run for local advisor, since we use sub-man id to identify hosts.
|
12
|
+
return if ForemanRhCloud.with_local_advisor_engine?
|
11
13
|
# by default the tasks will be executed concurrently
|
12
14
|
super(organizations)
|
13
15
|
plan_self_host_sync
|
@@ -26,6 +26,7 @@ namespace :rh_cloud_inventory do
|
|
26
26
|
task generate: :environment do
|
27
27
|
organizations = [ENV['organization_id']]
|
28
28
|
base_folder = ENV['target'] || Dir.pwd
|
29
|
+
filter = ENV['hosts_filter']
|
29
30
|
|
30
31
|
unless File.writable?(base_folder)
|
31
32
|
puts "#{base_folder} is not writable by the current process"
|
@@ -40,9 +41,9 @@ namespace :rh_cloud_inventory do
|
|
40
41
|
|
41
42
|
User.as_anonymous_admin do
|
42
43
|
organizations.each do |organization|
|
43
|
-
target = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(organization))
|
44
|
+
target = File.join(base_folder, ForemanInventoryUpload.facts_archive_name(organization, filter))
|
44
45
|
archived_report_generator = ForemanInventoryUpload::Generators::ArchivedReport.new(target, Logger.new(STDOUT))
|
45
|
-
archived_report_generator.render(organization: organization)
|
46
|
+
archived_report_generator.render(organization: organization, filter: filter)
|
46
47
|
puts "Successfully generated #{target} for organization id #{organization}"
|
47
48
|
end
|
48
49
|
end
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "foreman_rh_cloud",
|
3
|
-
"version": "12.1.
|
3
|
+
"version": "12.1.5",
|
4
4
|
"description": "Inventory Upload =============",
|
5
5
|
"main": "index.js",
|
6
6
|
"scripts": {
|
@@ -21,6 +21,10 @@
|
|
21
21
|
"peerDependencies": {
|
22
22
|
"@theforeman/vendor": ">= 15.0.1"
|
23
23
|
},
|
24
|
+
"dependencies": {
|
25
|
+
"@scalprum/react-core": "^0.9.3",
|
26
|
+
"@scalprum/core": "^0.8.1"
|
27
|
+
},
|
24
28
|
"devDependencies": {
|
25
29
|
"@babel/core": "^7.7.0",
|
26
30
|
"@theforeman/builder": ">= 15.0.1",
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
require 'rest-client'
|
3
|
+
|
4
|
+
module InsightsCloud
|
5
|
+
class UIRequestsControllerTest < ActionController::TestCase
|
6
|
+
include KatelloCVEHelper
|
7
|
+
|
8
|
+
setup do
|
9
|
+
FactoryBot.create(:common_parameter, name: InsightsCloud.enable_client_param, key_type: 'boolean', value: true)
|
10
|
+
end
|
11
|
+
|
12
|
+
context '#forward_request' do
|
13
|
+
include MockCerts
|
14
|
+
|
15
|
+
setup do
|
16
|
+
@body = 'Cloud response body'
|
17
|
+
@http_req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org')
|
18
|
+
|
19
|
+
@org = FactoryBot.create(:organization)
|
20
|
+
@loc = FactoryBot.create(:location)
|
21
|
+
host = FactoryBot.create(:host, :with_subscription, :organization => @org)
|
22
|
+
User.current = ::Katello::CpConsumerUser.new(:uuid => host.subscription_facet.uuid, :login => host.subscription_facet.uuid)
|
23
|
+
InsightsCloud::UIRequestsController.any_instance.stubs(:upstream_owner).returns({ 'uuid' => 'abcdefg' })
|
24
|
+
ForemanRhCloud::TagsAuth.any_instance.stubs(:execute_cloud_request)
|
25
|
+
|
26
|
+
setup_certs_expectation do
|
27
|
+
ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:foreman_certificates)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
test "should respond with response from cloud" do
|
32
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
33
|
+
net_http_resp.add_field 'Set-Cookie', 'Monster'
|
34
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
35
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:forward_request).returns(res)
|
36
|
+
|
37
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
38
|
+
assert_equal @body, @response.body
|
39
|
+
end
|
40
|
+
|
41
|
+
test "should handle timeout from cloud" do
|
42
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.
|
43
|
+
stubs(:forward_request).
|
44
|
+
raises(RestClient::Exceptions::OpenTimeout.new("Timed out connecting to server"))
|
45
|
+
|
46
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
47
|
+
request_response = JSON.parse(@response.body)
|
48
|
+
# I can't get @response.status to take a nil value so I'm not asserting for that
|
49
|
+
|
50
|
+
assert_equal 'Timed out connecting to server', request_response['error']
|
51
|
+
end
|
52
|
+
|
53
|
+
test "should add headers to response from cloud" do
|
54
|
+
x_resource_count = '101'
|
55
|
+
x_rh_insights_request_id = '202'
|
56
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
57
|
+
net_http_resp['x_resource_count'] = x_resource_count
|
58
|
+
net_http_resp['x_rh_insights_request_id'] = x_rh_insights_request_id
|
59
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
60
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:forward_request).returns(res)
|
61
|
+
|
62
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
63
|
+
assert_equal x_resource_count, @response.headers['x-resource-count']
|
64
|
+
assert_equal x_rh_insights_request_id, @response.headers['x_rh_insights_request_id']
|
65
|
+
end
|
66
|
+
|
67
|
+
test "should extract path from original_fullpath when URL starts with insights_cloud" do
|
68
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
69
|
+
# Simulate a request with insights_cloud in the path
|
70
|
+
@request.stubs(:original_fullpath).returns('/insights_cloud/api/vulnerability/v1/cves?search=test')
|
71
|
+
|
72
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
73
|
+
::ForemanRhCloud::InsightsApiForwarder
|
74
|
+
.any_instance
|
75
|
+
.expects(:forward_request)
|
76
|
+
.returns(res)
|
77
|
+
.with { |_, path_to_forward| _(path_to_forward).must_equal('api/vulnerability/v1/cves') }
|
78
|
+
|
79
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
80
|
+
|
81
|
+
assert_equal @body, @response.body
|
82
|
+
end
|
83
|
+
|
84
|
+
test "should set etag header to response from cloud" do
|
85
|
+
etag = '12345'
|
86
|
+
req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org', :headers => { "If-None-Match": etag })
|
87
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
88
|
+
net_http_resp[Rack::ETAG] = etag
|
89
|
+
res = RestClient::Response.create(@body, net_http_resp, req)
|
90
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:forward_request).returns(res)
|
91
|
+
|
92
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
93
|
+
assert_equal etag, @response.headers[Rack::ETAG]
|
94
|
+
end
|
95
|
+
|
96
|
+
test "should set content type header to response from cloud" do
|
97
|
+
req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org')
|
98
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
99
|
+
net_http_resp[:content_type] = 'application/zip'
|
100
|
+
res = RestClient::Response.create(@body, net_http_resp, req)
|
101
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:forward_request).returns(res)
|
102
|
+
|
103
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
104
|
+
assert_equal net_http_resp[:content_type], @response.headers['Content-Type']
|
105
|
+
end
|
106
|
+
|
107
|
+
test "should handle StandardError" do
|
108
|
+
error_message = "Connection refused"
|
109
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:execute_cloud_request).raises(Errno::ECONNREFUSED.new)
|
110
|
+
|
111
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
112
|
+
assert_equal 502, @response.status
|
113
|
+
body = JSON.parse(@response.body)
|
114
|
+
assert_equal error_message, body['error']
|
115
|
+
end
|
116
|
+
|
117
|
+
test "should handle 304 cloud" do
|
118
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 304, "Not Modified")
|
119
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
120
|
+
|
121
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::NotModified.new(res))
|
122
|
+
|
123
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
124
|
+
assert_equal 304, @response.status
|
125
|
+
assert_equal 'Cloud request not modified', JSON.parse(@response.body)['message']
|
126
|
+
end
|
127
|
+
|
128
|
+
test "should handle RestClient::Exceptions::Timeout" do
|
129
|
+
timeout_message = "execution expired"
|
130
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::Exceptions::Timeout.new(timeout_message))
|
131
|
+
|
132
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
133
|
+
assert_equal 504, @response.status
|
134
|
+
body = JSON.parse(@response.body)
|
135
|
+
assert_equal timeout_message, body['message']
|
136
|
+
assert_equal timeout_message, body['error']
|
137
|
+
end
|
138
|
+
|
139
|
+
test "should handle failed authentication to cloud" do
|
140
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 401, "Unauthorized")
|
141
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
142
|
+
|
143
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::Unauthorized.new(res))
|
144
|
+
|
145
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
146
|
+
assert_equal 401, @response.status
|
147
|
+
assert_equal 'Authentication to the Insights Service failed.', JSON.parse(@response.body)['message']
|
148
|
+
end
|
149
|
+
|
150
|
+
test "should forward errors to the client" do
|
151
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 500, "TEST_RESPONSE")
|
152
|
+
res = RestClient::Response.create(@body, net_http_resp, @http_req)
|
153
|
+
::ForemanRhCloud::InsightsApiForwarder.any_instance.stubs(:execute_cloud_request).raises(RestClient::InternalServerError.new(res))
|
154
|
+
|
155
|
+
get :forward_request, params: { "controller" => "vulnerabilities", "path" => "api/vulnerability/v1/cves" }, session: set_session
|
156
|
+
assert_equal 500, @response.status
|
157
|
+
assert_equal 'Cloud request failed', JSON.parse(@response.body)['message']
|
158
|
+
assert_match(/#{@body}/, JSON.parse(@response.body)['response'])
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def set_session
|
163
|
+
set_session_user.merge(
|
164
|
+
organization_id: @org.id,
|
165
|
+
location_id: @loc.id
|
166
|
+
)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -50,7 +50,7 @@ class ArchivedReportGeneratorTest < ActiveSupport::TestCase
|
|
50
50
|
batches = Host.where(id: @host.id).in_batches
|
51
51
|
test_org = FactoryBot.create(:organization)
|
52
52
|
|
53
|
-
ForemanInventoryUpload::Generators::Queries.expects(:for_org).with(test_org.id).returns(batches)
|
53
|
+
ForemanInventoryUpload::Generators::Queries.expects(:for_org).with(test_org.id, hosts_query: '').returns(batches)
|
54
54
|
ForemanInventoryUpload::Generators::Slice.any_instance.stubs(:golden_ticket?).returns(false)
|
55
55
|
Dir.mktmpdir do |tmpdir|
|
56
56
|
target = File.join(tmpdir, 'test.tar.gz')
|