foreman_rh_cloud 12.2.17 → 13.0.0
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/assets/javascripts/foreman_rh_cloud/locale/fr/foreman_rh_cloud.js +24 -78
- data/app/assets/javascripts/foreman_rh_cloud/locale/ja/foreman_rh_cloud.js +24 -78
- data/app/assets/javascripts/foreman_rh_cloud/locale/ka/foreman_rh_cloud.js +23 -77
- data/app/assets/javascripts/foreman_rh_cloud/locale/ko/foreman_rh_cloud.js +23 -77
- data/app/assets/javascripts/foreman_rh_cloud/locale/zh_CN/foreman_rh_cloud.js +23 -77
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +3 -5
- data/app/controllers/foreman_inventory_upload/accounts_controller.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +1 -1
- data/app/controllers/insights_cloud/ui_requests_controller.rb +3 -2
- data/app/models/concerns/rh_cloud_host.rb +1 -45
- data/app/models/foreman_rh_cloud/ping.rb +1 -2
- data/app/models/insights_hit.rb +1 -1
- data/app/services/foreman_rh_cloud/cert_auth.rb +3 -13
- data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +1 -3
- data/app/services/foreman_rh_cloud/tags_auth.rb +4 -15
- data/app/views/api/v2/advisor_engine/host_details.json.rabl +3 -1
- data/app/views/api/v2/hosts/insights/base.rabl +2 -3
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +8 -13
- data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +26 -4
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +96 -0
- data/lib/foreman_inventory_upload/generators/fact_helpers.rb +2 -2
- data/lib/foreman_inventory_upload/generators/slice.rb +3 -3
- data/lib/foreman_inventory_upload/scripts/uploader.sh.erb +49 -0
- data/lib/foreman_inventory_upload.rb +6 -6
- data/lib/foreman_rh_cloud/engine.rb +15 -34
- data/lib/foreman_rh_cloud/plugin.rb +13 -20
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +3 -3
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +3 -3
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
- data/lib/tasks/rh_cloud_inventory.rake +31 -14
- data/locale/foreman_rh_cloud.pot +157 -261
- data/locale/fr/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/fr/foreman_rh_cloud.po +26 -79
- data/locale/ja/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ja/foreman_rh_cloud.po +26 -79
- data/locale/ka/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ka/foreman_rh_cloud.po +24 -77
- data/locale/ko/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/ko/foreman_rh_cloud.po +25 -78
- data/locale/zh_CN/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
- data/locale/zh_CN/foreman_rh_cloud.po +25 -78
- data/package.json +1 -1
- data/test/controllers/accounts_controller_test.rb +1 -1
- data/test/controllers/insights_cloud/api/advisor_engine_controller_test.rb +1 -28
- data/test/controllers/insights_cloud/ui_requests_controller_test.rb +0 -26
- data/test/controllers/uploads_controller_test.rb +1 -1
- data/test/factories/insights_factories.rb +0 -29
- data/test/jobs/cloud_connector_announce_task_test.rb +2 -3
- data/test/jobs/connector_playbook_execution_reporter_task_test.rb +20 -32
- data/test/jobs/exponential_backoff_test.rb +8 -9
- data/test/jobs/insights_client_status_aging_test.rb +2 -3
- data/test/jobs/insights_full_sync_test.rb +7 -13
- data/test/jobs/insights_resolutions_sync_test.rb +5 -9
- data/test/jobs/insights_rules_sync_test.rb +3 -5
- data/test/jobs/inventory_full_sync_test.rb +5 -9
- data/test/jobs/inventory_hosts_sync_test.rb +6 -11
- data/test/jobs/inventory_scheduled_sync_test.rb +6 -10
- data/test/jobs/inventory_self_host_sync_test.rb +1 -1
- data/test/jobs/remove_insights_hosts_job_test.rb +15 -14
- data/test/jobs/upload_report_job_test.rb +36 -0
- data/test/unit/fact_helpers_test.rb +0 -47
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +0 -14
- data/test/unit/slice_generator_test.rb +0 -57
- data/webpack/ForemanColumnExtensions/index.js +0 -2
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +17 -24
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js +8 -178
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +36 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +1 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +1 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/ToolbarButtons.test.js +51 -69
- data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +1 -1
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +1 -1
- data/webpack/ForemanRhCloudFills.js +2 -6
- data/webpack/ForemanRhCloudHelpers.js +0 -4
- data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +3 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +9 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +4 -24
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +112 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +2 -2
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +0 -10
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +1 -1
- data/webpack/InsightsHostDetailsTab/InsightsTab.scss +0 -4
- data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +23 -59
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +23 -25
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +2 -8
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +4 -105
- data/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js +3 -0
- data/webpack/__tests__/ForemanRhCloudHelpers.test.js +1 -16
- data/webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap +0 -6
- data/webpack/common/Hooks/ConfigHooks.js +16 -3
- metadata +12 -32
- data/app/controllers/concerns/foreman_rh_cloud/registration_manager_extensions.rb +0 -39
- data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +0 -36
- data/lib/foreman_inventory_upload/async/generate_host_report.rb +0 -20
- data/lib/foreman_inventory_upload/async/host_inventory_report_job.rb +0 -39
- data/lib/foreman_inventory_upload/async/single_host_report_job.rb +0 -20
- data/lib/foreman_inventory_upload/async/upload_report_direct_job.rb +0 -200
- data/test/jobs/create_missing_insights_facets_test.rb +0 -151
- data/test/jobs/generate_host_report_test.rb +0 -100
- data/test/jobs/generate_report_job_test.rb +0 -146
- data/test/jobs/host_inventory_report_job_test.rb +0 -244
- data/test/jobs/queue_for_upload_job_test.rb +0 -54
- data/test/jobs/single_host_report_job_test.rb +0 -155
- data/test/jobs/upload_report_direct_job_test.rb +0 -399
- data/test/unit/foreman_rh_cloud_iop_metadata_test.rb +0 -200
- data/test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb +0 -154
- data/test/unit/rh_cloud_host_test.rb +0 -345
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTotalRiskChart.test.js +0 -194
- data/webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js +0 -154
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
} from '@patternfly/react-core/deprecated';
|
|
9
9
|
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
|
|
10
10
|
import { redHatAdvisorSystems } from '../InsightsCloudSyncHelpers';
|
|
11
|
-
import {
|
|
11
|
+
import { useAdvisorEngineConfig } from '../../common/Hooks/ConfigHooks';
|
|
12
12
|
|
|
13
13
|
const ToolbarDropdown = ({ onRecommendationSync }) => {
|
|
14
14
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
15
|
+
const isLocalAdvisorEngine = useAdvisorEngineConfig();
|
|
16
|
+
if (isLocalAdvisorEngine) {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
const dropdownItems = [
|
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
|
4
4
|
import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
|
|
5
5
|
import InsightsTable from './Components/InsightsTable';
|
|
6
|
-
import {
|
|
6
|
+
import { useAdvisorEngineConfig } from '../common/Hooks/ConfigHooks';
|
|
7
7
|
import { foremanUrl } from '../ForemanRhCloudHelpers';
|
|
8
8
|
import RemediationModal from './Components/RemediationModal';
|
|
9
9
|
import {
|
|
@@ -85,9 +85,9 @@ const IopRecommendationsPageWrapped = props => (
|
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
const RecommendationsPage = props => {
|
|
88
|
-
const
|
|
88
|
+
const isLocalAdvisorEngine = useAdvisorEngineConfig();
|
|
89
89
|
|
|
90
|
-
return
|
|
90
|
+
return isLocalAdvisorEngine ? (
|
|
91
91
|
<IopRecommendationsPageWrapped {...props} />
|
|
92
92
|
) : (
|
|
93
93
|
<InsightsCloudSync {...props} />
|
|
@@ -2,16 +2,6 @@ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
|
|
|
2
2
|
import { noop } from 'foremanReact/common/helpers';
|
|
3
3
|
import InsightsCloudSync from './InsightsCloudSync';
|
|
4
4
|
|
|
5
|
-
jest.mock('foremanReact/Root/Context/ForemanContext', () => ({
|
|
6
|
-
useForemanContext: () => ({
|
|
7
|
-
metadata: {
|
|
8
|
-
foreman_rh_cloud: {
|
|
9
|
-
iop: true,
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
}),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
5
|
const fixtures = {
|
|
16
6
|
render: {
|
|
17
7
|
status: 'RESOLVED',
|
|
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
import { push } from 'connected-react-router';
|
|
5
5
|
import { useHistory } from 'react-router-dom';
|
|
6
|
-
import { Bullseye,
|
|
6
|
+
import { Bullseye, Title } from '@patternfly/react-core';
|
|
7
|
+
import { DropdownItem } from '@patternfly/react-core/deprecated';
|
|
7
8
|
import {
|
|
8
9
|
ChartDonut,
|
|
9
10
|
ChartLegend,
|
|
@@ -18,67 +19,36 @@ import SkeletonLoader from 'foremanReact/components/common/SkeletonLoader';
|
|
|
18
19
|
import { insightsCloudUrl } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
19
20
|
import { getInitialRisks, theme } from './InsightsTabConstants';
|
|
20
21
|
|
|
21
|
-
const InsightsTotalRiskCard = ({ hostDetails }) => {
|
|
22
|
-
const { id, insights_attributes: insightsFacet } = hostDetails;
|
|
23
|
-
const uuid = insightsFacet?.uuid;
|
|
24
|
-
// eslint-disable-next-line camelcase
|
|
25
|
-
const isIop = insightsFacet?.use_iop_mode;
|
|
22
|
+
const InsightsTotalRiskCard = ({ hostDetails: { id } }) => {
|
|
26
23
|
const [totalRisks, setTotalRisks] = useState(getInitialRisks());
|
|
27
24
|
const hashHistory = useHistory();
|
|
28
25
|
const dispatch = useDispatch();
|
|
29
26
|
const API_KEY = `HOST_${id}_RECOMMENDATIONS`;
|
|
30
27
|
const API_OPTIONS = useMemo(() => ({ key: API_KEY }), [API_KEY]);
|
|
28
|
+
const url = id && insightsCloudUrl(`hits/${id}`); // This will keep the API call from being triggered if there's no host id.
|
|
29
|
+
const {
|
|
30
|
+
status = STATUS.PENDING,
|
|
31
|
+
response: { hits = [] },
|
|
32
|
+
} = useAPI('get', url, API_OPTIONS);
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: id && insightsCloudUrl(`hits/${id}`);
|
|
36
|
-
const { status = STATUS.PENDING, response } = useAPI('get', url, API_OPTIONS);
|
|
37
|
-
|
|
38
|
-
const checkRisks = useMemo(() => {
|
|
39
|
-
if (!response || status !== STATUS.RESOLVED) {
|
|
40
|
-
return getInitialRisks();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const risks = getInitialRisks();
|
|
44
|
-
if (isIop) {
|
|
45
|
-
const {
|
|
46
|
-
low_hits: lowHits = 0,
|
|
47
|
-
moderate_hits: moderateHits = 0,
|
|
48
|
-
important_hits: importantHits = 0,
|
|
49
|
-
critical_hits: criticalHits = 0,
|
|
50
|
-
hits = 0,
|
|
51
|
-
} = response;
|
|
52
|
-
|
|
53
|
-
risks[1].value += lowHits;
|
|
54
|
-
risks[2].value += moderateHits;
|
|
55
|
-
risks[3].value += importantHits;
|
|
56
|
-
risks[4].value += criticalHits;
|
|
57
|
-
risks.total = hits;
|
|
58
|
-
} else {
|
|
59
|
-
const { hits = [] } = response;
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (status === STATUS.RESOLVED) {
|
|
36
|
+
const risks = getInitialRisks();
|
|
60
37
|
hits.forEach(({ total_risk: risk }) => {
|
|
61
38
|
risks[risk].value += 1;
|
|
62
39
|
});
|
|
63
40
|
risks.total = hits.length;
|
|
41
|
+
setTotalRisks(risks);
|
|
64
42
|
}
|
|
65
|
-
|
|
66
|
-
}, [response, status, isIop]);
|
|
67
|
-
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
setTotalRisks(checkRisks);
|
|
70
|
-
}, [checkRisks]);
|
|
71
|
-
|
|
72
|
-
if (!insightsFacet) return null;
|
|
43
|
+
}, [hits, status]);
|
|
73
44
|
|
|
74
45
|
const onChartClick = (evt, { index }) => {
|
|
75
46
|
hashHistory.push(`/Insights`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
);
|
|
47
|
+
dispatch(
|
|
48
|
+
push({
|
|
49
|
+
search: `search=total_risk+%3D+${index + 1}`,
|
|
50
|
+
})
|
|
51
|
+
);
|
|
82
52
|
};
|
|
83
53
|
|
|
84
54
|
const onChartHover = (evt, { index }) => [
|
|
@@ -92,16 +62,11 @@ const InsightsTotalRiskCard = ({ hostDetails }) => {
|
|
|
92
62
|
const { 1: low, 2: moderate, 3: important, 4: critical, total } = totalRisks;
|
|
93
63
|
|
|
94
64
|
// eslint-disable-next-line react/prop-types
|
|
95
|
-
const LegendLabel = ({ index, ...rest }) =>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<a key={index} onClick={() => onChartClick(null, { index })}>
|
|
101
|
-
<ChartLabel {...rest} />
|
|
102
|
-
</a>
|
|
103
|
-
);
|
|
104
|
-
};
|
|
65
|
+
const LegendLabel = ({ index, ...rest }) => (
|
|
66
|
+
<a key={index} onClick={() => onChartClick(null, { index })}>
|
|
67
|
+
<ChartLabel {...rest} />
|
|
68
|
+
</a>
|
|
69
|
+
);
|
|
105
70
|
|
|
106
71
|
const legend = (
|
|
107
72
|
<ChartLegend
|
|
@@ -162,7 +127,6 @@ const InsightsTotalRiskCard = ({ hostDetails }) => {
|
|
|
162
127
|
return (
|
|
163
128
|
<CardTemplate
|
|
164
129
|
header={__('Total risks')}
|
|
165
|
-
overrideDropdownProps={{ id: 'total-risks-dropdown-container' }}
|
|
166
130
|
dropdownItems={[
|
|
167
131
|
<DropdownItem
|
|
168
132
|
key="insights-tab"
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
selectHits,
|
|
22
22
|
} from '../InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors';
|
|
23
23
|
import { redHatAdvisorSystems } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
24
|
-
import {
|
|
24
|
+
import { useAdvisorEngineConfig } from '../common/Hooks/ConfigHooks';
|
|
25
25
|
import { generateRuleUrl } from '../InsightsCloudSync/InsightsCloudSync';
|
|
26
26
|
import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
|
|
27
27
|
|
|
@@ -30,30 +30,15 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
30
30
|
const dispatch = useDispatch();
|
|
31
31
|
const query = useSelector(selectSearch);
|
|
32
32
|
const hits = useSelector(selectHits);
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
useEffect(
|
|
36
|
-
() => () => {
|
|
37
|
-
// Preserve hash when clearing search params to prevent tab navigation bugs
|
|
38
|
-
if (router && typeof router.replace === 'function') {
|
|
39
|
-
const replaceOptions = { search: null };
|
|
40
|
-
if (router.location && router.location.hash) {
|
|
41
|
-
replaceOptions.hash = router.location.hash;
|
|
42
|
-
}
|
|
43
|
-
router.replace(replaceOptions);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
[router]
|
|
47
|
-
);
|
|
33
|
+
const isLocalAdvisorEngine = useAdvisorEngineConfig();
|
|
34
|
+
|
|
35
|
+
useEffect(() => () => router.replace({ search: null }), [router]);
|
|
48
36
|
|
|
49
37
|
const onSearch = q => dispatch(fetchInsights({ query: q, page: 1 }));
|
|
50
38
|
|
|
51
39
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
52
|
-
const onSatInsightsClick = () =>
|
|
53
|
-
|
|
54
|
-
router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
|
|
55
|
-
}
|
|
56
|
-
};
|
|
40
|
+
const onSatInsightsClick = () =>
|
|
41
|
+
router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
|
|
57
42
|
|
|
58
43
|
const dropdownItems = [
|
|
59
44
|
<DropdownItem key="insights-link" ouiaId="insights-link">
|
|
@@ -61,7 +46,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
61
46
|
</DropdownItem>,
|
|
62
47
|
];
|
|
63
48
|
|
|
64
|
-
if (hits.length && !
|
|
49
|
+
if (hits.length && !isLocalAdvisorEngine) {
|
|
65
50
|
const { host_uuid: uuid } = hits[0];
|
|
66
51
|
dropdownItems.push(
|
|
67
52
|
<DropdownItem key="insights-advisor-link" ouiaId="insights-advisor-link">
|
|
@@ -146,15 +131,28 @@ const IopInsightsTabWrapped = props => (
|
|
|
146
131
|
);
|
|
147
132
|
|
|
148
133
|
const InsightsTab = props => {
|
|
149
|
-
const
|
|
134
|
+
const { response } = props;
|
|
135
|
+
const isLocalAdvisorEngine =
|
|
136
|
+
// eslint-disable-next-line camelcase
|
|
137
|
+
response?.insights_attributes?.use_iop_mode;
|
|
150
138
|
|
|
151
|
-
return
|
|
139
|
+
return isLocalAdvisorEngine ? (
|
|
152
140
|
<IopInsightsTabWrapped {...props} />
|
|
153
141
|
) : (
|
|
154
142
|
<NewHostDetailsTab {...props} />
|
|
155
143
|
);
|
|
156
144
|
};
|
|
157
145
|
|
|
158
|
-
InsightsTab.
|
|
146
|
+
InsightsTab.propTypes = {
|
|
147
|
+
response: PropTypes.shape({
|
|
148
|
+
insights_attributes: {
|
|
149
|
+
use_iop_mode: PropTypes.bool,
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
InsightsTab.defaultProps = {
|
|
155
|
+
response: {},
|
|
156
|
+
};
|
|
159
157
|
|
|
160
158
|
export default InsightsTab;
|
|
@@ -3,31 +3,25 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { UnknownIcon } from '@patternfly/react-icons';
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
|
6
|
+
|
|
6
7
|
import { insightsCloudUrl } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
7
|
-
import { useIopConfig } from '../common/Hooks/ConfigHooks';
|
|
8
8
|
|
|
9
9
|
const vulnerabilityApiPath = path =>
|
|
10
10
|
insightsCloudUrl(`api/vulnerability/v1/${path}`);
|
|
11
11
|
|
|
12
12
|
export const CVECountCell = ({ hostDetails }) => {
|
|
13
|
-
const isIopEnabled = useIopConfig();
|
|
14
|
-
|
|
15
13
|
// eslint-disable-next-line camelcase
|
|
16
14
|
const uuid = hostDetails?.subscription_facet_attributes?.uuid;
|
|
17
15
|
|
|
18
16
|
const key = `HOST_CVE_COUNT_${uuid}`;
|
|
19
17
|
const response = useAPI(
|
|
20
|
-
|
|
18
|
+
uuid ? 'get' : null,
|
|
21
19
|
vulnerabilityApiPath(`systems?uuid=${uuid}`),
|
|
22
20
|
{
|
|
23
21
|
key,
|
|
24
22
|
}
|
|
25
23
|
);
|
|
26
24
|
|
|
27
|
-
if (!isIopEnabled) {
|
|
28
|
-
return <UnknownIcon />;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
25
|
if (uuid === undefined) {
|
|
32
26
|
return <UnknownIcon />;
|
|
33
27
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { screen } from '@testing-library/react';
|
|
3
|
-
import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
4
3
|
import { API } from 'foremanReact/redux/API';
|
|
5
4
|
import { CVECountCell } from '../CVECountCell';
|
|
6
5
|
|
|
7
6
|
jest.mock('foremanReact/redux/API');
|
|
8
|
-
jest.mock('../../common/Hooks/ConfigHooks');
|
|
9
|
-
|
|
10
|
-
const { renderWithStore } = rtlHelpers;
|
|
11
|
-
|
|
12
7
|
API.get.mockImplementation(async () => ({
|
|
13
8
|
data: [
|
|
14
9
|
{
|
|
@@ -19,111 +14,15 @@ API.get.mockImplementation(async () => ({
|
|
|
19
14
|
],
|
|
20
15
|
}));
|
|
21
16
|
|
|
22
|
-
const hostDetailsMock = {
|
|
23
|
-
name: 'test-host.example.com',
|
|
24
|
-
subscription_facet_attributes: {
|
|
25
|
-
uuid: 'test-uuid-123',
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
17
|
describe('CVECountCell', () => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('renders an empty cves count column when no subscription UUID', () => {
|
|
35
|
-
const hostDetailsMockIoP = {
|
|
18
|
+
it('renders an empty cves count column', () => {
|
|
19
|
+
const hostDetailsMock = {
|
|
36
20
|
name: 'test-host.example.com',
|
|
37
21
|
subscription_facet_attributes: {
|
|
38
22
|
uuid: null, // no subscription
|
|
39
23
|
},
|
|
40
24
|
};
|
|
41
|
-
|
|
42
|
-
router: {
|
|
43
|
-
location: {
|
|
44
|
-
pathname: '/',
|
|
45
|
-
search: '',
|
|
46
|
-
hash: '',
|
|
47
|
-
query: {},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
API: {
|
|
51
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
52
|
-
response: { use_iop_mode: true },
|
|
53
|
-
status: 'RESOLVED',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
expect(screen.getByRole('img', { hidden: true })).toBeTruthy();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('renders UnknownIcon when IoP is not enabled', () => {
|
|
61
|
-
renderWithStore(<CVECountCell hostDetails={hostDetailsMock} />, {
|
|
62
|
-
router: {
|
|
63
|
-
location: {
|
|
64
|
-
pathname: '/',
|
|
65
|
-
search: '',
|
|
66
|
-
hash: '',
|
|
67
|
-
query: {},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
API: {
|
|
71
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
72
|
-
response: { use_iop_mode: false },
|
|
73
|
-
status: 'RESOLVED',
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
expect(screen.getByRole('img', { hidden: true })).toBeTruthy();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('renders UnknownIcon when IoP is enabled but CVE API call fails', () => {
|
|
81
|
-
// Mock CVE API failure - override the global mock for this test
|
|
82
|
-
API.get.mockImplementationOnce(async () => {
|
|
83
|
-
throw new Error('CVE API call failed');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
renderWithStore(<CVECountCell hostDetails={hostDetailsMock} />, {
|
|
87
|
-
router: {
|
|
88
|
-
location: {
|
|
89
|
-
pathname: '/',
|
|
90
|
-
search: '',
|
|
91
|
-
hash: '',
|
|
92
|
-
query: {},
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
API: {
|
|
96
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
97
|
-
response: { use_iop_mode: true },
|
|
98
|
-
status: 'RESOLVED',
|
|
99
|
-
},
|
|
100
|
-
// Mock the API failure state for the CVE endpoint
|
|
101
|
-
[`HOST_CVE_COUNT_${hostDetailsMock.subscription_facet_attributes.uuid}`]: {
|
|
102
|
-
status: 'ERROR',
|
|
103
|
-
error: 'CVE API call failed',
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
// Should render UnknownIcon when CVE API fails
|
|
108
|
-
expect(screen.getByRole('img', { hidden: true })).toBeTruthy();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('renders UnknownIcon when IoP is undefined (API call pending)', () => {
|
|
112
|
-
renderWithStore(<CVECountCell hostDetails={hostDetailsMock} />, {
|
|
113
|
-
router: {
|
|
114
|
-
location: {
|
|
115
|
-
pathname: '/',
|
|
116
|
-
search: '',
|
|
117
|
-
hash: '',
|
|
118
|
-
query: {},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
API: {
|
|
122
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
123
|
-
status: 'PENDING',
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
});
|
|
25
|
+
render(<CVECountCell hostDetails={hostDetailsMock} />);
|
|
127
26
|
expect(screen.getByRole('img', { hidden: true })).toBeTruthy();
|
|
128
27
|
});
|
|
129
28
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
import { foremanUrl, vulnerabilityDisabled
|
|
2
|
+
import { foremanUrl, vulnerabilityDisabled } from '../ForemanRhCloudHelpers';
|
|
3
3
|
|
|
4
4
|
global.URL_PREFIX = 'MY_TEST_URL_PREFIX.example.com';
|
|
5
5
|
|
|
@@ -34,21 +34,6 @@ const fixtures = {
|
|
|
34
34
|
}),
|
|
35
35
|
'vulnerabilityDisabled returns true for missing hostDetails': () =>
|
|
36
36
|
vulnerabilityDisabled({}),
|
|
37
|
-
'hasNoInsightsFacet returns false when insights_attributes is present': () =>
|
|
38
|
-
hasNoInsightsFacet({
|
|
39
|
-
response: {
|
|
40
|
-
insights_attributes: {
|
|
41
|
-
uuid: 'test-uuid',
|
|
42
|
-
insights_hits_count: 5,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
}),
|
|
46
|
-
'hasNoInsightsFacet returns true when insights_attributes is missing': () =>
|
|
47
|
-
hasNoInsightsFacet({
|
|
48
|
-
response: {},
|
|
49
|
-
}),
|
|
50
|
-
'hasNoInsightsFacet returns true when response is missing': () =>
|
|
51
|
-
hasNoInsightsFacet({}),
|
|
52
37
|
};
|
|
53
38
|
|
|
54
39
|
describe('ForemanRhCloud helpers', () =>
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`ForemanRhCloud helpers hasNoInsightsFacet returns false when insights_attributes is present 1`] = `false`;
|
|
4
|
-
|
|
5
|
-
exports[`ForemanRhCloud helpers hasNoInsightsFacet returns true when insights_attributes is missing 1`] = `true`;
|
|
6
|
-
|
|
7
|
-
exports[`ForemanRhCloud helpers hasNoInsightsFacet returns true when response is missing 1`] = `true`;
|
|
8
|
-
|
|
9
3
|
exports[`ForemanRhCloud helpers should return foreman Url 1`] = `"MY_TEST_URL_PREFIX.example.com/test_path"`;
|
|
10
4
|
|
|
11
5
|
exports[`ForemanRhCloud helpers vulnerabilityDisabled returns false for RHEL host with vulnerability enabled 1`] = `false`;
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
|
2
|
+
import {
|
|
3
|
+
ADVISOR_ENGINE_CONFIG_KEY,
|
|
4
|
+
ADVISOR_ENGINE_CONFIG_PATH,
|
|
5
|
+
} from '../../InsightsCloudSync/Components/InsightsTable/InsightsTableConstants';
|
|
6
|
+
|
|
7
|
+
export const useAdvisorEngineConfig = () => {
|
|
8
|
+
const { response: advisorEngineConfig } = useAPI(
|
|
9
|
+
'get',
|
|
10
|
+
ADVISOR_ENGINE_CONFIG_PATH,
|
|
11
|
+
{
|
|
12
|
+
key: ADVISOR_ENGINE_CONFIG_KEY,
|
|
13
|
+
}
|
|
14
|
+
);
|
|
2
15
|
|
|
3
|
-
export const useIopConfig = () =>
|
|
4
16
|
// eslint-disable-next-line camelcase
|
|
5
|
-
|
|
17
|
+
return advisorEngineConfig?.use_iop_mode;
|
|
18
|
+
};
|