foreman_rh_cloud 12.2.0 → 12.2.2
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/controllers/insights_cloud/ui_requests_controller.rb +11 -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/url_remediations_retriever.rb +1 -1
- 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 +8 -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 +8 -131
- data/lib/foreman_rh_cloud/plugin.rb +150 -0
- 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_cloud/ui_requests_controller_test.rb +23 -0
- 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/slice_generator_test.rb +33 -0
- data/test/unit/tags_generator_test.rb +4 -1
- data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +2 -1
- data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.scss +3 -0
- data/webpack/CveDetailsPage/CveDetailsPage.js +1 -1
- data/webpack/CveDetailsPage/CveDetailsPage.test.js +1 -3
- data/webpack/ForemanColumnExtensions/index.js +20 -15
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +23 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/PageDescription.test.js +2 -0
- 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 +16 -15
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +1 -1
- data/webpack/IopRecommendationDetails/IopRecommendationDetails.js +1 -11
- data/webpack/common/Hooks/ConfigHooks.js +1 -2
- data/webpack/common/styles.scss +7 -0
- metadata +6 -1
@@ -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', () => {
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
4
|
+
import { Link } from 'react-router-dom';
|
3
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
4
6
|
import { propsToCamelCase } from 'foremanReact/common/helpers';
|
5
7
|
import { CVECountCell } from '../InsightsVulnerabilityHostIndexExtensions/CVECountCell';
|
6
|
-
import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
|
7
8
|
|
8
9
|
const HostedRecommendationsCell = hostDetails => {
|
9
10
|
const insightsAttributes = propsToCamelCase(
|
@@ -18,22 +19,26 @@ const HostedRecommendationsCell = hostDetails => {
|
|
18
19
|
return <a href={hitsUrl}>{hitsCount}</a>;
|
19
20
|
};
|
20
21
|
|
21
|
-
const IopRecommendationsCell = hostDetails => {
|
22
|
-
|
23
|
-
const
|
22
|
+
const IopRecommendationsCell = ({ hostDetails }) => {
|
23
|
+
// eslint-disable-next-line camelcase
|
24
|
+
const uuid = hostDetails?.insights_attributes?.uuid;
|
25
|
+
const { response } = useAPI(
|
26
|
+
uuid ? 'get' : null,
|
27
|
+
`/insights_cloud/api/insights/v1/system/${uuid}`,
|
28
|
+
{ key: `HOST_RECS_COUNT_${uuid}` }
|
29
|
+
);
|
24
30
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
const hits = response?.hits;
|
32
|
+
return hits === undefined ? (
|
33
|
+
'—'
|
34
|
+
) : (
|
35
|
+
<Link to={`hosts/${hostDetails.name}#/Insights`}>{hits}</Link>
|
29
36
|
);
|
30
37
|
};
|
31
38
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
</ScalprumProvider>
|
36
|
-
);
|
39
|
+
IopRecommendationsCell.propTypes = {
|
40
|
+
hostDetails: PropTypes.object.isRequired,
|
41
|
+
};
|
37
42
|
|
38
43
|
const RecommendationsCell = hostDetails => {
|
39
44
|
const insightsAttributes = propsToCamelCase(
|
@@ -42,7 +47,7 @@ const RecommendationsCell = hostDetails => {
|
|
42
47
|
);
|
43
48
|
|
44
49
|
return insightsAttributes.useLocalAdvisorEngine ? (
|
45
|
-
<
|
50
|
+
<IopRecommendationsCell hostDetails={hostDetails} />
|
46
51
|
) : (
|
47
52
|
<HostedRecommendationsCell hostDetails={hostDetails} />
|
48
53
|
);
|
@@ -3,6 +3,7 @@ import { Text } from '@patternfly/react-core';
|
|
3
3
|
import { useSelector } from 'react-redux';
|
4
4
|
|
5
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
6
|
+
import { getDocsURL } from 'foremanReact/common/helpers';
|
6
7
|
import { FormattedMessage } from 'react-intl';
|
7
8
|
import { selectSubscriptionConnectionEnabled } from '../../../InventorySettings/InventorySettingsSelectors';
|
8
9
|
|
@@ -53,6 +54,28 @@ export const PageDescription = () => {
|
|
53
54
|
/>
|
54
55
|
</Text>
|
55
56
|
)}
|
57
|
+
<Text ouiaId="text-minimal-data-collection">
|
58
|
+
<FormattedMessage
|
59
|
+
id="minimal-data-collection-message"
|
60
|
+
defaultMessage={__(
|
61
|
+
'Learn more about {minimalDataCollectionSetting}.'
|
62
|
+
)}
|
63
|
+
values={{
|
64
|
+
minimalDataCollectionSetting: (
|
65
|
+
<a
|
66
|
+
href={getDocsURL(
|
67
|
+
'Managing_Hosts',
|
68
|
+
'setting-minimal-data-collection'
|
69
|
+
)}
|
70
|
+
target="_blank"
|
71
|
+
rel="noopener noreferrer"
|
72
|
+
>
|
73
|
+
{__('setting minimal data collection')}
|
74
|
+
</a>
|
75
|
+
),
|
76
|
+
}}
|
77
|
+
/>
|
78
|
+
</Text>
|
56
79
|
<Text ouiaId="text-more-info-subscription">
|
57
80
|
{__('For more information about the Subscriptions service, see:')}
|
58
81
|
|
@@ -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,
|
@@ -1,5 +1,6 @@
|
|
1
1
|
/* eslint-disable react-hooks/exhaustive-deps */
|
2
2
|
import React, { useEffect } from 'react';
|
3
|
+
import Immutable from 'seamless-immutable';
|
3
4
|
import PropTypes from 'prop-types';
|
4
5
|
import {
|
5
6
|
Table,
|
@@ -7,7 +8,7 @@ import {
|
|
7
8
|
TableBody,
|
8
9
|
} from '@patternfly/react-table/deprecated';
|
9
10
|
import { Modal, ModalVariant, Button } from '@patternfly/react-core';
|
10
|
-
import { isEmpty } from 'lodash';
|
11
|
+
import { isEmpty, noop } from 'lodash';
|
11
12
|
import { STATUS } from 'foremanReact/constants';
|
12
13
|
import { translate as __ } from 'foremanReact/common/I18n';
|
13
14
|
import { columns } from './RemediationTableConstants';
|
@@ -15,8 +16,48 @@ import { modifyRows } from './RemediationHelpers';
|
|
15
16
|
import ModalFooter from './RemediationModalFooter';
|
16
17
|
import TableEmptyState from '../../../common/table/EmptyState';
|
17
18
|
import './RemediationModal.scss';
|
19
|
+
import { useAdvisorEngineConfig } from '../../../common/Hooks/ConfigHooks';
|
20
|
+
|
21
|
+
/* eslint-disable spellcheck/spell-checker */
|
22
|
+
|
23
|
+
// Sample iopData:
|
24
|
+
// const iopTestData = Immutable([
|
25
|
+
// {
|
26
|
+
// hostid: 'c7c6727e-2966-4f7c-87f1-20ef14db7a2d',
|
27
|
+
// host_name: 'advisor-test.local',
|
28
|
+
// rulename: 'hardening_cryptopol_krb5|NO_CPOL_KRB5',
|
29
|
+
// resolutions: [
|
30
|
+
// {
|
31
|
+
// description: 'Remove manual crypto-policies',
|
32
|
+
// id: 'fix',
|
33
|
+
// needs_reboot: true,
|
34
|
+
// resolution_risk: 1,
|
35
|
+
// },
|
36
|
+
// ],
|
37
|
+
// rebootable: true,
|
38
|
+
// description: 'Decreased security: krb5 crypto-policies overridden',
|
39
|
+
// },
|
40
|
+
// {
|
41
|
+
// hostid: 'c7c6727e-2966-4f7c-87f1-20ef14db7a2d',
|
42
|
+
// host_name: 'advisor-test.local',
|
43
|
+
// rulename: 'hardening_logging_auditd|HARDENING_LOGGING_5_AUDITD',
|
44
|
+
// resolutions: [
|
45
|
+
// {
|
46
|
+
// description: 'Install and enable auditd',
|
47
|
+
// id: 'fix',
|
48
|
+
// needs_reboot: false,
|
49
|
+
// resolution_risk: 1,
|
50
|
+
// },
|
51
|
+
// ],
|
52
|
+
// rebootable: false,
|
53
|
+
// description: 'Decreased security: auditd not running',
|
54
|
+
// },
|
55
|
+
// ]);
|
56
|
+
|
57
|
+
/* eslint-enable spellcheck/spell-checker */
|
18
58
|
|
19
59
|
const RemediationModal = ({
|
60
|
+
iopData,
|
20
61
|
selectedIds,
|
21
62
|
fetchRemediations,
|
22
63
|
remediations,
|
@@ -24,31 +65,49 @@ const RemediationModal = ({
|
|
24
65
|
error,
|
25
66
|
isAllSelected,
|
26
67
|
query,
|
68
|
+
isDisabled,
|
27
69
|
}) => {
|
28
|
-
const
|
70
|
+
const iopRows = Immutable(iopData ?? []).map(recommendation => ({
|
71
|
+
id: recommendation.rulename,
|
72
|
+
host_id: recommendation.hostid,
|
73
|
+
hostname: recommendation.host_name,
|
74
|
+
title: recommendation.description,
|
75
|
+
resolutions: recommendation.resolutions ?? [],
|
76
|
+
reboot: recommendation.rebootable,
|
77
|
+
}));
|
78
|
+
|
29
79
|
const [open, setOpen] = React.useState(false);
|
30
80
|
const [resolutions, setResolutions] = React.useState([]);
|
31
81
|
const [hostsIds, setHostsIds] = React.useState([]);
|
82
|
+
const [rows, setRows] = React.useState([]);
|
32
83
|
const toggleModal = () => setOpen(prevValue => !prevValue);
|
33
84
|
|
85
|
+
const isIop = useAdvisorEngineConfig();
|
34
86
|
useEffect(() => {
|
35
|
-
|
87
|
+
// only fetch for Hosted. IoP provides via props.
|
88
|
+
if (!isIop && open)
|
89
|
+
fetchRemediations({ selectedIds, isAllSelected, query });
|
36
90
|
}, [open]);
|
37
91
|
|
38
92
|
useEffect(() => {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
93
|
+
let modifiedRows;
|
94
|
+
if (isIop) {
|
95
|
+
modifiedRows = modifyRows(iopRows, setResolutions, setHostsIds, true);
|
96
|
+
} else {
|
97
|
+
modifiedRows =
|
98
|
+
status === STATUS.PENDING
|
99
|
+
? []
|
100
|
+
: modifyRows(remediations, setResolutions, setHostsIds, false);
|
101
|
+
}
|
43
102
|
setRows(modifiedRows);
|
44
|
-
}, [remediations, status]);
|
103
|
+
}, [remediations, status, iopData, isIop]);
|
45
104
|
|
46
105
|
return (
|
47
106
|
<React.Fragment>
|
48
107
|
<Button
|
49
108
|
ouiaId="button-remediate"
|
50
109
|
variant="primary"
|
51
|
-
isDisabled={isEmpty(selectedIds)}
|
110
|
+
isDisabled={isDisabled || isEmpty(selectedIds)}
|
52
111
|
onClick={() => {
|
53
112
|
toggleModal();
|
54
113
|
}}
|
@@ -68,6 +127,7 @@ const RemediationModal = ({
|
|
68
127
|
toggleModal={toggleModal}
|
69
128
|
resolutions={resolutions}
|
70
129
|
hostsIds={hostsIds}
|
130
|
+
isIop={isIop}
|
71
131
|
/>
|
72
132
|
}
|
73
133
|
>
|
@@ -92,22 +152,36 @@ const RemediationModal = ({
|
|
92
152
|
};
|
93
153
|
|
94
154
|
RemediationModal.propTypes = {
|
95
|
-
|
96
|
-
|
155
|
+
iopData: PropTypes.arrayOf(
|
156
|
+
PropTypes.shape({
|
157
|
+
hostid: PropTypes.string,
|
158
|
+
host_name: PropTypes.string,
|
159
|
+
rulename: PropTypes.string,
|
160
|
+
resolutions: PropTypes.array,
|
161
|
+
rebootable: PropTypes.bool,
|
162
|
+
description: PropTypes.string,
|
163
|
+
})
|
164
|
+
),
|
165
|
+
selectedIds: PropTypes.shape({}),
|
166
|
+
fetchRemediations: PropTypes.func,
|
97
167
|
remediations: PropTypes.array,
|
98
168
|
status: PropTypes.string,
|
99
169
|
error: PropTypes.string,
|
100
170
|
isAllSelected: PropTypes.bool,
|
101
171
|
query: PropTypes.string,
|
172
|
+
isDisabled: PropTypes.bool,
|
102
173
|
};
|
103
174
|
|
104
175
|
RemediationModal.defaultProps = {
|
176
|
+
iopData: null,
|
105
177
|
selectedIds: {},
|
178
|
+
fetchRemediations: noop,
|
106
179
|
remediations: [],
|
107
180
|
status: null,
|
108
181
|
error: null,
|
109
182
|
isAllSelected: false,
|
110
183
|
query: null,
|
184
|
+
isDisabled: false,
|
111
185
|
};
|
112
186
|
|
113
187
|
export default RemediationModal;
|
@@ -2,18 +2,44 @@ import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Button } from '@patternfly/react-core';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
|
5
6
|
import { JOB_INVOCATION_PATH } from './RemediationTableConstants';
|
6
7
|
|
7
|
-
const ModalFooter = ({ toggleModal, resolutions, hostsIds }) => {
|
8
|
+
const ModalFooter = ({ toggleModal, resolutions, hostsIds, isIop }) => {
|
8
9
|
let token = document.querySelector('meta[name="csrf-token"]');
|
9
10
|
token = token?.content || '';
|
11
|
+
|
12
|
+
const [jobInProgress, setJobInProgress] = React.useState(false);
|
13
|
+
const formRef = React.useRef(null);
|
14
|
+
|
15
|
+
const { fetchBulkParams } = useBulkSelect({
|
16
|
+
initialArry: hostsIds,
|
17
|
+
idColumn: 'insights_uuid',
|
18
|
+
});
|
19
|
+
|
20
|
+
const handleSubmit = e => {
|
21
|
+
e.preventDefault();
|
22
|
+
setJobInProgress(true);
|
23
|
+
|
24
|
+
setTimeout(() => {
|
25
|
+
// eslint-disable-next-line no-unused-expressions
|
26
|
+
formRef.current?.submit?.();
|
27
|
+
}, 100);
|
28
|
+
};
|
10
29
|
return (
|
11
|
-
<form
|
30
|
+
<form
|
31
|
+
action={JOB_INVOCATION_PATH}
|
32
|
+
method="post"
|
33
|
+
ref={formRef}
|
34
|
+
onSubmit={handleSubmit}
|
35
|
+
>
|
12
36
|
<Button
|
13
37
|
type="submit"
|
14
38
|
ouiaId="button-confirm"
|
15
39
|
key="confirm"
|
16
40
|
variant="primary"
|
41
|
+
isDisabled={jobInProgress}
|
42
|
+
isLoading={jobInProgress}
|
17
43
|
>
|
18
44
|
{__('Remediate')}
|
19
45
|
</Button>
|
@@ -32,9 +58,15 @@ const ModalFooter = ({ toggleModal, resolutions, hostsIds }) => {
|
|
32
58
|
name="inputs[hit_remediation_pairs]"
|
33
59
|
value={JSON.stringify(resolutions)}
|
34
60
|
/>
|
35
|
-
{
|
36
|
-
|
37
|
-
|
61
|
+
{!isIop &&
|
62
|
+
hostsIds.map(id => (
|
63
|
+
<input type="hidden" name="host_ids[]" key={id} value={id} />
|
64
|
+
))}
|
65
|
+
{isIop && (
|
66
|
+
<>
|
67
|
+
<input type="hidden" name="search" value={fetchBulkParams()} />
|
68
|
+
</>
|
69
|
+
)}
|
38
70
|
</form>
|
39
71
|
);
|
40
72
|
};
|
@@ -43,11 +75,13 @@ ModalFooter.propTypes = {
|
|
43
75
|
toggleModal: PropTypes.func.isRequired,
|
44
76
|
resolutions: PropTypes.array,
|
45
77
|
hostsIds: PropTypes.array,
|
78
|
+
isIop: PropTypes.bool,
|
46
79
|
};
|
47
80
|
|
48
81
|
ModalFooter.defaultProps = {
|
49
82
|
resolutions: [],
|
50
83
|
hostsIds: [],
|
84
|
+
isIop: false,
|
51
85
|
};
|
52
86
|
|
53
87
|
export default ModalFooter;
|
@@ -2,12 +2,14 @@
|
|
2
2
|
import React from 'react';
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
import { Radio } from '@patternfly/react-core';
|
5
|
+
import { getResolutionId } from './RemediationHelpers';
|
5
6
|
|
6
7
|
const Resolutions = ({
|
7
8
|
resolutions,
|
8
9
|
setResolutions,
|
9
10
|
selectedResolution,
|
10
11
|
hit_id,
|
12
|
+
isIop,
|
11
13
|
}) => {
|
12
14
|
const [checkedID, setCheckedID] = React.useState(selectedResolution);
|
13
15
|
|
@@ -27,6 +29,15 @@ const Resolutions = ({
|
|
27
29
|
stateRes.map(res => {
|
28
30
|
if (hit_id === res.hit_id) {
|
29
31
|
setCheckedID(resolution_id);
|
32
|
+
if (isIop)
|
33
|
+
return {
|
34
|
+
...res,
|
35
|
+
resolution_id: getResolutionId(
|
36
|
+
resolution_id,
|
37
|
+
res.rule_id
|
38
|
+
),
|
39
|
+
resolution_type: resolution_id,
|
40
|
+
};
|
30
41
|
return { ...res, resolution_id };
|
31
42
|
}
|
32
43
|
return res;
|
@@ -45,12 +56,14 @@ Resolutions.propTypes = {
|
|
45
56
|
resolutions: PropTypes.array,
|
46
57
|
hit_id: PropTypes.number,
|
47
58
|
selectedResolution: PropTypes.number,
|
59
|
+
isIop: PropTypes.bool,
|
48
60
|
};
|
49
61
|
|
50
62
|
Resolutions.defaultProps = {
|
51
63
|
resolutions: [],
|
52
64
|
hit_id: null,
|
53
65
|
selectedResolution: null,
|
66
|
+
isIop: false,
|
54
67
|
};
|
55
68
|
|
56
69
|
export default Resolutions;
|
@@ -67,13 +67,15 @@ export const generateRuleUrl = ruleId =>
|
|
67
67
|
foremanUrl(`/foreman_rh_cloud/recommendations/${ruleId}`);
|
68
68
|
|
69
69
|
const IopRecommendationsPage = props => (
|
70
|
-
<
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
<div className="advisor">
|
71
|
+
<ScalprumComponent
|
72
|
+
scope={scope}
|
73
|
+
module={module}
|
74
|
+
IopRemediationModal={RemediationModal}
|
75
|
+
generateRuleUrl={generateRuleUrl}
|
76
|
+
{...props}
|
77
|
+
/>
|
78
|
+
</div>
|
77
79
|
);
|
78
80
|
|
79
81
|
const IopRecommendationsPageWrapped = props => (
|
@@ -110,17 +110,18 @@ NewHostDetailsTab.defaultProps = {
|
|
110
110
|
|
111
111
|
// Local Insights advisor
|
112
112
|
const scope = 'advisor';
|
113
|
-
|
114
|
-
const module = './HostDetailsLightspeedTabWrapped';
|
113
|
+
const module = './SystemDetailWrapped';
|
115
114
|
|
116
115
|
const IopInsightsTab = props => (
|
117
|
-
<
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
116
|
+
<div className="advisor">
|
117
|
+
<ScalprumComponent
|
118
|
+
scope={scope}
|
119
|
+
module={module}
|
120
|
+
IopRemediationModal={RemediationModal}
|
121
|
+
generateRuleUrl={generateRuleUrl}
|
122
|
+
{...props}
|
123
|
+
/>
|
124
|
+
</div>
|
124
125
|
);
|
125
126
|
|
126
127
|
const IopInsightsTabWrapped = props => (
|
@@ -129,11 +130,11 @@ const IopInsightsTabWrapped = props => (
|
|
129
130
|
</ScalprumProvider>
|
130
131
|
);
|
131
132
|
|
132
|
-
const
|
133
|
+
const InsightsTab = props => {
|
133
134
|
const { response } = props;
|
134
135
|
const isLocalAdvisorEngine =
|
135
136
|
// eslint-disable-next-line camelcase
|
136
|
-
response?.insights_attributes?.
|
137
|
+
response?.insights_attributes?.use_iop_mode;
|
137
138
|
|
138
139
|
return isLocalAdvisorEngine ? (
|
139
140
|
<IopInsightsTabWrapped {...props} />
|
@@ -142,16 +143,16 @@ const LightspeedTab = props => {
|
|
142
143
|
);
|
143
144
|
};
|
144
145
|
|
145
|
-
|
146
|
+
InsightsTab.propTypes = {
|
146
147
|
response: PropTypes.shape({
|
147
148
|
insights_attributes: {
|
148
|
-
|
149
|
+
use_iop_mode: PropTypes.bool,
|
149
150
|
},
|
150
151
|
}),
|
151
152
|
};
|
152
153
|
|
153
|
-
|
154
|
+
InsightsTab.defaultProps = {
|
154
155
|
response: {},
|
155
156
|
};
|
156
157
|
|
157
|
-
export default
|
158
|
+
export default InsightsTab;
|
@@ -6,7 +6,7 @@ const InsightsVulnerabilityListPage = () => {
|
|
6
6
|
const scope = 'vulnerability';
|
7
7
|
const module = './CveListPage';
|
8
8
|
return (
|
9
|
-
<div className="rh-cloud-insights-vulnerability-page">
|
9
|
+
<div className="rh-cloud-insights-vulnerability-page vulnerability">
|
10
10
|
<ScalprumComponent scope={scope} module={module} />
|
11
11
|
</div>
|
12
12
|
);
|
@@ -8,15 +8,12 @@ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
|
|
8
8
|
const scope = 'advisor';
|
9
9
|
const module = './RecommendationDetailsWrapped';
|
10
10
|
|
11
|
-
const invScope = 'inventory';
|
12
|
-
const invModule = './HybridInventoryTabs';
|
13
|
-
|
14
11
|
const IopRecommendationDetails = props => {
|
15
12
|
const urlParams = useRouteMatch('/foreman_rh_cloud/recommendations/:rule_id');
|
16
13
|
// eslint-disable-next-line camelcase
|
17
14
|
const ruleId = urlParams?.params?.rule_id;
|
18
15
|
return (
|
19
|
-
<div className="
|
16
|
+
<div className="iop-recommendation-details-scalprum advisor">
|
20
17
|
<ScalprumComponent
|
21
18
|
scope={scope}
|
22
19
|
module={module}
|
@@ -24,13 +21,6 @@ const IopRecommendationDetails = props => {
|
|
24
21
|
ruleId={ruleId}
|
25
22
|
{...props}
|
26
23
|
/>
|
27
|
-
<ScalprumComponent
|
28
|
-
scope={invScope}
|
29
|
-
module={invModule}
|
30
|
-
IopRemediationModal={RemediationModal}
|
31
|
-
ruleId={ruleId}
|
32
|
-
{...props}
|
33
|
-
/>
|
34
24
|
</div>
|
35
25
|
);
|
36
26
|
};
|