foreman_rh_cloud 12.1.3 → 12.1.5

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -5
  3. data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +33 -0
  4. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -2
  5. data/app/controllers/insights_cloud/ui_requests_controller.rb +99 -0
  6. data/app/services/foreman_rh_cloud/cert_auth.rb +9 -1
  7. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +12 -13
  8. data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
  9. data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +116 -0
  10. data/app/services/foreman_rh_cloud/tags_auth.rb +55 -0
  11. data/app/views/api/v2/hosts/insights/base.rabl +6 -0
  12. data/config/routes.rb +2 -0
  13. data/lib/foreman_inventory_upload/async/generate_report_job.rb +11 -5
  14. data/lib/foreman_inventory_upload/async/upload_report_job.rb +15 -4
  15. data/lib/foreman_inventory_upload/generators/archived_report.rb +2 -2
  16. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +65 -13
  17. data/lib/foreman_inventory_upload/generators/queries.rb +7 -5
  18. data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
  19. data/lib/foreman_inventory_upload.rb +2 -2
  20. data/lib/foreman_rh_cloud/engine.rb +5 -3
  21. data/lib/foreman_rh_cloud/version.rb +1 -1
  22. data/lib/insights_cloud.rb +8 -0
  23. data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
  24. data/lib/tasks/rh_cloud_inventory.rake +3 -2
  25. data/package.json +5 -1
  26. data/test/controllers/insights_cloud/ui_requests_controller_test.rb +169 -0
  27. data/test/unit/archived_report_generator_test.rb +1 -1
  28. data/test/unit/fact_helpers_test.rb +267 -2
  29. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +20 -3
  30. data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +176 -0
  31. data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +29 -0
  32. data/test/unit/slice_generator_test.rb +69 -10
  33. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +30 -10
  34. data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +18 -11
  35. data/webpack/CVEsHostDetailsTab/index.js +2 -2
  36. data/webpack/ForemanColumnExtensions/index.js +51 -0
  37. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -0
  38. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +1 -0
  39. data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +2 -0
  40. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +8 -1
  41. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +4 -0
  42. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +3 -3
  43. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +3 -0
  44. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +10 -4
  45. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +6 -6
  46. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +2 -0
  47. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +2 -0
  48. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +1 -0
  49. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +1 -0
  50. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
  51. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +3 -0
  52. data/webpack/ForemanRhCloudFills.js +6 -3
  53. data/webpack/ForemanRhCloudPages.js +6 -3
  54. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -0
  55. data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +2 -0
  56. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +1 -0
  57. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +3 -0
  58. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +12 -2
  59. data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -0
  60. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +6 -1
  61. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +21 -0
  62. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js +20 -0
  63. data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +45 -0
  64. data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +28 -0
  65. data/webpack/common/DropdownToggle.js +1 -0
  66. data/webpack/common/ScalprumModule/ScalprumContext.js +63 -0
  67. data/webpack/common/Switcher/SwitcherPF4.js +1 -0
  68. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
  69. data/webpack/common/Switcher/index.js +1 -0
  70. data/webpack/global_index.js +3 -0
  71. metadata +19 -4
  72. data/webpack/InsightsVulnerability/InsightsVulnerability.js +0 -13
  73. data/webpack/InsightsVulnerability/InsightsVulnerability.test.js +0 -18
@@ -1,17 +1,37 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
4
5
 
5
- const CVEsHostDetailsTab = ({ hostName }) => (
6
- <div>
7
- <h1>
8
- {__('CVEs tab for host:')} {hostName}
9
- </h1>
10
- </div>
11
- );
6
+ const CVEsHostDetailsTab = ({ systemId }) => {
7
+ const scope = 'vulnerability';
8
+ const module = './SystemDetailTable';
9
+ return (
10
+ <div className="rh-cloud-insights-vulnerability-host-details-component">
11
+ <ScalprumComponent scope={scope} module={module} systemId={systemId} />
12
+ </div>
13
+ );
14
+ };
12
15
 
13
16
  CVEsHostDetailsTab.propTypes = {
14
- hostName: PropTypes.string.isRequired,
17
+ systemId: PropTypes.string.isRequired,
18
+ };
19
+
20
+ const CVEsHostDetailsTabWrapper = ({ response }) => (
21
+ <ScalprumProvider {...providerOptions}>
22
+ <CVEsHostDetailsTab
23
+ // eslint-disable-next-line camelcase
24
+ systemId={response?.subscription_facet_attributes?.uuid}
25
+ />
26
+ </ScalprumProvider>
27
+ );
28
+
29
+ CVEsHostDetailsTabWrapper.propTypes = {
30
+ response: PropTypes.shape({
31
+ subscription_facet_attributes: PropTypes.shape({
32
+ uuid: PropTypes.string.isRequired,
33
+ }),
34
+ }).isRequired,
15
35
  };
16
36
 
17
- export default CVEsHostDetailsTab;
37
+ export default CVEsHostDetailsTabWrapper;
@@ -1,18 +1,25 @@
1
1
  import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import CVEsHostDetailsTab from '../CVEsHostDetailsTab';
2
+ import { render } from '@testing-library/react';
3
+ import CVEsHostDetailsTabWrapper from '../CVEsHostDetailsTab';
4
4
 
5
- describe('CVEsHostDetailsTab', () => {
5
+ jest.mock('@scalprum/react-core', () => ({
6
+ ScalprumComponent: jest.fn(props => (
7
+ <div data-testid="mock-scalprum-component">{JSON.stringify(props)}</div>
8
+ )),
9
+ ScalprumProvider: jest.fn(({ children }) => <div>{children}</div>),
10
+ }));
11
+
12
+ describe('CVEsHostDetailsTabWrapper', () => {
6
13
  it('renders without crashing', () => {
7
- render(<CVEsHostDetailsTab hostName="test-host.example.com" />);
14
+ const { container } = render(
15
+ <CVEsHostDetailsTabWrapper
16
+ response={{ subscription_facet_attributes: { uuid: '1-2-3' } }}
17
+ />
18
+ );
8
19
  expect(
9
- screen.getByText('CVEs tab for host: test-host.example.com')
20
+ container.querySelector(
21
+ '.rh-cloud-insights-vulnerability-host-details-component'
22
+ )
10
23
  ).toBeTruthy();
11
24
  });
12
-
13
- it('renders the host name', () => {
14
- const hostName = 'test-host.example.com';
15
- render(<CVEsHostDetailsTab hostName={hostName} />);
16
- expect(screen.getByText(`CVEs tab for host: ${hostName}`)).toBeTruthy();
17
- });
18
25
  });
@@ -1,3 +1,3 @@
1
- import CVEsHostDetailsTab from './CVEsHostDetailsTab';
1
+ import CVEsHostDetailsTabWrapper from './CVEsHostDetailsTab';
2
2
 
3
- export default CVEsHostDetailsTab;
3
+ export default CVEsHostDetailsTabWrapper;
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { propsToCamelCase } from 'foremanReact/common/helpers';
4
+ import { CVECountCell } from '../InsightsVulnerabilityHostIndexExtensions/CVECountCell';
5
+
6
+ const RecommendationsCell = hostDetails => {
7
+ const insightsAttributes = propsToCamelCase(
8
+ // eslint-disable-next-line camelcase
9
+ hostDetails?.insights_attributes ?? {}
10
+ );
11
+ // Local insights advisor
12
+ if (insightsAttributes.useLocalAdvisorEngine) {
13
+ // TODO: Replace this placeholder with the actual local advisor integration
14
+ return <span>Local advisor placeholder</span>;
15
+ }
16
+
17
+ // Hosted insights advisor
18
+ const { insightsHitsCount: hitsCount } = insightsAttributes;
19
+ if (hitsCount === undefined || hitsCount === null) return '—';
20
+ const hostname = hostDetails?.name;
21
+ const encodedHostname = encodeURIComponent(hostname);
22
+ const hitsUrl = `/foreman_rh_cloud/insights_cloud?search=hostname+%3D+${encodedHostname}`;
23
+ return <a href={hitsUrl}>{hitsCount}</a>;
24
+ };
25
+
26
+ const insightsCategoryName = __('Insights');
27
+
28
+ const hostsIndexColumnExtensions = [
29
+ {
30
+ columnName: 'insights_recommendations_count',
31
+ title: __('Recommendations'),
32
+ wrapper: RecommendationsCell,
33
+ weight: 1500,
34
+ isSorted: true,
35
+ tableName: 'hosts',
36
+ categoryName: insightsCategoryName,
37
+ categoryKey: 'insights',
38
+ },
39
+ {
40
+ columnName: 'cves_count',
41
+ title: __('Total CVEs'),
42
+ wrapper: hostDetails => <CVECountCell hostDetails={hostDetails} />,
43
+ weight: 2600,
44
+ tableName: 'hosts',
45
+ categoryName: insightsCategoryName,
46
+ categoryKey: 'insights',
47
+ isSorted: false,
48
+ },
49
+ ];
50
+
51
+ export default hostsIndexColumnExtensions;
@@ -26,6 +26,7 @@ const InventoryFilter = ({
26
26
  <FormGroup>
27
27
  <TextInput
28
28
  id="inventory_filter_input"
29
+ ouiaId="inventory_filter_input"
29
30
  value={filterTerm}
30
31
  type="text"
31
32
  placeholder={__('Filter..')}
@@ -8,6 +8,7 @@ exports[`InventoryFilter rendering render with props 1`] = `
8
8
  <TextInput
9
9
  id="inventory_filter_input"
10
10
  onChange={[Function]}
11
+ ouiaId="inventory_filter_input"
11
12
  placeholder="Filter.."
12
13
  type="text"
13
14
  value="test_filter_term"
@@ -68,6 +68,7 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
68
68
  };
69
69
  return (
70
70
  <Dropdown
71
+ ouiaId="inventory-dropdown"
71
72
  isOpen={isOpen}
72
73
  onSelect={onSelect}
73
74
  onOpenChange={val => setIsOpen(val)}
@@ -90,6 +91,7 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
90
91
  value={value}
91
92
  key={value}
92
93
  description={item.description}
94
+ ouiaId={`inventory-dropdownItem-${value}`}
93
95
  >
94
96
  {item.title}
95
97
  </DropdownItem>
@@ -26,6 +26,7 @@ const PageTitle = () => {
26
26
  const dropdownItems = [
27
27
  <DropdownItem
28
28
  key="tasks-history-button"
29
+ ouiaId="tasks-history-button"
29
30
  href={getActionsHistoryUrl()}
30
31
  target="_blank"
31
32
  rel="noopener noreferrer"
@@ -34,13 +35,18 @@ const PageTitle = () => {
34
35
  </DropdownItem>,
35
36
  <DropdownItem
36
37
  key="inventory-documentation-button"
38
+ ouiaId="inventory-documentation-button"
37
39
  href={getInventoryDocsUrl()}
38
40
  target="_blank"
39
41
  rel="noopener noreferrer"
40
42
  >
41
43
  {DOCS_BUTTON_TEXT}
42
44
  </DropdownItem>,
43
- <DropdownItem key="cloud-ping" onClick={togglePingModal}>
45
+ <DropdownItem
46
+ key="cloud-ping"
47
+ ouiaId="dropdownItem-cloud-ping"
48
+ onClick={togglePingModal}
49
+ >
44
50
  {CLOUD_PING_TITLE}
45
51
  </DropdownItem>,
46
52
  ];
@@ -55,6 +61,7 @@ const PageTitle = () => {
55
61
  <GridItem span={6}>
56
62
  <Dropdown
57
63
  className="title-dropdown"
64
+ ouiaId="title-dropdown"
58
65
  onSelect={() => setIsDropdownOpen(false)}
59
66
  toggle={
60
67
  <KebabToggle
@@ -25,6 +25,7 @@ exports[`PageTitle rendering render without Props 1`] = `
25
25
  Array [
26
26
  <DropdownItem
27
27
  href="/foreman_tasks/tasks?search=label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AGenerateReportJob+or+label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AGenerateAllReportsJob&page=1"
28
+ ouiaId="tasks-history-button"
28
29
  rel="noopener noreferrer"
29
30
  target="_blank"
30
31
  >
@@ -32,6 +33,7 @@ exports[`PageTitle rendering render without Props 1`] = `
32
33
  </DropdownItem>,
33
34
  <DropdownItem
34
35
  href="/links/manual/?root_url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fen-us%2Fred_hat_insights%2F2023%2Fhtml%2Fred_hat_insights_remediations_guide%2Fhost-communication-with-insights_red-hat-insights-remediation-guide%23uploading-satellite-host-inventory-to-insights_configuring-satellite-cloud-connector"
36
+ ouiaId="inventory-documentation-button"
35
37
  rel="noopener noreferrer"
36
38
  target="_blank"
37
39
  >
@@ -39,6 +41,7 @@ exports[`PageTitle rendering render without Props 1`] = `
39
41
  </DropdownItem>,
40
42
  <DropdownItem
41
43
  onClick={[Function]}
44
+ ouiaId="dropdownItem-cloud-ping"
42
45
  >
43
46
  Connectivity test
44
47
  </DropdownItem>,
@@ -47,6 +50,7 @@ exports[`PageTitle rendering render without Props 1`] = `
47
50
  isOpen={false}
48
51
  isPlain={true}
49
52
  onSelect={[Function]}
53
+ ouiaId="title-dropdown"
50
54
  position="right"
51
55
  toggle={
52
56
  <KebabToggle
@@ -26,7 +26,7 @@ export const CloudConnectorButton = ({ status, onClick, jobLink }) => {
26
26
  className="cloud-connector-pending-button"
27
27
  onMouseEnter={() => setIsPopoverVisible(true)}
28
28
  >
29
- <Button variant="secondary" isDisabled>
29
+ <Button variant="secondary" ouiaId="button-in-progress" isDisabled>
30
30
  <Spinner size="sm" /> {__('Cloud Connector is in progress')}
31
31
  </Button>
32
32
  </div>
@@ -36,14 +36,14 @@ export const CloudConnectorButton = ({ status, onClick, jobLink }) => {
36
36
 
37
37
  if (status === CONNECTOR_STATUS.RESOLVED) {
38
38
  return (
39
- <Button variant="secondary" onClick={onClick}>
39
+ <Button variant="secondary" ouiaId="button-reconfigure" onClick={onClick}>
40
40
  {__('Reconfigure cloud connector')}
41
41
  </Button>
42
42
  );
43
43
  }
44
44
 
45
45
  return (
46
- <Button variant="secondary" onClick={onClick}>
46
+ <Button variant="secondary" ouiaId="button-configure" onClick={onClick}>
47
47
  {__('Configure cloud connector')}
48
48
  </Button>
49
49
  );
@@ -3,6 +3,7 @@
3
3
  exports[`CloudConnectorButton render no cloud connector 1`] = `
4
4
  <Button
5
5
  onClick={[MockFunction]}
6
+ ouiaId="button-configure"
6
7
  variant="secondary"
7
8
  >
8
9
  Configure cloud connector
@@ -34,6 +35,7 @@ exports[`CloudConnectorButton render pending connector 1`] = `
34
35
  >
35
36
  <Button
36
37
  isDisabled={true}
38
+ ouiaId="button-in-progress"
37
39
  variant="secondary"
38
40
  >
39
41
  <Spinner
@@ -49,6 +51,7 @@ exports[`CloudConnectorButton render pending connector 1`] = `
49
51
  exports[`CloudConnectorButton render resolved cloud connector 1`] = `
50
52
  <Button
51
53
  onClick={[MockFunction]}
54
+ ouiaId="button-reconfigure"
52
55
  variant="secondary"
53
56
  >
54
57
  Reconfigure cloud connector
@@ -79,26 +79,32 @@ const CloudPingModal = ({ title, isOpen, toggle }) => {
79
79
  <>
80
80
  <Modal
81
81
  id="cloud-ping-modal"
82
+ ouiaId="cloud-ping-modal"
82
83
  appendTo={document.getElementsByClassName('react-container')[0]}
83
84
  variant={ModalVariant.large}
84
85
  title={title}
85
86
  isOpen={isOpen}
86
87
  onClose={toggle}
87
88
  >
88
- <Card className="certs-status">
89
+ <Card className="certs-status" ouiaId="card-org-status">
89
90
  <CardTitle>{__('Organization status')}</CardTitle>
90
91
  <CardBody>
91
- <Text>
92
+ <Text ouiaId="text-description">
92
93
  {__('Displays manifest statuses per accessible organizations.')}
93
94
  </Text>
94
95
  {isPending ? (
95
96
  <Spinner size="xl" />
96
97
  ) : (
97
98
  <>
98
- <Text className="pull-right">
99
+ <Text className="pull-right" ouiaId="text-org-count">
99
100
  {sprintf(__('%s organizations'), rows.length)}
100
101
  </Text>
101
- <Table aria-label="Simple Table" cells={['']} rows={rows}>
102
+ <Table
103
+ aria-label="Simple Table"
104
+ ouiaId="simple-table"
105
+ cells={['']}
106
+ rows={rows}
107
+ >
102
108
  <TableHeader />
103
109
  <TableBody />
104
110
  </Table>{' '}
@@ -13,18 +13,18 @@ export const PageDescription = () => {
13
13
 
14
14
  return (
15
15
  <div id="inventory_page_description">
16
- <Text>
16
+ <Text ouiaId="text-cloud-console">
17
17
  {__(
18
18
  'The Red Hat Hybrid Cloud Console provides a set of cloud services, including Red Hat Insights and Subscriptions, that provide predictive analysis, remediation of issues, and unified subscription reporting for this Foreman instance.'
19
19
  )}
20
20
  </Text>
21
- <Text>
21
+ <Text ouiaId="text-inventory-upload">
22
22
  {__(
23
23
  'The Foreman inventory upload plugin automatically uploads Foreman host inventory data to the Inventory service of Insights, where it can also be used by the Subscriptions service for subscription reporting. If you use the Subscriptions service, enabling inventory uploads is required.'
24
24
  )}
25
25
  </Text>
26
26
  {subscriptionConnectionEnabled && (
27
- <Text>
27
+ <Text ouiaId="text-enable-report">
28
28
  <FormattedMessage
29
29
  id="enable-upload-hint"
30
30
  defaultMessage={__(
@@ -39,7 +39,7 @@ export const PageDescription = () => {
39
39
  </Text>
40
40
  )}
41
41
  {subscriptionConnectionEnabled && (
42
- <Text>
42
+ <Text ouiaId="text-restart-button">
43
43
  <FormattedMessage
44
44
  id="restart-button-hint"
45
45
  defaultMessage={__(
@@ -53,7 +53,7 @@ export const PageDescription = () => {
53
53
  />
54
54
  </Text>
55
55
  )}
56
- <Text>
56
+ <Text ouiaId="text-more-info-subscription">
57
57
  {__('For more information about the Subscriptions service, see:')}
58
58
  &nbsp;
59
59
  <a
@@ -64,7 +64,7 @@ export const PageDescription = () => {
64
64
  {__('About subscription watch')}
65
65
  </a>
66
66
  </Text>
67
- <Text>
67
+ <Text ouiaId="text-more-info-insights">
68
68
  {__('For more information about Insights and Cloud Connector, see:')}
69
69
  &nbsp;
70
70
  <a
@@ -22,6 +22,7 @@ export const SettingsWarning = ({
22
22
  alerts.push(
23
23
  <Alert
24
24
  key="auto-upload"
25
+ ouiaId="auto-upload"
25
26
  variant="warning"
26
27
  title={__(
27
28
  "Cloud Connector has been configured however the inventory auto-upload is disabled, it's recommended to enable it"
@@ -36,6 +37,7 @@ export const SettingsWarning = ({
36
37
  alerts.push(
37
38
  <Alert
38
39
  key="obfuscating-host"
40
+ ouiaId="obfuscating-host"
39
41
  variant="warning"
40
42
  title={__(
41
43
  "Cloud Connector has been configured however obfuscating host names setting is enabled, it's recommended to disable it"
@@ -11,6 +11,7 @@ exports[`SettingsWarning with 2 alerts 1`] = `
11
11
  />
12
12
  }
13
13
  key="auto-upload"
14
+ ouiaId="auto-upload"
14
15
  title="Cloud Connector has been configured however the inventory auto-upload is disabled, it's recommended to enable it"
15
16
  variant="warning"
16
17
  />
@@ -21,6 +22,7 @@ exports[`SettingsWarning with 2 alerts 1`] = `
21
22
  />
22
23
  }
23
24
  key="obfuscating-host"
25
+ ouiaId="obfuscating-host"
24
26
  title="Cloud Connector has been configured however obfuscating host names setting is enabled, it's recommended to disable it"
25
27
  variant="warning"
26
28
  />
@@ -21,6 +21,7 @@ class SyncButton extends React.Component {
21
21
  <React.Fragment>
22
22
  <Button
23
23
  className="sync_button"
24
+ ouiaId="sync-button"
24
25
  onClick={handleClick}
25
26
  isDisabled={status === STATUS.PENDING}
26
27
  variant="secondary"
@@ -6,6 +6,7 @@ exports[`SyncButton rendering render with Props 1`] = `
6
6
  className="sync_button"
7
7
  isDisabled={false}
8
8
  onClick={[Function]}
9
+ ouiaId="sync-button"
9
10
  variant="secondary"
10
11
  >
11
12
  Sync all inventory status
@@ -48,6 +48,7 @@ const InventoryAutoUploadSwitcher = ({
48
48
  position="right"
49
49
  >
50
50
  <Button
51
+ ouiaId="button-advanced-settings"
51
52
  variant="secondary"
52
53
  style={{ fontSize: 'small', marginTop: '-4px' }}
53
54
  >
@@ -59,9 +60,10 @@ const InventoryAutoUploadSwitcher = ({
59
60
  <br />
60
61
  <Grid.Row>
61
62
  <Grid.Col sm={12}>
62
- <Text component={TextVariants.p}>
63
+ <Text component={TextVariants.p} ouiaId="text-more-details">
63
64
  <InfoAltIcon /> {__('More details can be found in')}{' '}
64
65
  <Text
66
+ ouiaId="text-details-link"
65
67
  component={TextVariants.a}
66
68
  href={foremanUrl('/foreman_rh_cloud/inventory_upload')}
67
69
  target="_blank"
@@ -41,6 +41,7 @@ exports[`InventoryAutoUpload rendering render with props 1`] = `
41
41
  position="right"
42
42
  >
43
43
  <Button
44
+ ouiaId="button-advanced-settings"
44
45
  style={
45
46
  Object {
46
47
  "fontSize": "small",
@@ -68,6 +69,7 @@ exports[`InventoryAutoUpload rendering render with props 1`] = `
68
69
  >
69
70
  <Text
70
71
  component="p"
72
+ ouiaId="text-more-details"
71
73
  >
72
74
  <InfoAltIcon />
73
75
 
@@ -76,6 +78,7 @@ exports[`InventoryAutoUpload rendering render with props 1`] = `
76
78
  <Text
77
79
  component="a"
78
80
  href="/foreman_rh_cloud/inventory_upload"
81
+ ouiaId="text-details-link"
79
82
  rel="noopener noreferrer"
80
83
  target="_blank"
81
84
  >
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
3
4
  import InventoryAutoUploadSwitcher from './ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload';
4
5
  import NewHostDetailsTab from './InsightsHostDetailsTab/NewHostDetailsTab';
5
6
  import { InsightsTotalRiskChartWrapper } from './InsightsHostDetailsTab/InsightsTotalRiskChartWrapper';
6
7
  import { isNotRhelHost, vulnerabilityDisabled } from './ForemanRhCloudHelpers';
7
- import CVEsHostDetailsTab from './CVEsHostDetailsTab/CVEsHostDetailsTab';
8
+ import CVEsHostDetailsTabWrapper from './CVEsHostDetailsTab/CVEsHostDetailsTab';
8
9
 
9
10
  const fills = [
10
11
  {
@@ -20,6 +21,7 @@ const fills = [
20
21
  weight: 400,
21
22
  metadata: {
22
23
  hideTab: isNotRhelHost,
24
+ title: __('Insights'),
23
25
  },
24
26
  },
25
27
  {
@@ -30,11 +32,12 @@ const fills = [
30
32
  },
31
33
  {
32
34
  slot: 'host-details-page-tabs',
33
- name: 'CVEs',
34
- component: props => <CVEsHostDetailsTab {...props} />,
35
+ name: 'Vulnerabilities',
36
+ component: props => <CVEsHostDetailsTabWrapper {...props} />,
35
37
  weight: 300,
36
38
  metadata: {
37
39
  hideTab: vulnerabilityDisabled,
40
+ title: __('Vulnerabilities'),
38
41
  },
39
42
  },
40
43
  ];
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import componentRegistry from 'foremanReact/components/componentRegistry';
3
3
  import { registerRoutes as foremanRegisterRoutes } from 'foremanReact/routes/RoutingService';
4
4
  import ForemanInventoryUpload from './ForemanInventoryUpload';
5
- import InsightsVulnerability from './InsightsVulnerability/InsightsVulnerability';
5
+ import InsightsVulnerabilityListPage from './InsightsVulnerability/InsightsVulnerabilityListPage';
6
6
  import InsightsCloudSync from './InsightsCloudSync';
7
7
  import InsightsHostDetailsTab from './InsightsHostDetailsTab';
8
8
 
@@ -10,7 +10,10 @@ const pages = [
10
10
  { name: 'ForemanInventoryUpload', type: ForemanInventoryUpload },
11
11
  { name: 'InsightsCloudSync', type: InsightsCloudSync },
12
12
  { name: 'InsightsHostDetailsTab', type: InsightsHostDetailsTab },
13
- { name: 'InsightsVulnerability', type: InsightsVulnerability },
13
+ {
14
+ name: 'InsightsVulnerabilityListPage',
15
+ type: InsightsVulnerabilityListPage,
16
+ },
14
17
  ];
15
18
 
16
19
  export const registerPages = () => {
@@ -31,7 +34,7 @@ export const routes = [
31
34
  {
32
35
  path: '/foreman_rh_cloud/insights_vulnerability',
33
36
  exact: true,
34
- render: props => <InsightsVulnerability {...props} />,
37
+ render: props => <InsightsVulnerabilityListPage {...props} />,
35
38
  },
36
39
  ];
37
40
 
@@ -75,6 +75,7 @@ const InsightsTable = ({
75
75
  />
76
76
  <Table
77
77
  className="rh-cloud-recommendations-table"
78
+ ouiaId="rh-cloud-recommendations-table"
78
79
  aria-label="Recommendations Table"
79
80
  onSelect={(_event, isSelected, rowId) =>
80
81
  onTableSelect(isSelected, rowId, rows, selectedIds)
@@ -18,6 +18,7 @@ const SelectAllAlert = ({
18
18
  <Alert
19
19
  isInline
20
20
  variant="info"
21
+ ouiaId="alert-recommendations-selected"
21
22
  title={sprintf(__('Recommendations selected: %s.'), selectedCount)}
22
23
  actionLinks={
23
24
  <AlertActionLink onClick={selectAll}>
@@ -32,6 +33,7 @@ const SelectAllAlert = ({
32
33
  <Alert
33
34
  isInline
34
35
  variant="info"
36
+ ouiaId="alert-all-selected"
35
37
  title={__('All recommendations are now selected.')}
36
38
  actionLinks={
37
39
  <AlertActionLink onClick={clearAllSelection}>
@@ -83,6 +83,7 @@ exports[`InsightsTable rendering render with Props 1`] = `
83
83
  isTreeTable={false}
84
84
  onSelect={[Function]}
85
85
  onSort={[Function]}
86
+ ouiaId="rh-cloud-recommendations-table"
86
87
  ouiaSafe={true}
87
88
  role="grid"
88
89
  rowLabeledBy="simple-node"
@@ -46,6 +46,7 @@ const RemediationModal = ({
46
46
  return (
47
47
  <React.Fragment>
48
48
  <Button
49
+ ouiaId="button-remediate"
49
50
  variant="primary"
50
51
  isDisabled={isEmpty(selectedIds)}
51
52
  onClick={() => {
@@ -56,6 +57,7 @@ const RemediationModal = ({
56
57
  </Button>{' '}
57
58
  <Modal
58
59
  id="remediation-modal"
60
+ ouiaId="remediation-modal"
59
61
  appendTo={document.body}
60
62
  variant={ModalVariant.large}
61
63
  title={__('Remediation summary')}
@@ -71,6 +73,7 @@ const RemediationModal = ({
71
73
  >
72
74
  <Table
73
75
  className="remediations-table"
76
+ ouiaId="remediations-table"
74
77
  aria-label="remediations Table"
75
78
  cells={columns}
76
79
  rows={rows}
@@ -9,10 +9,20 @@ const ModalFooter = ({ toggleModal, resolutions, hostsIds }) => {
9
9
  token = token?.content || '';
10
10
  return (
11
11
  <form action={JOB_INVOCATION_PATH} method="post">
12
- <Button type="submit" key="confirm" variant="primary">
12
+ <Button
13
+ type="submit"
14
+ ouiaId="button-confirm"
15
+ key="confirm"
16
+ variant="primary"
17
+ >
13
18
  {__('Remediate')}
14
19
  </Button>
15
- <Button key="cancel" variant="link" onClick={toggleModal}>
20
+ <Button
21
+ key="cancel"
22
+ ouiaId="button-cancel"
23
+ variant="link"
24
+ onClick={toggleModal}
25
+ >
16
26
  {__('Cancel')}
17
27
  </Button>
18
28
  <input type="hidden" name="feature" value="rh_cloud_remediate_hosts" />
@@ -18,6 +18,7 @@ const Resolutions = ({
18
18
  {resolutions.map(({ id: resolution_id, description }) => (
19
19
  <Radio
20
20
  key={resolution_id}
21
+ ouiaId={`resolution-radio-${resolution_id}`}
21
22
  className="resolution-radio"
22
23
  id={resolution_id}
23
24
  isChecked={resolution_id === checkedID}