foreman_rh_cloud 4.0.24.1 → 4.0.25
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/services/foreman_rh_cloud/cloud_auth.rb +4 -0
- data/app/services/foreman_rh_cloud/remediations_retriever.rb +5 -0
- data/lib/foreman_inventory_upload/generators/tags.rb +3 -1
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/insights_cloud/async/insights_full_sync.rb +5 -0
- data/lib/insights_cloud/async/insights_resolutions_sync.rb +9 -0
- data/lib/insights_cloud/async/insights_rules_sync.rb +5 -0
- data/lib/inventory_sync/async/inventory_full_sync.rb +5 -0
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +5 -0
- data/lib/inventory_sync/async/inventory_self_host_sync.rb +9 -0
- data/package.json +1 -1
- data/test/jobs/insights_full_sync_test.rb +1 -0
- data/test/jobs/insights_resolutions_sync_test.rb +1 -0
- data/test/jobs/insights_rules_sync_test.rb +1 -0
- data/test/jobs/inventory_full_sync_test.rb +10 -0
- data/test/jobs/inventory_hosts_sync_test.rb +1 -0
- data/test/jobs/inventory_self_host_sync_test.rb +1 -0
- data/test/unit/services/foreman_rh_cloud/template_renderer_helper_test.rb +1 -0
- data/test/unit/tags_generator_test.rb +41 -0
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/EmptyState.js +1 -1
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/__snapshots__/EmptyState.test.js.snap +1 -2
- data/webpack/ForemanInventoryUpload/Components/FileDownload/FileDownload.js +3 -1
- data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/__snapshots__/FileDownload.test.js.snap +2 -1
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -2
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilterConstants.js +3 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +2 -2
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Modal.js +1 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Toast.js +2 -2
- data/webpack/ForemanInventoryUpload/Components/StatusChart/StatusChart.js +4 -3
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
- data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.js +1 -1
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +2 -1
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +14 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +1 -1
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +2 -2
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.scss +14 -0
- data/webpack/InsightsHostDetailsTab/InsightsTab.js +3 -2
- data/webpack/InsightsHostDetailsTab/InsightsTab.scss +4 -4
- data/webpack/InsightsHostDetailsTab/components/ListItem/ListItem.js +9 -7
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ac06b57bc84d2c31a7a2e5ad8ec8874053bf4419f018c94b95192ba7281ccf4
|
|
4
|
+
data.tar.gz: 1e8dd2dce4252a247123e0662f6b33621fadf34e3d03a008335d1902dc7d69db
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7f0324f7854d483ce3c8836fcc5a70af02ed5f3f1bb64e3e1fcb68603eb4daa078b7cb7090ba4b9bcda6c4003639d5cd7265432f5d0b60b89cd5bccaf521fe3
|
|
7
|
+
data.tar.gz: f8e8b5317c59dc110e7315ba8bf665d7bdeda836e899dc81c1c7bcecdcd81a4568b0c8ad9849e69b9f74dd4cf7127ca097f234001b1492992d677d4cd5b44939
|
|
@@ -12,6 +12,11 @@ module ForemanRhCloud
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def create_playbook
|
|
15
|
+
unless cloud_auth_available?
|
|
16
|
+
logger.debug('Cloud authentication is not available, cannot continue')
|
|
17
|
+
return
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
response = query_playbook
|
|
16
21
|
|
|
17
22
|
logger.debug("Got playbook response: #{response.body}")
|
|
@@ -19,7 +19,9 @@ module ForemanInventoryUpload
|
|
|
19
19
|
def generate_parameters
|
|
20
20
|
return [] unless Setting[:include_parameter_tags]
|
|
21
21
|
|
|
22
|
-
(@host.host_inherited_params_objects || [])
|
|
22
|
+
(@host.host_inherited_params_objects || [])
|
|
23
|
+
.map { |item| [item.name, item.value] }
|
|
24
|
+
.select { |_name, value| value.present? || value.is_a?(FalseClass) }
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
private
|
|
@@ -6,6 +6,11 @@ module InsightsCloud
|
|
|
6
6
|
include ::ForemanRhCloud::CloudAuth
|
|
7
7
|
|
|
8
8
|
def plan
|
|
9
|
+
unless cloud_auth_available?
|
|
10
|
+
logger.debug('Cloud authentication is not available, skipping insights sync')
|
|
11
|
+
return
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
sequence do
|
|
10
15
|
# This can be turned off when we enable automatic status syncs
|
|
11
16
|
# This step will query cloud inventory to retrieve inventory uuids for each host
|
|
@@ -7,6 +7,15 @@ module InsightsCloud
|
|
|
7
7
|
|
|
8
8
|
RULE_ID_REGEX = /[^:]*:(?<id>.*)/
|
|
9
9
|
|
|
10
|
+
def plan
|
|
11
|
+
unless cloud_auth_available?
|
|
12
|
+
logger.debug('Cloud authentication is not available, skipping resolutions sync')
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
plan_self
|
|
17
|
+
end
|
|
18
|
+
|
|
10
19
|
def run
|
|
11
20
|
InsightsResolution.transaction do
|
|
12
21
|
InsightsResolution.delete_all
|
|
@@ -5,6 +5,11 @@ module InventorySync
|
|
|
5
5
|
set_callback :step, :around, :update_statuses_batch
|
|
6
6
|
|
|
7
7
|
def plan(organization)
|
|
8
|
+
unless cloud_auth_available?
|
|
9
|
+
logger.debug('Cloud authentication is not available, skipping inventory hosts sync')
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
plan_self(organization_id: organization.id)
|
|
9
14
|
end
|
|
10
15
|
|
|
@@ -5,6 +5,11 @@ module InventorySync
|
|
|
5
5
|
set_callback :step, :around, :create_facets
|
|
6
6
|
|
|
7
7
|
def plan
|
|
8
|
+
unless cloud_auth_available?
|
|
9
|
+
logger.debug('Cloud authentication is not available, skipping inventory hosts sync')
|
|
10
|
+
return
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
# by default the tasks will be executed concurrently
|
|
9
14
|
plan_self
|
|
10
15
|
plan_self_host_sync
|
|
@@ -3,6 +3,15 @@ module InventorySync
|
|
|
3
3
|
class InventorySelfHostSync < QueryInventoryJob
|
|
4
4
|
set_callback :step, :around, :create_facets
|
|
5
5
|
|
|
6
|
+
def plan
|
|
7
|
+
unless cloud_auth_available?
|
|
8
|
+
logger.debug('Cloud authentication is not available, skipping self host sync')
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
plan_self
|
|
13
|
+
end
|
|
14
|
+
|
|
6
15
|
def create_facets
|
|
7
16
|
# get the results from the event
|
|
8
17
|
results = yield
|
data/package.json
CHANGED
|
@@ -7,6 +7,7 @@ class InsightsFullSyncTest < ActiveSupport::TestCase
|
|
|
7
7
|
setup do
|
|
8
8
|
InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_rules_sync)
|
|
9
9
|
InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_notifications)
|
|
10
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
10
11
|
|
|
11
12
|
uuid1 = 'accdf444-5628-451d-bf3e-cf909ad72756'
|
|
12
13
|
@host1 = FactoryBot.create(:host, :managed, name: 'host1')
|
|
@@ -63,6 +63,7 @@ class InsightsResolutionsSyncTest < ActiveSupport::TestCase
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
@rule = FactoryBot.create(:insights_rule, rule_id: 'network_tcp_connection_hang|NETWORK_TCP_CONNECTION_HANG_WARN')
|
|
66
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
test 'Resolutions data is replaced with data from cloud' do
|
|
@@ -112,6 +112,7 @@ class InsightsRulesSyncTest < ActiveSupport::TestCase
|
|
|
112
112
|
@hit = FactoryBot.create(:insights_hit, host_id: @host.id)
|
|
113
113
|
|
|
114
114
|
InsightsCloud::Async::InsightsRulesSync.any_instance.stubs(:plan_resolutions)
|
|
115
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
test 'Hits data is replaced with data from cloud' do
|
|
@@ -242,6 +242,7 @@ class InventoryFullSyncTest < ActiveSupport::TestCase
|
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
test 'Host status should be SYNC for inventory hosts' do
|
|
245
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'TEST TOKEN')
|
|
245
246
|
InventorySync::Async::InventoryFullSync.any_instance.expects(:query_inventory).returns(@inventory)
|
|
246
247
|
|
|
247
248
|
ForemanTasks.sync_task(InventorySync::Async::InventoryFullSync, @host2.organization)
|
|
@@ -253,6 +254,7 @@ class InventoryFullSyncTest < ActiveSupport::TestCase
|
|
|
253
254
|
end
|
|
254
255
|
|
|
255
256
|
test 'Host status should be DISCONNECT for hosts that are not returned from cloud' do
|
|
257
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'TEST TOKEN')
|
|
256
258
|
InventorySync::Async::InventoryFullSync.any_instance.expects(:query_inventory).returns(@inventory)
|
|
257
259
|
FactoryBot.create(:fact_value, fact_name: fact_names['virt::uuid'], value: '1234', host: @host2)
|
|
258
260
|
|
|
@@ -261,4 +263,12 @@ class InventoryFullSyncTest < ActiveSupport::TestCase
|
|
|
261
263
|
|
|
262
264
|
assert_equal InventorySync::InventoryStatus::DISCONNECT, InventorySync::InventoryStatus.where(host_id: @host1.id).first.status
|
|
263
265
|
end
|
|
266
|
+
|
|
267
|
+
test 'Task should be aborted if token is not present' do
|
|
268
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: '')
|
|
269
|
+
|
|
270
|
+
InventorySync::Async::InventoryFullSync.any_instance.expects(:plan_self).never
|
|
271
|
+
|
|
272
|
+
ForemanTasks.sync_task(InventorySync::Async::InventoryFullSync, @host1.organization)
|
|
273
|
+
end
|
|
264
274
|
end
|
|
@@ -6,6 +6,7 @@ class InventoryHostsSyncTest < ActiveSupport::TestCase
|
|
|
6
6
|
|
|
7
7
|
setup do
|
|
8
8
|
User.current = User.find_by(login: 'secret_admin')
|
|
9
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
9
10
|
|
|
10
11
|
env = FactoryBot.create(:katello_k_t_environment)
|
|
11
12
|
cv = env.content_views << FactoryBot.create(:katello_content_view, organization: env.organization)
|
|
@@ -6,6 +6,7 @@ class InventorySelfHostSyncTest < ActiveSupport::TestCase
|
|
|
6
6
|
|
|
7
7
|
setup do
|
|
8
8
|
User.current = User.find_by(login: 'secret_admin')
|
|
9
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
9
10
|
|
|
10
11
|
# this host would pass our plugin queries, so it could be uploaded to the cloud.
|
|
11
12
|
@host1 = FactoryBot.create(:host)
|
|
@@ -8,6 +8,7 @@ class TemplateRendererHelperTest < ActiveSupport::TestCase
|
|
|
8
8
|
response.stubs(:body).returns('TEST PLAYBOOK')
|
|
9
9
|
ForemanRhCloud::RemediationsRetriever.any_instance.stubs(:query_playbook).returns(response)
|
|
10
10
|
@host1 = FactoryBot.create(:host)
|
|
11
|
+
FactoryBot.create(:setting, name: 'rh_cloud_token', value: 'MOCK_TOKEN')
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
test 'Generates a playbook for hit and remediation' do
|
|
@@ -62,6 +62,47 @@ class TagsGeneratorTest < ActiveSupport::TestCase
|
|
|
62
62
|
assert_equal false, actual.key?('content_view')
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
test 'generates parameter tags' do
|
|
66
|
+
FactoryBot.create(:setting, :name => 'include_parameter_tags', :settings_type => "boolean", :category => "Setting::RhCloud", :default => false, :value => true)
|
|
67
|
+
|
|
68
|
+
@host.stubs(:host_inherited_params_objects).returns(
|
|
69
|
+
[
|
|
70
|
+
OpenStruct.new(name: 'bool_param', value: true),
|
|
71
|
+
OpenStruct.new(name: 'false_param', value: false),
|
|
72
|
+
OpenStruct.new(name: 'int_param', value: 1),
|
|
73
|
+
OpenStruct.new(name: 'empty_param', value: nil),
|
|
74
|
+
OpenStruct.new(name: 'empty_str_param', value: ''),
|
|
75
|
+
]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
generator = create_generator
|
|
79
|
+
actual = Hash[generator.generate_parameters]
|
|
80
|
+
|
|
81
|
+
assert_equal 3, actual.count
|
|
82
|
+
assert_equal true, actual['bool_param']
|
|
83
|
+
assert_equal false, actual['false_param']
|
|
84
|
+
assert_equal 1, actual['int_param']
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test 'skips parameter tags if include_parameter_tags setting is off' do
|
|
88
|
+
FactoryBot.create(:setting, :name => 'include_parameter_tags', :settings_type => "boolean", :category => "Setting::RhCloud", :default => false, :value => false)
|
|
89
|
+
|
|
90
|
+
@host.stubs(:host_inherited_params_objects).returns(
|
|
91
|
+
[
|
|
92
|
+
OpenStruct.new(name: 'bool_param', value: true),
|
|
93
|
+
OpenStruct.new(name: 'false_param', value: false),
|
|
94
|
+
OpenStruct.new(name: 'int_param', value: 1),
|
|
95
|
+
OpenStruct.new(name: 'empty_param', value: nil),
|
|
96
|
+
OpenStruct.new(name: 'empty_str_param', value: ''),
|
|
97
|
+
]
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
generator = create_generator
|
|
101
|
+
actual = generator.generate_parameters.group_by { |key, value| key }
|
|
102
|
+
|
|
103
|
+
assert_equal 0, actual.count
|
|
104
|
+
end
|
|
105
|
+
|
|
65
106
|
private
|
|
66
107
|
|
|
67
108
|
def create_generator
|
data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/EmptyState.js
CHANGED
|
@@ -9,7 +9,7 @@ const inventoryEmptyState = () => (
|
|
|
9
9
|
<EmptyState.Title>
|
|
10
10
|
{__('Fetching data about your accounts')}
|
|
11
11
|
</EmptyState.Title>
|
|
12
|
-
<EmptyState.Info>{__('Loading')}
|
|
12
|
+
<EmptyState.Info>{__('Loading...')}</EmptyState.Info>
|
|
13
13
|
</EmptyState>
|
|
14
14
|
);
|
|
15
15
|
|
|
@@ -2,12 +2,14 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { Grid, Button, Icon } from 'patternfly-react';
|
|
4
4
|
import { noop } from 'foremanReact/common/helpers';
|
|
5
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
6
|
+
|
|
5
7
|
import './fileDownload.scss';
|
|
6
8
|
|
|
7
9
|
const FileDownload = ({ onClick }) => (
|
|
8
10
|
<Grid.Col sm={12}>
|
|
9
11
|
<Button onClick={onClick} className="download-button">
|
|
10
|
-
Download Report <Icon name="download" />
|
|
12
|
+
{__('Download Report')} <Icon name="download" />
|
|
11
13
|
</Button>
|
|
12
14
|
</Grid.Col>
|
|
13
15
|
);
|
|
@@ -15,8 +15,7 @@ const InventoryFilter = ({
|
|
|
15
15
|
organization,
|
|
16
16
|
}) => {
|
|
17
17
|
useEffect(() => {
|
|
18
|
-
const initialTerm =
|
|
19
|
-
organization === __(ANY_ORGANIZATION) ? '' : organization;
|
|
18
|
+
const initialTerm = organization === ANY_ORGANIZATION ? '' : organization;
|
|
20
19
|
handleFilterChange(initialTerm);
|
|
21
20
|
}, []);
|
|
22
21
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
2
|
+
|
|
1
3
|
export const INVENTORY_FILTER_UPDATE = 'INVENTORY_FILTER_UPDATE';
|
|
2
4
|
export const INVENTORY_FILTER_CLEAR = 'INVENTORY_FILTER_CLEAR';
|
|
3
|
-
export const ANY_ORGANIZATION = 'Any Organization';
|
|
5
|
+
export const ANY_ORGANIZATION = __('Any Organization');
|
|
@@ -28,7 +28,7 @@ export const PageDescription = () => (
|
|
|
28
28
|
target="_blank"
|
|
29
29
|
rel="noopener noreferrer"
|
|
30
30
|
>
|
|
31
|
-
About subscription watch
|
|
31
|
+
{__('About subscription watch')}
|
|
32
32
|
</a>
|
|
33
33
|
</p>
|
|
34
34
|
<p>
|
|
@@ -39,7 +39,7 @@ export const PageDescription = () => (
|
|
|
39
39
|
target="_blank"
|
|
40
40
|
rel="noopener noreferrer"
|
|
41
41
|
>
|
|
42
|
-
Red Hat Insights Data and Application Security
|
|
42
|
+
{__('Red Hat Insights Data and Application Security')}
|
|
43
43
|
</a>
|
|
44
44
|
</p>
|
|
45
45
|
</div>
|
data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/components/Toast.js
CHANGED
|
@@ -20,13 +20,13 @@ const Toast = ({ syncHosts, disconnectHosts }) => {
|
|
|
20
20
|
<strong>{disconnectHosts}</strong>
|
|
21
21
|
</p>
|
|
22
22
|
<p>
|
|
23
|
-
For more info, please visit the{' '}
|
|
23
|
+
{__('For more info, please visit the')}{' '}
|
|
24
24
|
<a
|
|
25
25
|
href={foremanUrl('/hosts')}
|
|
26
26
|
target="_blank"
|
|
27
27
|
rel="noopener noreferrer"
|
|
28
28
|
>
|
|
29
|
-
hosts page
|
|
29
|
+
{__('hosts page')}
|
|
30
30
|
</a>
|
|
31
31
|
</p>
|
|
32
32
|
</span>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { Grid, DonutChart } from 'patternfly-react';
|
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
5
|
import './statusChart.scss';
|
|
5
6
|
|
|
6
7
|
const StatusChart = ({ completed }) => {
|
|
7
8
|
const donutConfigData = {
|
|
8
9
|
columns: [
|
|
9
|
-
['Completed', completed],
|
|
10
|
-
['Remain', 100 - completed],
|
|
10
|
+
[__('Completed'), completed],
|
|
11
|
+
[__('Remain'), 100 - completed],
|
|
11
12
|
],
|
|
12
13
|
order: null,
|
|
13
14
|
};
|
|
@@ -37,7 +38,7 @@ const StatusChart = ({ completed }) => {
|
|
|
37
38
|
title={{
|
|
38
39
|
type: 'percent',
|
|
39
40
|
primary: `${completed}%`,
|
|
40
|
-
secondary: 'Completed',
|
|
41
|
+
secondary: __('Completed'),
|
|
41
42
|
}}
|
|
42
43
|
/>
|
|
43
44
|
</div>
|
|
@@ -41,7 +41,9 @@ const InventoryAutoUploadSwitcher = ({
|
|
|
41
41
|
|
|
42
42
|
<Grid.Col sm={5}>
|
|
43
43
|
<Popover
|
|
44
|
-
headerContent={
|
|
44
|
+
headerContent={
|
|
45
|
+
<strong>{__('Advanced Inventory Settings')}</strong>
|
|
46
|
+
}
|
|
45
47
|
bodyContent={
|
|
46
48
|
<AdvancedSettings
|
|
47
49
|
autoUploadEnabled={autoUploadEnabled}
|
|
@@ -17,7 +17,7 @@ class InsightsSyncSwitcher extends Component {
|
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<div className="insights_sync_switcher">
|
|
20
|
-
<span>Synchronize Automatically</span>
|
|
20
|
+
<span>{__('Synchronize Automatically')}</span>
|
|
21
21
|
<FieldLevelHelp
|
|
22
22
|
content={__(
|
|
23
23
|
'Enable automatic synchronization of Insights recommendations from the Red Hat cloud'
|
|
@@ -5,7 +5,7 @@ import { Pagination, PaginationVariant } from '@patternfly/react-core';
|
|
|
5
5
|
import { Table, TableHeader, TableBody } from '@patternfly/react-table';
|
|
6
6
|
import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
|
|
7
7
|
import SelectAllAlert from './SelectAllAlert';
|
|
8
|
-
import { columns } from './InsightsTableConstants';
|
|
8
|
+
import { columns, paginationTitles } from './InsightsTableConstants';
|
|
9
9
|
import TableEmptyState from '../../../common/table/EmptyState';
|
|
10
10
|
import {
|
|
11
11
|
modifySelectedRows,
|
|
@@ -82,6 +82,7 @@ const InsightsTable = ({
|
|
|
82
82
|
onSetPage={onTableSetPage}
|
|
83
83
|
onPerPageSelect={onTablePerPageSelect}
|
|
84
84
|
perPageOptions={getPerPageOptions(urlPerPage, appPerPage)}
|
|
85
|
+
titles={paginationTitles}
|
|
85
86
|
/>
|
|
86
87
|
</React.Fragment>
|
|
87
88
|
);
|
|
@@ -45,6 +45,20 @@ export const columns = [
|
|
|
45
45
|
},
|
|
46
46
|
];
|
|
47
47
|
|
|
48
|
+
export const paginationTitles = {
|
|
49
|
+
items: __('items'),
|
|
50
|
+
page: __('page'),
|
|
51
|
+
itemsPerPage: __('Items per page'),
|
|
52
|
+
perPageSuffix: __('per page'),
|
|
53
|
+
toFirstPage: __('Go to first page'),
|
|
54
|
+
toPreviousPage: __('Go to previous page'),
|
|
55
|
+
toLastPage: __('Go to last page'),
|
|
56
|
+
toNextPage: __('Go to next page'),
|
|
57
|
+
optionsToggle: __('Items per page'),
|
|
58
|
+
currPage: __('Current page'),
|
|
59
|
+
paginationTitle: __('Pagination'),
|
|
60
|
+
};
|
|
61
|
+
|
|
48
62
|
export const INSIGHTS_HITS_PATH = foremanUrl('/insights_cloud/hits');
|
|
49
63
|
|
|
50
64
|
export const INSIGHTS_HITS_API_KEY = 'INSIGHTS_HITS';
|
|
@@ -18,7 +18,7 @@ const SelectAllAlert = ({
|
|
|
18
18
|
<Alert
|
|
19
19
|
isInline
|
|
20
20
|
variant="info"
|
|
21
|
-
title={sprintf('Recommendations selected: %s.', selectedCount)}
|
|
21
|
+
title={sprintf(__('Recommendations selected: %s.'), selectedCount)}
|
|
22
22
|
actionLinks={
|
|
23
23
|
<AlertActionLink onClick={selectAll}>
|
|
24
24
|
{__('Select recommendations from all pages')}
|
|
@@ -135,10 +135,10 @@ exports[`InsightsTable rendering render with Props 1`] = `
|
|
|
135
135
|
titles={
|
|
136
136
|
Object {
|
|
137
137
|
"currPage": "Current page",
|
|
138
|
-
"items": "",
|
|
138
|
+
"items": "items",
|
|
139
139
|
"itemsPerPage": "Items per page",
|
|
140
140
|
"optionsToggle": "Items per page",
|
|
141
|
-
"page": "",
|
|
141
|
+
"page": "page",
|
|
142
142
|
"paginationTitle": "Pagination",
|
|
143
143
|
"perPageSuffix": "per page",
|
|
144
144
|
"toFirstPage": "Go to first page",
|
|
@@ -6,4 +6,18 @@
|
|
|
6
6
|
margin-top: 5px;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
|
|
10
|
+
// applies to the backdrop parent of the modal
|
|
11
|
+
@at-root .pf-c-backdrop {
|
|
12
|
+
width: calc(100% - 200px);
|
|
13
|
+
left: 200px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// where the vertical nav breaks: https://github.com/theforeman/foreman/blob/3347fa49d500964f0209122d8d36c920d1feafcc/webpack/assets/javascripts/react_app/components/Layout/components/Toolbar/HeaderToolbar.scss#L26
|
|
17
|
+
@media (max-width: 768px) {
|
|
18
|
+
@at-root .pf-c-backdrop {
|
|
19
|
+
width: 100%;
|
|
20
|
+
left: 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
9
23
|
}
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { orderBy } from 'lodash';
|
|
4
4
|
import { Grid, ListView } from 'patternfly-react';
|
|
5
5
|
import { noop } from 'foremanReact/common/helpers';
|
|
6
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
6
7
|
import ListItem from './components/ListItem';
|
|
7
8
|
import './InsightsTab.scss';
|
|
8
9
|
|
|
@@ -16,7 +17,7 @@ class InsightsHostDetailsTab extends React.Component {
|
|
|
16
17
|
const { hits } = this.props;
|
|
17
18
|
|
|
18
19
|
if (!hits.length) {
|
|
19
|
-
return <h2>No recommendations were found for this host
|
|
20
|
+
return <h2>{__('No recommendations were found for this host!')}</h2>;
|
|
20
21
|
}
|
|
21
22
|
const hitsSorted = orderBy(hits, ['total_risk'], ['desc']);
|
|
22
23
|
const items = hitsSorted.map(
|
|
@@ -42,7 +43,7 @@ class InsightsHostDetailsTab extends React.Component {
|
|
|
42
43
|
<div id="host_details_insights_tab">
|
|
43
44
|
<Grid.Row>
|
|
44
45
|
<Grid.Col xs={12}>
|
|
45
|
-
<h2>Recommendations</h2>
|
|
46
|
+
<h2>{__('Recommendations')}</h2>
|
|
46
47
|
<ListView id="hits_list">{items}</ListView>
|
|
47
48
|
</Grid.Col>
|
|
48
49
|
</Grid.Row>
|
|
@@ -48,19 +48,19 @@
|
|
|
48
48
|
padding: 5px 8px;
|
|
49
49
|
border-radius: 12px;
|
|
50
50
|
|
|
51
|
-
&.
|
|
51
|
+
&.risk-1 {
|
|
52
52
|
background-color: #e7f1fa;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
&.
|
|
55
|
+
&.risk-2 {
|
|
56
56
|
background-color: #fdf7e7;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
&.
|
|
59
|
+
&.risk-3 {
|
|
60
60
|
background-color: #f9dddd;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
&.
|
|
63
|
+
&.risk-4 {
|
|
64
64
|
background-color: #ffecec;
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React, { Fragment } from 'react';
|
|
2
2
|
import { ListView, Icon } from 'patternfly-react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
5
|
|
|
5
6
|
const labelMapper = {
|
|
6
|
-
1: 'Low',
|
|
7
|
-
2: 'Moderate',
|
|
8
|
-
3: 'Important',
|
|
9
|
-
4: 'Critical',
|
|
7
|
+
1: __('Low'),
|
|
8
|
+
2: __('Moderate'),
|
|
9
|
+
3: __('Important'),
|
|
10
|
+
4: __('Critical'),
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
const ListItem = ({ title, totalRisk, resultsUrl, solutionUrl }) => {
|
|
@@ -18,7 +19,7 @@ const ListItem = ({ title, totalRisk, resultsUrl, solutionUrl }) => {
|
|
|
18
19
|
|
|
19
20
|
const riskLabel = labelMapper[totalRisk];
|
|
20
21
|
const additionalInfo = [
|
|
21
|
-
<span key={`risk-info-${title}`} className={`risk-label
|
|
22
|
+
<span key={`risk-info-${title}`} className={`risk-label risk-${totalRisk}`}>
|
|
22
23
|
<p>{riskLabel}</p>
|
|
23
24
|
</span>,
|
|
24
25
|
];
|
|
@@ -26,7 +27,7 @@ const ListItem = ({ title, totalRisk, resultsUrl, solutionUrl }) => {
|
|
|
26
27
|
const knowledgebaseLink = solutionUrl && (
|
|
27
28
|
<p>
|
|
28
29
|
<a href={solutionUrl} target="_blank" rel="noopener noreferrer">
|
|
29
|
-
Knowledgebase article <Icon name="external-link" />
|
|
30
|
+
{__('Knowledgebase article')} <Icon name="external-link" />
|
|
30
31
|
</a>
|
|
31
32
|
</p>
|
|
32
33
|
);
|
|
@@ -34,7 +35,8 @@ const ListItem = ({ title, totalRisk, resultsUrl, solutionUrl }) => {
|
|
|
34
35
|
const insightsCloudLink = resultsUrl && (
|
|
35
36
|
<p>
|
|
36
37
|
<a href={resultsUrl} target="_blank" rel="noopener noreferrer">
|
|
37
|
-
Read more about it in RH cloud insights
|
|
38
|
+
{__('Read more about it in RH cloud insights')}{' '}
|
|
39
|
+
<Icon name="external-link" />
|
|
38
40
|
</a>
|
|
39
41
|
</p>
|
|
40
42
|
);
|
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: 4.0.
|
|
4
|
+
version: 4.0.25
|
|
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: 2021-
|
|
11
|
+
date: 2021-08-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: katello
|