foreman_rh_cloud 12.2.2 → 12.2.4
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/models/foreman_rh_cloud/ping.rb +90 -0
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +14 -12
- data/app/services/foreman_rh_cloud/tags_auth.rb +3 -2
- data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
- data/lib/foreman_inventory_upload.rb +1 -1
- data/lib/foreman_rh_cloud/engine.rb +2 -2
- data/lib/foreman_rh_cloud/plugin.rb +4 -0
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/package.json +1 -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 +0 -1
- data/webpack/ForemanColumnExtensions/index.js +1 -1
- data/webpack/ForemanRhCloudFills.js +1 -1
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationHelpers.js +15 -7
- data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0c1c612bfa55b7b792c80577d33718502ad3ecc35273f6c9ae5fef2d055e872
|
4
|
+
data.tar.gz: 16f86dba2beea9aa6930b1a60579b6f29097bc1e06c8fa4c1eadeb7ebb4cfd46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5f2081a2f011ad358a56a13c51f7098e762faa98bba4556b60a24fa7dd3f05151a919eb61d40fb10e8125c083fb553a0fc5bc39c89a9b8ce6ca6a2dea12491c
|
7
|
+
data.tar.gz: a1a6496c40f2716c7b05606047f5daab3b0578f699bbc604d2082db36b8595514c2b6c681e487150eda127311e2142227b75fe23ce86f3a5fcaa7c4ad4a6510c
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module ForemanRhCloud
|
2
|
+
class Ping
|
3
|
+
OK_RETURN_CODE = 'ok'.freeze
|
4
|
+
FAIL_RETURN_CODE = 'FAIL'.freeze
|
5
|
+
|
6
|
+
class << self
|
7
|
+
include ForemanRhCloud::CertAuth
|
8
|
+
|
9
|
+
def iop_smart_proxy_url
|
10
|
+
@iop_smart_proxy_url ||= ForemanRhCloud.iop_smart_proxy.url
|
11
|
+
end
|
12
|
+
|
13
|
+
def service_urls
|
14
|
+
{
|
15
|
+
:advisor => "#{iop_smart_proxy_url}/api/insights/v1/status/live/",
|
16
|
+
:vulnerability => "#{iop_smart_proxy_url}/api/vulnerability/v1/apistatus",
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def services
|
21
|
+
service_urls.keys
|
22
|
+
end
|
23
|
+
|
24
|
+
def status
|
25
|
+
{
|
26
|
+
iop_smart_proxy_exists: ForemanRhCloud.with_iop_smart_proxy?,
|
27
|
+
timeUTC: Time.zone.now.getutc,
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def exception_watch(result, &blk)
|
32
|
+
::Katello::Ping.exception_watch(result, &blk)
|
33
|
+
end
|
34
|
+
|
35
|
+
def ping
|
36
|
+
ping_services
|
37
|
+
end
|
38
|
+
|
39
|
+
def ping!
|
40
|
+
result = ping_services
|
41
|
+
|
42
|
+
if result[:status] != OK_RETURN_CODE
|
43
|
+
failed_names = result[:services].reject do |_name, details|
|
44
|
+
details[:status] == OK_RETURN_CODE
|
45
|
+
end
|
46
|
+
raise "The following services have not been started or are reporting errors: #{failed_names.keys.join(', ')}"
|
47
|
+
end
|
48
|
+
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def ping_services
|
53
|
+
result = {}
|
54
|
+
services.each do |service|
|
55
|
+
result[service] = {}
|
56
|
+
ping_service(service, result[service])
|
57
|
+
end
|
58
|
+
|
59
|
+
# set overall status result code
|
60
|
+
result = { :services => result }
|
61
|
+
result[:status] = result[:services].each_value.any? { |v| v[:status] == FAIL_RETURN_CODE } ? FAIL_RETURN_CODE : OK_RETURN_CODE
|
62
|
+
result
|
63
|
+
end
|
64
|
+
|
65
|
+
def logger
|
66
|
+
Rails.logger
|
67
|
+
end
|
68
|
+
|
69
|
+
def ping_url(url)
|
70
|
+
response = execute_cloud_request(
|
71
|
+
method: :get,
|
72
|
+
url: url
|
73
|
+
)
|
74
|
+
return {} if response.empty?
|
75
|
+
begin
|
76
|
+
result = JSON.parse(response).with_indifferent_access
|
77
|
+
rescue JSON::ParserError, NoMethodError
|
78
|
+
result = { :response => response.body&.strip }
|
79
|
+
end
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
def ping_service(service_name, service_result_hash)
|
84
|
+
exception_watch(service_result_hash) do
|
85
|
+
ping_url(service_urls[service_name])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -5,13 +5,13 @@ module ForemanRhCloud
|
|
5
5
|
include ForemanRhCloud::GatewayRequest
|
6
6
|
|
7
7
|
SCOPED_REQUESTS = [
|
8
|
-
%r{
|
9
|
-
%r{
|
10
|
-
%r{
|
11
|
-
%r{
|
12
|
-
%r{
|
13
|
-
%r{
|
14
|
-
%r{
|
8
|
+
{ test: %r{api/vulnerability/v1/vulnerabilities/cves}, tag_name: :tags },
|
9
|
+
{ test: %r{api/vulnerability/v1/dashbar}, tag_name: :tags },
|
10
|
+
{ test: %r{api/vulnerability/v1/cves/[^/]+/affected_systems}, tag_name: :tags },
|
11
|
+
{ test: %r{api/vulnerability/v1/systems/[^/]+/cves}, tag_name: :tags },
|
12
|
+
{ test: %r{api/insights/.*}, tag_name: :tags },
|
13
|
+
{ test: %r{api/inventory/.*}, tag_name: :tags },
|
14
|
+
{ test: %r{api/tasks/.*}, tag_name: :tags },
|
15
15
|
].freeze
|
16
16
|
|
17
17
|
def forward_request(original_request, path, controller_name, user, organization, location)
|
@@ -31,10 +31,10 @@ module ForemanRhCloud
|
|
31
31
|
execute_cloud_request(request_opts)
|
32
32
|
end
|
33
33
|
|
34
|
-
def prepare_tags(user, organization, location)
|
34
|
+
def prepare_tags(user, organization, location, tag_name)
|
35
35
|
[
|
36
36
|
TagsAuth.auth_tag_for(user, organization, location),
|
37
|
-
].map { |tag_value| [
|
37
|
+
].map { |tag_value| [tag_name, tag_value] }
|
38
38
|
end
|
39
39
|
|
40
40
|
def prepare_request_opts(original_request, path, forward_payload, forward_params)
|
@@ -70,7 +70,8 @@ module ForemanRhCloud
|
|
70
70
|
def prepare_forward_params(original_request, path, user:, organization:, location:)
|
71
71
|
forward_params = original_request.query_parameters.to_a
|
72
72
|
|
73
|
-
|
73
|
+
tag_name = scope_request?(original_request, path)
|
74
|
+
forward_params += prepare_tags(user, organization, location, tag_name) if tag_name
|
74
75
|
|
75
76
|
forward_params
|
76
77
|
end
|
@@ -92,9 +93,10 @@ module ForemanRhCloud
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def scope_request?(original_request, path)
|
95
|
-
return
|
96
|
+
return nil unless original_request.get?
|
96
97
|
|
97
|
-
SCOPED_REQUESTS.
|
98
|
+
request_pattern = SCOPED_REQUESTS.find { |pattern| pattern[:test].match?(path) }
|
99
|
+
request_pattern[:tag_name] if request_pattern
|
98
100
|
end
|
99
101
|
|
100
102
|
def core_app_name
|
@@ -22,15 +22,16 @@ module ForemanRhCloud
|
|
22
22
|
def update_tag
|
23
23
|
logger.debug("Updating tags for user: #{@user}, org: #{@org.name}, loc: #{@loc.name}")
|
24
24
|
|
25
|
+
payload = tags_query_payload
|
25
26
|
params = {
|
26
27
|
method: :post,
|
27
28
|
url: "#{InsightsCloud.gateway_url}/tags",
|
28
29
|
headers: {
|
29
30
|
content_type: :json,
|
30
31
|
},
|
31
|
-
payload:
|
32
|
+
payload: payload.to_json,
|
32
33
|
}
|
33
|
-
execute_cloud_request(params)
|
34
|
+
execute_cloud_request(params) unless payload[:host_id_list].empty?
|
34
35
|
end
|
35
36
|
|
36
37
|
def allowed_hosts
|
@@ -253,7 +253,6 @@ module ForemanInventoryUpload
|
|
253
253
|
|
254
254
|
def report_yum_repos(host)
|
255
255
|
return unless host&.content_facet&.bound_repositories&.any?
|
256
|
-
return unless ForemanRhCloud.with_iop_smart_proxy?
|
257
256
|
|
258
257
|
@stream.array_field('yum_repos') do
|
259
258
|
host.content_facet.bound_repositories.each_with_index do |repo, index|
|
@@ -58,7 +58,7 @@ module ForemanInventoryUpload
|
|
58
58
|
|
59
59
|
def self.upload_url
|
60
60
|
# for testing set ENV to 'https://ci.cloud.redhat.com/api/ingress/v1/upload'
|
61
|
-
|
61
|
+
ENV['SATELLITE_INVENTORY_UPLOAD_URL'] || "#{ForemanRhCloud.cert_base_url}/api/ingress/v1/upload"
|
62
62
|
end
|
63
63
|
|
64
64
|
def self.slice_size
|
@@ -122,11 +122,11 @@ module ForemanRhCloud
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def self.with_iop_smart_proxy?
|
125
|
-
SmartProxy.with_features('iop').exists?
|
125
|
+
SmartProxy.unscoped.with_features('iop').exists?
|
126
126
|
end
|
127
127
|
|
128
128
|
def self.iop_smart_proxy
|
129
|
-
SmartProxy.with_features('iop').first
|
129
|
+
SmartProxy.unscoped.with_features('iop').first
|
130
130
|
end
|
131
131
|
|
132
132
|
def self.ca_cert
|
@@ -121,6 +121,10 @@ module ForemanRhCloud
|
|
121
121
|
|
122
122
|
register_custom_status InventorySync::InventoryStatus
|
123
123
|
register_custom_status InsightsClientReportStatus
|
124
|
+
if ForemanRhCloud.with_iop_smart_proxy?
|
125
|
+
register_ping_extension { ForemanRhCloud::Ping.ping }
|
126
|
+
register_status_extension { ForemanRhCloud::Ping.status }
|
127
|
+
end
|
124
128
|
|
125
129
|
describe_host do
|
126
130
|
overview_buttons_provider :insights_host_overview_buttons
|
data/package.json
CHANGED
@@ -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
|
@@ -999,7 +999,6 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
999
999
|
end
|
1000
1000
|
|
1001
1001
|
test 'reports yum repos' do
|
1002
|
-
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
1003
1002
|
FactoryBot.create(:katello_content, cp_content_id: '1', organization: @host.organization, name: 'Test Content', label: 'test-content')
|
1004
1003
|
repo = FactoryBot.build(
|
1005
1004
|
:katello_repository,
|
@@ -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} />
|
@@ -3,8 +3,10 @@ import React from 'react';
|
|
3
3
|
import { orderBy } from 'lodash';
|
4
4
|
import Resolutions from './Resolutions';
|
5
5
|
|
6
|
-
export const getResolutionId = (selectedResolution, id) =>
|
7
|
-
`${id}_${selectedResolution}`;
|
6
|
+
export const getResolutionId = (selectedResolution, id, isIop = true) => {
|
7
|
+
if (isIop) return `${id}_${selectedResolution}`;
|
8
|
+
return selectedResolution;
|
9
|
+
};
|
8
10
|
|
9
11
|
export const modifyRows = (
|
10
12
|
remediations,
|
@@ -25,20 +27,26 @@ export const modifyRows = (
|
|
25
27
|
const selectedResolution = resolutions[0]?.id;
|
26
28
|
/* eslint-disable spellcheck/spell-checker */
|
27
29
|
|
28
|
-
// For IoP:
|
29
|
-
//
|
30
|
+
// For IoP:
|
31
|
+
// All of the values will be plain strings
|
32
|
+
// {
|
33
|
+
// hit_id: "c7c6727e-2966-4f7c-87f1-20ef14db7a2d", <-- this refers to a host by insights ID
|
30
34
|
// rule_id: "hardening_ssh_client_alive|OPENSSH_HARDENING_CLIENT_ALIVE",
|
31
35
|
// resolution_type: "less_secure",
|
32
|
-
// resolution_id:"hardening_ssh_client_alive|OPENSSH_HARDENING_CLIENT_ALIVE_less_secure",
|
36
|
+
// resolution_id:"hardening_ssh_client_alive|OPENSSH_HARDENING_CLIENT_ALIVE_less_secure", <-- joined rule id and resolution type
|
33
37
|
// }
|
34
|
-
//
|
38
|
+
// For non-IoP:
|
39
|
+
// All of the values will be numeric Foreman database IDs
|
40
|
+
// hit_id refers to an InsightsHit
|
41
|
+
// rule_id refers to an InsightsRule
|
42
|
+
// resolution_type and resolution_id both refer to an InsightsResolution (InsightsHit.find(xx).rule.resolutions)
|
35
43
|
|
36
44
|
/* eslint-enable spellcheck/spell-checker */
|
37
45
|
resolutionToSubmit.push({
|
38
46
|
hit_id: isIop ? host_id : id,
|
39
47
|
rule_id: id,
|
40
48
|
resolution_type: selectedResolution /** defaults to the first resolution if many */,
|
41
|
-
resolution_id: getResolutionId(selectedResolution, id),
|
49
|
+
resolution_id: getResolutionId(selectedResolution, id, isIop),
|
42
50
|
});
|
43
51
|
return {
|
44
52
|
cells: [
|
@@ -22,7 +22,7 @@ const Resolutions = ({
|
|
22
22
|
key={resolution_id}
|
23
23
|
ouiaId={`resolution-radio-${resolution_id}`}
|
24
24
|
className="resolution-radio"
|
25
|
-
id={resolution_id}
|
25
|
+
id={`${hit_id}_${resolution_id}`}
|
26
26
|
isChecked={resolution_id === checkedID}
|
27
27
|
onChange={() =>
|
28
28
|
setResolutions(stateRes =>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_rh_cloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.2.
|
4
|
+
version: 12.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Red Hat Cloud team
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- app/helpers/foreman_inventory_upload_helper.rb
|
122
122
|
- app/helpers/foreman_inventory_upload_host_helper.rb
|
123
123
|
- app/models/concerns/rh_cloud_host.rb
|
124
|
+
- app/models/foreman_rh_cloud/ping.rb
|
124
125
|
- app/models/insights_client_report_status.rb
|
125
126
|
- app/models/insights_facet.rb
|
126
127
|
- app/models/insights_hit.rb
|