foreman_rh_cloud 12.2.1 → 12.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/rh_cloud/advisor_engine_config_controller.rb +1 -1
- data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +3 -0
- data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +3 -0
- data/app/controllers/concerns/foreman_rh_cloud/iop_smart_proxy_access.rb +28 -0
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +3 -0
- data/app/controllers/foreman_rh_cloud/foreman_rh_cloud_controller.rb +22 -0
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +19 -5
- data/app/models/foreman_rh_cloud/ping.rb +90 -0
- data/app/services/foreman_rh_cloud/cert_auth.rb +1 -1
- data/app/services/foreman_rh_cloud/cloud_request.rb +1 -1
- data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -1
- data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +27 -10
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +14 -12
- data/app/services/foreman_rh_cloud/tags_auth.rb +3 -2
- data/app/views/api/v2/hosts/insights/base.rabl +2 -2
- data/app/views/api/v2/hosts/insights/single.rabl +1 -1
- data/config/routes.rb +6 -14
- data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +2 -2
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +1 -1
- data/lib/foreman_inventory_upload/generators/slice.rb +24 -0
- data/lib/foreman_rh_cloud/engine.rb +6 -2
- data/lib/foreman_rh_cloud/plugin.rb +18 -2
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +5 -6
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +2 -2
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +1 -1
- data/lib/inventory_sync/async/inventory_scheduled_sync.rb +2 -2
- data/lib/tasks/insights.rake +1 -1
- data/lib/tasks/rh_cloud_inventory.rake +20 -2
- data/package.json +1 -1
- data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +20 -3
- data/test/controllers/insights_sync/settings_controller_test.rb +1 -1
- data/test/factories/inventory_upload_factories.rb +4 -112
- data/test/jobs/inventory_scheduled_sync_test.rb +3 -3
- data/test/test_plugin_helper.rb +8 -2
- data/test/unit/rh_cloud_http_proxy_test.rb +3 -3
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +4 -1
- data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +43 -2
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +15 -1
- data/test/unit/slice_generator_test.rb +33 -0
- data/test/unit/tags_generator_test.rb +4 -1
- data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +1 -1
- data/webpack/CveDetailsPage/CveDetailsPage.js +1 -1
- data/webpack/CveDetailsPage/CveDetailsPage.test.js +1 -3
- data/webpack/ForemanColumnExtensions/index.js +1 -1
- data/webpack/ForemanRhCloudPages.js +1 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +26 -4
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +85 -11
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +39 -5
- data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +13 -0
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +9 -7
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +12 -10
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +1 -1
- data/webpack/IopRecommendationDetails/IopRecommendationDetails.js +1 -1
- data/webpack/common/Hooks/ConfigHooks.js +1 -2
- data/webpack/common/styles.scss +7 -0
- metadata +5 -1
@@ -13,7 +13,7 @@ module InsightsCloud
|
|
13
13
|
return
|
14
14
|
end
|
15
15
|
|
16
|
-
if ForemanRhCloud.
|
16
|
+
if ForemanRhCloud.with_iop_smart_proxy?
|
17
17
|
plan_self
|
18
18
|
else
|
19
19
|
after_delay do
|
@@ -23,7 +23,7 @@ module InsightsCloud
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def run
|
26
|
-
output[:status] = _('The scheduled process is disabled because this Foreman is configured with
|
26
|
+
output[:status] = _('The scheduled process is disabled because this Foreman is configured with a local IoP Smart Proxy.') if ForemanRhCloud.with_iop_smart_proxy?
|
27
27
|
end
|
28
28
|
|
29
29
|
def plan_full_sync
|
@@ -9,7 +9,7 @@ module InventorySync
|
|
9
9
|
|
10
10
|
def plan(organizations)
|
11
11
|
# Do not run for local advisor, since we use sub-man id to identify hosts.
|
12
|
-
return if ForemanRhCloud.
|
12
|
+
return if ForemanRhCloud.with_iop_smart_proxy?
|
13
13
|
# by default the tasks will be executed concurrently
|
14
14
|
super(organizations)
|
15
15
|
plan_self_host_sync
|
@@ -13,7 +13,7 @@ module InventorySync
|
|
13
13
|
return
|
14
14
|
end
|
15
15
|
|
16
|
-
if ForemanRhCloud.
|
16
|
+
if ForemanRhCloud.with_iop_smart_proxy?
|
17
17
|
plan_self # so that 'run' runs
|
18
18
|
else
|
19
19
|
after_delay do
|
@@ -35,7 +35,7 @@ module InventorySync
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def run
|
38
|
-
output[:status] = _('The scheduled process is disabled because this Foreman is configured with
|
38
|
+
output[:status] = _('The scheduled process is disabled because this Foreman is configured with a local IoP Smart Proxy.') if ForemanRhCloud.with_iop_smart_proxy?
|
39
39
|
end
|
40
40
|
|
41
41
|
def plan_remove_insights_hosts(org_id)
|
data/lib/tasks/insights.rake
CHANGED
@@ -24,7 +24,7 @@ namespace :rh_cloud_insights do
|
|
24
24
|
desc "Re-announce all organizations into Sources on RH cloud."
|
25
25
|
task announce_to_sources: [:environment] do
|
26
26
|
logger = Logging::Logger.new(STDOUT)
|
27
|
-
if ForemanRhCloud.
|
27
|
+
if ForemanRhCloud.with_iop_smart_proxy?
|
28
28
|
logger.warn('Task announce_to_sources is not available when using local advisor engine')
|
29
29
|
else
|
30
30
|
Organization.unscoped.each do |org|
|
@@ -9,7 +9,7 @@ namespace :rh_cloud_inventory do
|
|
9
9
|
else
|
10
10
|
organizations = [Organization.where(:id => ENV['organization_id']).first]
|
11
11
|
end
|
12
|
-
disconnected = ForemanRhCloud.
|
12
|
+
disconnected = ForemanRhCloud.with_iop_smart_proxy?
|
13
13
|
User.as_anonymous_admin do
|
14
14
|
organizations.each do |organization|
|
15
15
|
ForemanTasks.async_task(
|
@@ -45,6 +45,24 @@ namespace :rh_cloud_inventory do
|
|
45
45
|
archived_report_generator = ForemanInventoryUpload::Generators::ArchivedReport.new(target, Logger.new(STDOUT))
|
46
46
|
archived_report_generator.render(organization: organization, filter: filter)
|
47
47
|
puts "Successfully generated #{target} for organization id #{organization}"
|
48
|
+
|
49
|
+
next unless ForemanRhCloud.with_iop_smart_proxy?
|
50
|
+
|
51
|
+
puts 'Creating missing insights facets'
|
52
|
+
hosts_without_facets = ForemanInventoryUpload::Generators::Queries.for_org(organization, hosts_query: 'null? insights_uuid')
|
53
|
+
hosts_without_facets.each do |batch|
|
54
|
+
facets = batch.pluck(:id, 'katello_subscription_facets.uuid').map do |host_id, uuid|
|
55
|
+
{
|
56
|
+
host_id: host_id,
|
57
|
+
uuid: uuid,
|
58
|
+
}
|
59
|
+
end
|
60
|
+
# We don't need to validate the facets here as we create the necessary fields.
|
61
|
+
# rubocop:disable Rails/SkipsModelValidations
|
62
|
+
InsightsFacet.upsert_all(facets, unique_by: :host_id) unless facets.empty?
|
63
|
+
# rubocop:enable Rails/SkipsModelValidations
|
64
|
+
end
|
65
|
+
puts 'Missing Insights facets created'
|
48
66
|
end
|
49
67
|
end
|
50
68
|
end
|
@@ -53,7 +71,7 @@ namespace :rh_cloud_inventory do
|
|
53
71
|
base_folder = ENV['target'] || ForemanInventoryUpload.generated_reports_folder
|
54
72
|
organization_id = ENV['organization_id']
|
55
73
|
report_file = ForemanInventoryUpload.facts_archive_name(organization_id)
|
56
|
-
disconnected = ForemanRhCloud.
|
74
|
+
disconnected = ForemanRhCloud.with_iop_smart_proxy?
|
57
75
|
ForemanTasks.sync_task(ForemanInventoryUpload::Async::QueueForUploadJob, base_folder, report_file, organization_id, disconnected)
|
58
76
|
puts "Uploaded #{report_file}"
|
59
77
|
end
|
data/package.json
CHANGED
@@ -17,8 +17,8 @@ module InsightsCloud::Api
|
|
17
17
|
@http_req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org')
|
18
18
|
|
19
19
|
org = FactoryBot.create(:organization)
|
20
|
-
host = FactoryBot.create(:host, :with_subscription, :organization => org)
|
21
|
-
User.current = ::Katello::CpConsumerUser.new(:uuid => host.subscription_facet.uuid, :login => host.subscription_facet.uuid)
|
20
|
+
@host = FactoryBot.create(:host, :with_subscription, :organization => org)
|
21
|
+
User.current = ::Katello::CpConsumerUser.new(:uuid => @host.subscription_facet.uuid, :login => @host.subscription_facet.uuid)
|
22
22
|
InsightsCloud::Api::MachineTelemetriesController.any_instance.stubs(:upstream_owner).returns({ 'uuid' => 'abcdefg' })
|
23
23
|
|
24
24
|
setup_certs_expectation do
|
@@ -151,6 +151,20 @@ module InsightsCloud::Api
|
|
151
151
|
assert_equal 'Cloud request failed', JSON.parse(@response.body)['message']
|
152
152
|
assert_match /#{@body}/, JSON.parse(@response.body)['response']
|
153
153
|
end
|
154
|
+
|
155
|
+
test "should create insights facet" do
|
156
|
+
assert_nil InsightsFacet.find_by(host_id: @host.id)
|
157
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
158
|
+
req = RestClient::Request.new(:method => 'GET', :url => 'http://test.theforeman.org/')
|
159
|
+
net_http_resp = Net::HTTPResponse.new(1.0, 200, "OK")
|
160
|
+
net_http_resp[:content_type] = 'application/zip'
|
161
|
+
res = RestClient::Response.create(@body, net_http_resp, req)
|
162
|
+
::ForemanRhCloud::CloudRequestForwarder.any_instance.stubs(:forward_request).returns(res)
|
163
|
+
|
164
|
+
get :forward_request, params: { "path" => "/redhat_access/r/insights/uploads/" }
|
165
|
+
|
166
|
+
assert_not_nil InsightsFacet.find_by(host_id: @host.id)
|
167
|
+
end
|
154
168
|
end
|
155
169
|
|
156
170
|
context '#branch_info' do
|
@@ -166,7 +180,10 @@ module InsightsCloud::Api
|
|
166
180
|
:with_content,
|
167
181
|
:with_hostgroup,
|
168
182
|
:with_parameter,
|
169
|
-
|
183
|
+
content_facet: FactoryBot.build(
|
184
|
+
:content_facet,
|
185
|
+
content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
|
186
|
+
),
|
170
187
|
organization: env.organization
|
171
188
|
)
|
172
189
|
|
@@ -3,7 +3,7 @@ require 'test_plugin_helper'
|
|
3
3
|
class SettingsControllerTest < ActionController::TestCase
|
4
4
|
tests InsightsCloud::SettingsController
|
5
5
|
def setup
|
6
|
-
ForemanRhCloud.stubs(:
|
6
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
7
7
|
end
|
8
8
|
|
9
9
|
test 'should return allow_auto_insights_sync setting' do
|
@@ -1,87 +1,3 @@
|
|
1
|
-
# redefine katello factories, as long as katello is not compatible with dynamic properties
|
2
|
-
FactoryBot.define do
|
3
|
-
factory :katello_organization, :class => "Organization" do
|
4
|
-
type { "Organization" }
|
5
|
-
sequence(:name) { |n| "Organization#{n}" }
|
6
|
-
sequence(:label) { |n| "org#{n}" }
|
7
|
-
sequence(:id) { |n| n }
|
8
|
-
|
9
|
-
trait :acme_corporation do
|
10
|
-
name { "ACME_Corporation" }
|
11
|
-
type { "Organization" }
|
12
|
-
description { "This is the first Organization." }
|
13
|
-
label { "acme_corporation_label" }
|
14
|
-
end
|
15
|
-
|
16
|
-
trait :with_library do
|
17
|
-
association :library, :factory => :katello_library
|
18
|
-
end
|
19
|
-
|
20
|
-
factory :acme_corporation, :traits => [:acme_corporation]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
FactoryBot.define do
|
25
|
-
factory :katello_content_view, :class => Katello::ContentView do
|
26
|
-
sequence(:name) { |n| "Database#{n}" }
|
27
|
-
description { "This content view is for database content" }
|
28
|
-
association :organization, :factory => :katello_organization
|
29
|
-
|
30
|
-
trait :composite do
|
31
|
-
composite { true }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
FactoryBot.define do
|
37
|
-
factory :katello_content_view_environment, :class => Katello::ContentViewEnvironment do
|
38
|
-
sequence(:name) { |n| "name#{n}" }
|
39
|
-
sequence(:label) { |n| "label#{n}" }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
FactoryBot.define do
|
44
|
-
factory :katello_k_t_environment, :aliases => [:katello_environment], :class => Katello::KTEnvironment do
|
45
|
-
sequence(:name) { |n| "Environment#{n}" }
|
46
|
-
sequence(:label) { |n| "environment#{n}" }
|
47
|
-
association :organization, :factory => :katello_organization
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
FactoryBot.define do
|
52
|
-
factory :katello_content_facets, :aliases => [:content_facet], :class => ::Katello::Host::ContentFacet do
|
53
|
-
sequence(:uuid) { |n| "uuid-#{n}" }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
FactoryBot.define do
|
58
|
-
factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
|
59
|
-
sequence(:uuid) { |n| "00000000-%<n>04d-%<r>04d-0000-000000000000" % { n: n, r: rand(500) } }
|
60
|
-
facts { { 'memory.memtotal' => "12 GB" } }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
FactoryBot.define do
|
65
|
-
factory :katello_subscription, :class => Katello::Subscription do
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
FactoryBot.define do
|
70
|
-
factory :katello_pool, :class => Katello::Pool do
|
71
|
-
active { true }
|
72
|
-
end_date { Date.today + 1.year }
|
73
|
-
cp_id { 1 }
|
74
|
-
|
75
|
-
association :organization, :factory => :katello_organization
|
76
|
-
|
77
|
-
after(:build) do |pool, _evaluator|
|
78
|
-
pool.subscription.organization = pool.organization
|
79
|
-
end
|
80
|
-
|
81
|
-
association :subscription, :factory => :katello_subscription
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
1
|
FactoryBot.define do
|
86
2
|
factory :katello_host_collection_host, :class => Katello::HostCollectionHosts do
|
87
3
|
host_id { nil }
|
@@ -94,34 +10,10 @@ FactoryBot.define do
|
|
94
10
|
end
|
95
11
|
end
|
96
12
|
|
13
|
+
# Fix Katello factories to return a valid UUID
|
97
14
|
FactoryBot.modify do
|
98
|
-
factory :
|
99
|
-
|
100
|
-
|
101
|
-
lifecycle_environment { nil }
|
102
|
-
content_source { nil }
|
103
|
-
content_view_environments { [] }
|
104
|
-
end
|
105
|
-
|
106
|
-
trait :with_content do
|
107
|
-
association :content_facet, :factory => :content_facet, :strategy => :build
|
108
|
-
|
109
|
-
after(:build) do |host, evaluator|
|
110
|
-
if host.content_facet
|
111
|
-
if evaluator.content_view && evaluator.lifecycle_environment
|
112
|
-
host.content_facet.assign_single_environment(
|
113
|
-
content_view_id: evaluator.content_view.id,
|
114
|
-
lifecycle_environment_id: evaluator.lifecycle_environment.id
|
115
|
-
)
|
116
|
-
end
|
117
|
-
host.content_facet.content_source = evaluator.content_source if evaluator.content_source
|
118
|
-
host.content_facet.content_view_environments = evaluator.content_view_environments unless evaluator.content_view_environments.empty?
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
trait :with_subscription do
|
124
|
-
association :subscription_facet, :factory => :subscription_facet, :strategy => :build
|
125
|
-
end
|
15
|
+
factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
|
16
|
+
sequence(:uuid) { |n| "00000000-%<n>04d-%<r>04d-0000-000000000000" % { n: n, r: rand(500) } }
|
17
|
+
facts { { 'memory.memtotal' => "12 GB" } }
|
126
18
|
end
|
127
19
|
end
|
@@ -14,14 +14,14 @@ class InventoryScheduledSyncTest < ActiveSupport::TestCase
|
|
14
14
|
ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
|
15
15
|
end
|
16
16
|
|
17
|
-
test 'Skips execution if
|
18
|
-
ForemanRhCloud.stubs(:
|
17
|
+
test 'Skips execution if with_iop_smart_proxy? is true' do
|
18
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
19
19
|
|
20
20
|
InventorySync::Async::InventoryScheduledSync.any_instance.expects(:plan_org_sync).never
|
21
21
|
|
22
22
|
task = ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
|
23
23
|
status = task.output[:status].to_s
|
24
|
-
assert_match(/Foreman is configured with
|
24
|
+
assert_match(/Foreman is configured with a local IoP Smart Proxy/, status)
|
25
25
|
end
|
26
26
|
|
27
27
|
test 'Skips execution if auto upload is disabled' do
|
data/test/test_plugin_helper.rb
CHANGED
@@ -2,10 +2,16 @@
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
# Add plugin to FactoryBot's paths
|
5
|
-
|
5
|
+
katello_files = Dir.glob("#{Katello::Engine.root}/test/factories/**/*.rb")
|
6
|
+
FactoryBot.definition_file_paths +=
|
7
|
+
katello_files
|
8
|
+
# skip foreman_task factories, since we already have those definitions in ForemanTasks
|
9
|
+
.reject { |f| f =~ /foreman_task|recurring_logic/ }
|
10
|
+
.map { |f| f.gsub('.rb', '') } # .rb extension is will be appended by factorybot
|
6
11
|
FactoryBot.definition_file_paths << "#{ForemanRemoteExecution::Engine.root}/test/factories"
|
12
|
+
FactoryBot.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
|
13
|
+
|
7
14
|
FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
|
8
|
-
# FactoryBot.definition_file_paths << "#{Katello::Engine.root}/test/factories"
|
9
15
|
FactoryBot.reload
|
10
16
|
|
11
17
|
begin
|
@@ -4,7 +4,7 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
|
|
4
4
|
setup do
|
5
5
|
@global_content_proxy_mock = 'http://global:content@localhost:80'
|
6
6
|
@global_foreman_proxy_mock = 'http://global:foreman@localhost:80'
|
7
|
-
ForemanRhCloud.stubs(:
|
7
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
8
8
|
end
|
9
9
|
|
10
10
|
test 'selects global content proxy' do
|
@@ -20,8 +20,8 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
test 'returns empty string in on-prem setup' do
|
23
|
-
ForemanRhCloud.unstub(:
|
24
|
-
ForemanRhCloud.stubs(:
|
23
|
+
ForemanRhCloud.unstub(:with_iop_smart_proxy?)
|
24
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
25
25
|
|
26
26
|
assert_empty ForemanRhCloud.proxy_setting
|
27
27
|
end
|
@@ -22,7 +22,10 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
|
|
22
22
|
:with_content,
|
23
23
|
:with_hostgroup,
|
24
24
|
:with_parameter,
|
25
|
-
|
25
|
+
content_facet: FactoryBot.build(
|
26
|
+
:content_facet,
|
27
|
+
content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
|
28
|
+
),
|
26
29
|
organization: env.organization
|
27
30
|
)
|
28
31
|
|
@@ -32,7 +32,7 @@ class UIRequestForwarderTest < ActiveSupport::TestCase
|
|
32
32
|
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
|
33
33
|
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
34
34
|
actual = actual_params[:headers][:params]
|
35
|
-
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :
|
35
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tags && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
|
36
36
|
true
|
37
37
|
end
|
38
38
|
|
@@ -82,7 +82,7 @@ class UIRequestForwarderTest < ActiveSupport::TestCase
|
|
82
82
|
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
|
83
83
|
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
84
84
|
actual = actual_params[:headers][:params]
|
85
|
-
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :
|
85
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tags && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
|
86
86
|
assert_equal 5, actual.find { |param| param[0] == :page }[1]
|
87
87
|
assert_equal 42, actual.find { |param| param[0] == :per_page }[1]
|
88
88
|
true
|
@@ -160,6 +160,47 @@ class UIRequestForwarderTest < ActiveSupport::TestCase
|
|
160
160
|
# This is done by setting the expectation before the actual call.
|
161
161
|
end
|
162
162
|
|
163
|
+
test 'scope_request? should return tag_name for scoped requests' do
|
164
|
+
get_req = ActionDispatch::Request.new(
|
165
|
+
'REQUEST_URI' => '/api/vulnerability/v1/vulnerabilities/cves',
|
166
|
+
'REQUEST_METHOD' => 'GET',
|
167
|
+
'rack.input' => ::Puma::NullIO.new
|
168
|
+
)
|
169
|
+
|
170
|
+
result = @forwarder.send(:scope_request?, get_req, 'api/vulnerability/v1/vulnerabilities/cves')
|
171
|
+
assert_equal :tags, result
|
172
|
+
end
|
173
|
+
|
174
|
+
test 'scope_request? should return nil for non-GET requests' do
|
175
|
+
post_req = ActionDispatch::Request.new(
|
176
|
+
'REQUEST_URI' => '/api/vulnerability/v1/cves',
|
177
|
+
'REQUEST_METHOD' => 'POST',
|
178
|
+
'rack.input' => ::Puma::NullIO.new
|
179
|
+
)
|
180
|
+
|
181
|
+
result = @forwarder.send(:scope_request?, post_req, '/api/vulnerability/v1/cves')
|
182
|
+
assert_nil result
|
183
|
+
end
|
184
|
+
|
185
|
+
test 'scope_request? should return nil for unmatched paths' do
|
186
|
+
get_req = ActionDispatch::Request.new(
|
187
|
+
'REQUEST_URI' => '/api/unmatched/path',
|
188
|
+
'REQUEST_METHOD' => 'GET',
|
189
|
+
'rack.input' => ::Puma::NullIO.new
|
190
|
+
)
|
191
|
+
|
192
|
+
result = @forwarder.send(:scope_request?, get_req, '/api/unmatched/path')
|
193
|
+
assert_nil result
|
194
|
+
end
|
195
|
+
|
196
|
+
test 'prepare_tags should use provided tag_name' do
|
197
|
+
result = @forwarder.send(:prepare_tags, @user, @organization, @location, :custom_tag)
|
198
|
+
|
199
|
+
assert_equal 1, result.length
|
200
|
+
assert_equal :custom_tag, result[0][0]
|
201
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(result[0][1])
|
202
|
+
end
|
203
|
+
|
163
204
|
def tag_value(param_value)
|
164
205
|
return param_value unless param_value.is_a?(String)
|
165
206
|
|
@@ -10,7 +10,7 @@ class TagsAuthTest < ActiveSupport::TestCase
|
|
10
10
|
@auth = ::ForemanRhCloud::TagsAuth.new(@user, @org, @loc, @logger)
|
11
11
|
end
|
12
12
|
|
13
|
-
test 'Generates tags update request' do
|
13
|
+
test 'Generates tags update request when hosts are present' do
|
14
14
|
uuid1 = 'test_uuid1'
|
15
15
|
uuid2 = 'test_uuid2'
|
16
16
|
|
@@ -26,4 +26,18 @@ class TagsAuthTest < ActiveSupport::TestCase
|
|
26
26
|
|
27
27
|
@auth.update_tag
|
28
28
|
end
|
29
|
+
|
30
|
+
test 'Should not execute cloud request when no hosts are present' do
|
31
|
+
@auth.expects(:allowed_hosts).returns([])
|
32
|
+
@auth.expects(:execute_cloud_request).never
|
33
|
+
|
34
|
+
@auth.update_tag
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'Should not execute cloud request when allowed_hosts is nil' do
|
38
|
+
@auth.expects(:allowed_hosts).returns(nil)
|
39
|
+
@auth.expects(:execute_cloud_request).never
|
40
|
+
|
41
|
+
@auth.update_tag
|
42
|
+
end
|
29
43
|
end
|
@@ -998,6 +998,39 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
998
998
|
assert_not_nil actual_host['insights_id']
|
999
999
|
end
|
1000
1000
|
|
1001
|
+
test 'reports yum repos' do
|
1002
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
1003
|
+
FactoryBot.create(:katello_content, cp_content_id: '1', organization: @host.organization, name: 'Test Content', label: 'test-content')
|
1004
|
+
repo = FactoryBot.build(
|
1005
|
+
:katello_repository,
|
1006
|
+
:fedora_17_x86_64_dev,
|
1007
|
+
:with_content_view,
|
1008
|
+
product: FactoryBot.create(:katello_product, :redhat, :with_provider, organization: @host.organization)
|
1009
|
+
)
|
1010
|
+
# force-save the root repo to avoid validation errors
|
1011
|
+
repo.root.save(validate: false)
|
1012
|
+
repo.save(validate: false)
|
1013
|
+
@host.content_facet.bound_repositories << repo
|
1014
|
+
@host.content_facet.content_source = FactoryBot.create(:smart_proxy, :with_pulp3)
|
1015
|
+
@host.save(validate: false)
|
1016
|
+
|
1017
|
+
batch = Host.where(id: @host.id).in_batches.first
|
1018
|
+
generator = create_generator(batch)
|
1019
|
+
json_str = generator.render
|
1020
|
+
actual = JSON.parse(json_str.join("\n"))
|
1021
|
+
|
1022
|
+
assert_not_nil(actual_host = actual['hosts'].first)
|
1023
|
+
assert_not_nil(actual_system_profile = actual_host['system_profile'])
|
1024
|
+
assert_not_nil(actual_yum_repos = actual_system_profile['yum_repos'])
|
1025
|
+
assert_equal 1, actual_yum_repos.count
|
1026
|
+
assert_not_nil(actual_yum_repo = actual_yum_repos.first)
|
1027
|
+
assert_equal 'Test Content', actual_yum_repo['name']
|
1028
|
+
assert_equal 'test-content', actual_yum_repo['id']
|
1029
|
+
assert_match(/fedora_17/, actual_yum_repo['base_url'])
|
1030
|
+
assert_equal true, actual_yum_repo['enabled']
|
1031
|
+
assert_equal true, actual_yum_repo['gpgcheck']
|
1032
|
+
end
|
1033
|
+
|
1001
1034
|
private
|
1002
1035
|
|
1003
1036
|
def create_generator(batch, name = '00000000-0000-0000-0000-000000000000')
|
@@ -26,7 +26,10 @@ class TagsGeneratorTest < ActiveSupport::TestCase
|
|
26
26
|
organization: env.organization,
|
27
27
|
location: @location2,
|
28
28
|
hostgroup: @hostgroup2,
|
29
|
-
|
29
|
+
content_facet: FactoryBot.build(
|
30
|
+
:content_facet,
|
31
|
+
content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)]
|
32
|
+
)
|
30
33
|
)
|
31
34
|
|
32
35
|
@host.organization.pools << FactoryBot.create(:katello_pool, account_number: '1234', cp_id: 1)
|
@@ -8,7 +8,7 @@ const CVEsHostDetailsTab = ({ systemId }) => {
|
|
8
8
|
const scope = 'vulnerability';
|
9
9
|
const module = './SystemDetailTable';
|
10
10
|
return (
|
11
|
-
<div className="rh-cloud-insights-vulnerability-host-details-component">
|
11
|
+
<div className="rh-cloud-insights-vulnerability-host-details-component vulnerability">
|
12
12
|
<ScalprumComponent scope={scope} module={module} systemId={systemId} />
|
13
13
|
</div>
|
14
14
|
);
|
@@ -10,7 +10,7 @@ const CveDetailsPage = () => {
|
|
10
10
|
|
11
11
|
return (
|
12
12
|
<ScalprumProvider {...providerOptions}>
|
13
|
-
<div className="rh-cloud-cve-details-page">
|
13
|
+
<div className="rh-cloud-cve-details-page vulnerability">
|
14
14
|
<ScalprumComponent scope={scope} module={module} cveId={cveId} />
|
15
15
|
</div>
|
16
16
|
</ScalprumProvider>
|
@@ -18,9 +18,7 @@ jest.mock('@scalprum/react-core', () => ({
|
|
18
18
|
describe('CveDetailsPage component', () => {
|
19
19
|
it('renders the container with correct class', () => {
|
20
20
|
const { container } = render(<CveDetailsPage />);
|
21
|
-
expect(
|
22
|
-
container.querySelector('.rh-cloud-cve-details-page')
|
23
|
-
).toBeTruthy();
|
21
|
+
expect(container.querySelector('.rh-cloud-cve-details-page')).toBeTruthy();
|
24
22
|
});
|
25
23
|
|
26
24
|
it('passes cveId from URL params to ScalprumComponent', () => {
|
@@ -46,7 +46,7 @@ const RecommendationsCell = hostDetails => {
|
|
46
46
|
hostDetails?.insights_attributes ?? {}
|
47
47
|
);
|
48
48
|
|
49
|
-
return insightsAttributes.
|
49
|
+
return insightsAttributes.useIopMode ? (
|
50
50
|
<IopRecommendationsCell hostDetails={hostDetails} />
|
51
51
|
) : (
|
52
52
|
<HostedRecommendationsCell hostDetails={hostDetails} />
|
@@ -8,6 +8,7 @@ import InsightsCloudSync from './InsightsCloudSync';
|
|
8
8
|
import IopRecommendationDetails from './IopRecommendationDetails/IopRecommendationDetails';
|
9
9
|
import InsightsHostDetailsTab from './InsightsHostDetailsTab';
|
10
10
|
import CveDetailsPage from './CveDetailsPage';
|
11
|
+
import './common/styles.scss';
|
11
12
|
|
12
13
|
const pages = [
|
13
14
|
{ name: 'ForemanInventoryUpload', type: ForemanInventoryUpload },
|
@@ -3,7 +3,15 @@ import React from 'react';
|
|
3
3
|
import { orderBy } from 'lodash';
|
4
4
|
import Resolutions from './Resolutions';
|
5
5
|
|
6
|
-
export const
|
6
|
+
export const getResolutionId = (selectedResolution, id) =>
|
7
|
+
`${id}_${selectedResolution}`;
|
8
|
+
|
9
|
+
export const modifyRows = (
|
10
|
+
remediations,
|
11
|
+
setResolutions,
|
12
|
+
setHostsIds,
|
13
|
+
isIop
|
14
|
+
) => {
|
7
15
|
if (remediations.length === 0) return [];
|
8
16
|
|
9
17
|
const resolutionToSubmit = [];
|
@@ -15,9 +23,22 @@ export const modifyRows = (remediations, setResolutions, setHostsIds) => {
|
|
15
23
|
).map(({ id, host_id, hostname, title, resolutions, reboot }) => {
|
16
24
|
hostsIdsToSubmit.add(host_id);
|
17
25
|
const selectedResolution = resolutions[0]?.id;
|
26
|
+
/* eslint-disable spellcheck/spell-checker */
|
27
|
+
|
28
|
+
// For IoP: {
|
29
|
+
// hit_id: "c7c6727e-2966-4f7c-87f1-20ef14db7a2d",
|
30
|
+
// rule_id: "hardening_ssh_client_alive|OPENSSH_HARDENING_CLIENT_ALIVE",
|
31
|
+
// resolution_type: "less_secure",
|
32
|
+
// resolution_id:"hardening_ssh_client_alive|OPENSSH_HARDENING_CLIENT_ALIVE_less_secure",
|
33
|
+
// }
|
34
|
+
// for Hosted, hit_id and rule_id will be Foreman database IDs
|
35
|
+
|
36
|
+
/* eslint-enable spellcheck/spell-checker */
|
18
37
|
resolutionToSubmit.push({
|
19
|
-
hit_id: id,
|
20
|
-
|
38
|
+
hit_id: isIop ? host_id : id,
|
39
|
+
rule_id: id,
|
40
|
+
resolution_type: selectedResolution /** defaults to the first resolution if many */,
|
41
|
+
resolution_id: getResolutionId(selectedResolution, id),
|
21
42
|
});
|
22
43
|
return {
|
23
44
|
cells: [
|
@@ -25,10 +46,11 @@ export const modifyRows = (remediations, setResolutions, setHostsIds) => {
|
|
25
46
|
title,
|
26
47
|
<div>
|
27
48
|
<Resolutions
|
28
|
-
hit_id={id}
|
49
|
+
hit_id={isIop ? host_id : id}
|
29
50
|
resolutions={resolutions}
|
30
51
|
setResolutions={setResolutions}
|
31
52
|
selectedResolution={selectedResolution}
|
53
|
+
isIop={isIop}
|
32
54
|
/>
|
33
55
|
</div>,
|
34
56
|
reboot,
|