foreman_rh_cloud 12.1.5 → 12.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abf912ff1170fb60a3b10a6d1178f71ad7a92662c2272a883179eb30a62e2c2e
4
- data.tar.gz: 3ff64877a61a50890423e1d25980ea37e9fc3ae949f875be344b299f5580ab24
3
+ metadata.gz: 32fdc4ecba1d5949bce50e394de7cdd097697902c8ba47f47b14e26c96e44881
4
+ data.tar.gz: 0de08119aa42cce06a73dd7bce46d730e023d40b7f54b621cb6a3cef50fb0b63
5
5
  SHA512:
6
- metadata.gz: 5792bc34bf4e7a254cacc14cd014b9e008378d695ddc5ae00afcbd5f10371840a53ecdd106f2a845531a2c174fab3c7d1b931ba0a6f766c749124adcbcff742f
7
- data.tar.gz: dffa948ae7cca41a839be2c07f26193ccc11c9af71d84c07d4b0f256a0ad0e5763ce107cf69a22ecb6436212a5e68d09512a4043eb8eb5b01a2268c88d0d44fd
6
+ metadata.gz: 03ad7ffd1b43db38bdd6762d01b1bd88e7404702a43cd7be626a72892e73f498c990eab3a4cc1037fe63393cdc87d460cd1b87fa7770749e87b9e9a2bf949418
7
+ data.tar.gz: 403935258065a6cc0755b0d71ed9c3fa6a8652c59264c85da213aa21471d93af5efcde6a829f0e1606d949474b41ab6eaa7b9c573b0ecc74393dce786795f01f
data/config/routes.rb CHANGED
@@ -38,8 +38,13 @@ Rails.application.routes.draw do
38
38
  unless ForemanRhCloud.with_local_advisor_engine?
39
39
  get 'inventory_upload', to: '/react#index'
40
40
  end
41
+ if ForemanRhCloud.with_local_advisor_engine?
42
+ get 'recommendations', to: '/react#index'
43
+ get 'recommendations/:rule_id', to: '/react#index'
44
+ end
41
45
  get 'insights_cloud', to: '/react#index' # Uses foreman's react controller
42
46
  get 'insights_vulnerability', to: '/react#index'
47
+ get 'insights_vulnerability/:cve_id', to: '/react#index'
43
48
  end
44
49
 
45
50
  scope :module => :'insights_cloud/api', :path => :redhat_access do
@@ -229,10 +229,15 @@ module ForemanRhCloud
229
229
  Katello::Api::V2::OrganizationsController.before_action(:local_find_taxonomy, only: :download_debug_certificate)
230
230
 
231
231
  Katello::Api::V2::RepositoriesController.include Foreman::Controller::SmartProxyAuth
232
+ # patch the callbacks order for :index, since find_product has to run after the user is already initialized
233
+ Katello::Api::V2::RepositoriesController.skip_before_action(:find_product, only: :index)
234
+ Katello::Api::V2::RepositoriesController.skip_before_action(:find_optional_organization, only: :index)
232
235
  Katello::Api::V2::RepositoriesController.add_smart_proxy_filters(
233
236
  :index,
234
237
  features: ForemanRhCloud.on_prem_smart_proxy_features
235
238
  )
239
+ Katello::Api::V2::RepositoriesController.before_action(:find_product, only: :index)
240
+ Katello::Api::V2::RepositoriesController.before_action(:find_optional_organization, only: :index)
236
241
  end
237
242
  end
238
243
 
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '12.1.5'.freeze
2
+ VERSION = '12.2.0'.freeze
3
3
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "12.1.5",
3
+ "version": "12.2.0",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { useParams } from 'react-router-dom';
3
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
5
+
6
+ const CveDetailsPage = () => {
7
+ const { cveId } = useParams();
8
+ const scope = 'vulnerability';
9
+ const module = './CveDetailPage';
10
+
11
+ return (
12
+ <ScalprumProvider {...providerOptions}>
13
+ <div className="rh-cloud-cve-details-page">
14
+ <ScalprumComponent scope={scope} module={module} cveId={cveId} />
15
+ </div>
16
+ </ScalprumProvider>
17
+ );
18
+ };
19
+
20
+ export default CveDetailsPage;
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import CveDetailsPage from './CveDetailsPage';
5
+
6
+ // Mock react-router-dom
7
+ jest.mock('react-router-dom', () => ({
8
+ useParams: jest.fn(() => ({ cveId: 'CVE-2021-1234' })),
9
+ }));
10
+
11
+ jest.mock('@scalprum/react-core', () => ({
12
+ ScalprumComponent: jest.fn(props => (
13
+ <div data-testid="mock-scalprum-component">{JSON.stringify(props)}</div>
14
+ )),
15
+ ScalprumProvider: jest.fn(({ children }) => <div>{children}</div>),
16
+ }));
17
+
18
+ describe('CveDetailsPage component', () => {
19
+ it('renders the container with correct class', () => {
20
+ const { container } = render(<CveDetailsPage />);
21
+ expect(
22
+ container.querySelector('.rh-cloud-cve-details-page')
23
+ ).toBeTruthy();
24
+ });
25
+
26
+ it('passes cveId from URL params to ScalprumComponent', () => {
27
+ const { getByTestId } = render(<CveDetailsPage />);
28
+ const mockComponent = getByTestId('mock-scalprum-component');
29
+ expect(mockComponent.textContent).toContain('CVE-2021-1234');
30
+ });
31
+ });
@@ -0,0 +1 @@
1
+ export { default } from './CveDetailsPage';
@@ -1,20 +1,15 @@
1
1
  import React from 'react';
2
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
2
3
  import { translate as __ } from 'foremanReact/common/I18n';
3
4
  import { propsToCamelCase } from 'foremanReact/common/helpers';
4
5
  import { CVECountCell } from '../InsightsVulnerabilityHostIndexExtensions/CVECountCell';
6
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
5
7
 
6
- const RecommendationsCell = hostDetails => {
8
+ const HostedRecommendationsCell = hostDetails => {
7
9
  const insightsAttributes = propsToCamelCase(
8
10
  // eslint-disable-next-line camelcase
9
11
  hostDetails?.insights_attributes ?? {}
10
12
  );
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
13
  const { insightsHitsCount: hitsCount } = insightsAttributes;
19
14
  if (hitsCount === undefined || hitsCount === null) return '—';
20
15
  const hostname = hostDetails?.name;
@@ -23,6 +18,36 @@ const RecommendationsCell = hostDetails => {
23
18
  return <a href={hitsUrl}>{hitsCount}</a>;
24
19
  };
25
20
 
21
+ const IopRecommendationsCell = hostDetails => {
22
+ const scope = 'advisor';
23
+ const module = './RecommendationsCellWrapped';
24
+
25
+ return (
26
+ <span className="rh-cloud-insights-recommendations-cell">
27
+ <ScalprumComponent scope={scope} module={module} />
28
+ </span>
29
+ );
30
+ };
31
+
32
+ const IopRecommendationsCellWrapped = hostDetails => (
33
+ <ScalprumProvider {...providerOptions}>
34
+ <IopRecommendationsCell hostDetails={hostDetails} />
35
+ </ScalprumProvider>
36
+ );
37
+
38
+ const RecommendationsCell = hostDetails => {
39
+ const insightsAttributes = propsToCamelCase(
40
+ // eslint-disable-next-line camelcase
41
+ hostDetails?.insights_attributes ?? {}
42
+ );
43
+
44
+ return insightsAttributes.useLocalAdvisorEngine ? (
45
+ <IopRecommendationsCellWrapped hostDetails={hostDetails} />
46
+ ) : (
47
+ <HostedRecommendationsCell hostDetails={hostDetails} />
48
+ );
49
+ };
50
+
26
51
  const insightsCategoryName = __('Insights');
27
52
 
28
53
  const hostsIndexColumnExtensions = [
@@ -1,19 +1,24 @@
1
+ /* eslint-disable spellcheck/spell-checker */
1
2
  import React from 'react';
2
3
  import componentRegistry from 'foremanReact/components/componentRegistry';
3
4
  import { registerRoutes as foremanRegisterRoutes } from 'foremanReact/routes/RoutingService';
4
5
  import ForemanInventoryUpload from './ForemanInventoryUpload';
5
6
  import InsightsVulnerabilityListPage from './InsightsVulnerability/InsightsVulnerabilityListPage';
6
7
  import InsightsCloudSync from './InsightsCloudSync';
8
+ import IopRecommendationDetails from './IopRecommendationDetails/IopRecommendationDetails';
7
9
  import InsightsHostDetailsTab from './InsightsHostDetailsTab';
10
+ import CveDetailsPage from './CveDetailsPage';
8
11
 
9
12
  const pages = [
10
13
  { name: 'ForemanInventoryUpload', type: ForemanInventoryUpload },
11
14
  { name: 'InsightsCloudSync', type: InsightsCloudSync },
15
+ { name: 'IopRecommendationDetails', type: IopRecommendationDetails },
12
16
  { name: 'InsightsHostDetailsTab', type: InsightsHostDetailsTab },
13
17
  {
14
18
  name: 'InsightsVulnerabilityListPage',
15
19
  type: InsightsVulnerabilityListPage,
16
20
  },
21
+ { name: 'CveDetailsPage', type: CveDetailsPage },
17
22
  ];
18
23
 
19
24
  export const registerPages = () => {
@@ -26,6 +31,11 @@ export const routes = [
26
31
  exact: true,
27
32
  render: props => <InsightsCloudSync {...props} />,
28
33
  },
34
+ {
35
+ path: '/foreman_rh_cloud/recommendations',
36
+ exact: false,
37
+ render: props => <IopRecommendationDetails {...props} />,
38
+ },
29
39
  {
30
40
  path: '/foreman_rh_cloud/inventory_upload',
31
41
  exact: true,
@@ -36,6 +46,11 @@ export const routes = [
36
46
  exact: true,
37
47
  render: props => <InsightsVulnerabilityListPage {...props} />,
38
48
  },
49
+ {
50
+ path: '/foreman_rh_cloud/insights_vulnerability/:cveId',
51
+ exact: true,
52
+ render: props => <CveDetailsPage {...props} />,
53
+ },
39
54
  ];
40
55
 
41
56
  export const registerRoutes = () => {
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
4
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
5
  import InsightsTable from './Components/InsightsTable';
6
+ import { useAdvisorEngineConfig } from '../common/Hooks/ConfigHooks';
7
+ import { foremanUrl } from '../ForemanRhCloudHelpers';
5
8
  import RemediationModal from './Components/RemediationModal';
6
9
  import {
7
10
  INSIGHTS_SYNC_PAGE_TITLE,
@@ -11,7 +14,9 @@ import './InsightsCloudSync.scss';
11
14
  import Pagination from './Components/InsightsTable/Pagination';
12
15
  import ToolbarDropdown from './Components/ToolbarDropdown';
13
16
  import InsightsSettings from './Components/InsightsSettings';
17
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
14
18
 
19
+ // Hosted Insights advisor
15
20
  const InsightsCloudSync = ({ syncInsights, query, fetchInsights }) => {
16
21
  const onRecommendationSync = () => syncInsights(fetchInsights, query);
17
22
  const toolbarButtons = (
@@ -54,4 +59,37 @@ InsightsCloudSync.defaultProps = {
54
59
  query: '',
55
60
  };
56
61
 
57
- export default InsightsCloudSync;
62
+ // Local Insights advisor
63
+ const scope = 'advisor';
64
+ const module = './ListWrapped';
65
+
66
+ export const generateRuleUrl = ruleId =>
67
+ foremanUrl(`/foreman_rh_cloud/recommendations/${ruleId}`);
68
+
69
+ const IopRecommendationsPage = props => (
70
+ <ScalprumComponent
71
+ scope={scope}
72
+ module={module}
73
+ IopRemediationModal={RemediationModal}
74
+ generateRuleUrl={generateRuleUrl}
75
+ {...props}
76
+ />
77
+ );
78
+
79
+ const IopRecommendationsPageWrapped = props => (
80
+ <ScalprumProvider {...providerOptions}>
81
+ <IopRecommendationsPage {...props} />
82
+ </ScalprumProvider>
83
+ );
84
+
85
+ const RecommendationsPage = props => {
86
+ const isLocalAdvisorEngine = useAdvisorEngineConfig();
87
+
88
+ return isLocalAdvisorEngine ? (
89
+ <IopRecommendationsPageWrapped {...props} />
90
+ ) : (
91
+ <InsightsCloudSync {...props} />
92
+ );
93
+ };
94
+
95
+ export default RecommendationsPage;
@@ -1,54 +1,10 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`InsightsCloudSync render 1`] = `
4
- <div
5
- className="rh-cloud-insights"
6
- >
7
- <Connect(InsightsSettings) />
8
- <PageLayout
9
- beforeToolbarComponent={null}
10
- header="Red Hat Insights"
11
- onSearch={[Function]}
12
- searchProps={
13
- Object {
14
- "autocomplete": Object {
15
- "id": "searchBar",
16
- "searchQuery": "",
17
- "url": "/insights_cloud/hits/auto_complete_search",
18
- "useKeyShortcuts": true,
19
- },
20
- "bookmarks": Object {
21
- "canCreateBookmarks": true,
22
- "documentationUrl": "4.1.5Searching",
23
- "url": "/api/bookmarks",
24
- },
25
- "controller": "insights_hits",
26
- }
27
- }
28
- searchQuery=""
29
- searchable={true}
30
- toolbarButtons={
31
- <React.Fragment>
32
- <span
33
- className="insights-toolbar-buttons"
34
- >
35
- <Memo(Connect(RemediationModal)) />
36
- <ToolbarDropdown
37
- onRecommendationSync={[Function]}
38
- />
39
- </span>
40
- <span
41
- className="pull-right"
42
- >
43
- <Pagination
44
- isCompact={true}
45
- variant="top"
46
- />
47
- </span>
48
- </React.Fragment>
49
- }
50
- >
51
- <Connect(InsightsTable) />
52
- </PageLayout>
53
- </div>
4
+ <InsightsCloudSync
5
+ fetchInsights={[Function]}
6
+ query=""
7
+ status="RESOLVED"
8
+ syncInsights={[Function]}
9
+ />
54
10
  `;
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
4
  import SearchBar from 'foremanReact/components/SearchBar';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
6
7
  import { Grid, GridItem } from '@patternfly/react-core';
7
8
  import {
8
9
  Dropdown,
@@ -21,7 +22,10 @@ import {
21
22
  } from '../InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors';
22
23
  import { redHatAdvisorSystems } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
23
24
  import { useAdvisorEngineConfig } from '../common/Hooks/ConfigHooks';
25
+ import { generateRuleUrl } from '../InsightsCloudSync/InsightsCloudSync';
26
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
24
27
 
28
+ // Hosted Insights advisor
25
29
  const NewHostDetailsTab = ({ hostName, router }) => {
26
30
  const dispatch = useDispatch();
27
31
  const query = useSelector(selectSearch);
@@ -104,4 +108,50 @@ NewHostDetailsTab.defaultProps = {
104
108
  router: {},
105
109
  };
106
110
 
107
- export default NewHostDetailsTab;
111
+ // Local Insights advisor
112
+ const scope = 'advisor';
113
+ // eslint-disable-next-line spellcheck/spell-checker
114
+ const module = './HostDetailsLightspeedTabWrapped';
115
+
116
+ const IopInsightsTab = props => (
117
+ <ScalprumComponent
118
+ scope={scope}
119
+ module={module}
120
+ IopRemediationModal={RemediationModal}
121
+ generateRuleUrl={generateRuleUrl}
122
+ {...props}
123
+ />
124
+ );
125
+
126
+ const IopInsightsTabWrapped = props => (
127
+ <ScalprumProvider {...providerOptions}>
128
+ <IopInsightsTab {...props} />
129
+ </ScalprumProvider>
130
+ );
131
+
132
+ const LightspeedTab = props => {
133
+ const { response } = props;
134
+ const isLocalAdvisorEngine =
135
+ // eslint-disable-next-line camelcase
136
+ response?.insights_attributes?.use_local_advisor_engine;
137
+
138
+ return isLocalAdvisorEngine ? (
139
+ <IopInsightsTabWrapped {...props} />
140
+ ) : (
141
+ <NewHostDetailsTab {...props} />
142
+ );
143
+ };
144
+
145
+ LightspeedTab.propTypes = {
146
+ response: PropTypes.shape({
147
+ insights_attributes: {
148
+ use_local_advisor_engine: PropTypes.bool,
149
+ },
150
+ }),
151
+ };
152
+
153
+ LightspeedTab.defaultProps = {
154
+ response: {},
155
+ };
156
+
157
+ export default LightspeedTab;
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { useRouteMatch } from 'react-router-dom';
3
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
+
5
+ import RemediationModal from '../InsightsCloudSync/Components/RemediationModal';
6
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
7
+
8
+ const scope = 'advisor';
9
+ const module = './RecommendationDetailsWrapped';
10
+
11
+ const invScope = 'inventory';
12
+ const invModule = './HybridInventoryTabs';
13
+
14
+ const IopRecommendationDetails = props => {
15
+ const urlParams = useRouteMatch('/foreman_rh_cloud/recommendations/:rule_id');
16
+ // eslint-disable-next-line camelcase
17
+ const ruleId = urlParams?.params?.rule_id;
18
+ return (
19
+ <div className="rh-cloud-recommendation-details-cell">
20
+ <ScalprumComponent
21
+ scope={scope}
22
+ module={module}
23
+ IopRemediationModal={RemediationModal}
24
+ ruleId={ruleId}
25
+ {...props}
26
+ />
27
+ <ScalprumComponent
28
+ scope={invScope}
29
+ module={invModule}
30
+ IopRemediationModal={RemediationModal}
31
+ ruleId={ruleId}
32
+ {...props}
33
+ />
34
+ </div>
35
+ );
36
+ };
37
+
38
+ const IopRecommendationDetailsWrapped = props => (
39
+ <ScalprumProvider {...providerOptions}>
40
+ <IopRecommendationDetails {...props} />
41
+ </ScalprumProvider>
42
+ );
43
+
44
+ export default IopRecommendationDetailsWrapped;
@@ -4,6 +4,16 @@ export const modulesConfig = {
4
4
  manifestLocation: `${window.location.origin}/assets/apps/vulnerability/fed-mods.json`,
5
5
  cdnPath: `${window.location.origin}/assets/apps/vulnerability/`,
6
6
  },
7
+ advisor: {
8
+ name: 'advisor',
9
+ manifestLocation: `${window.location.origin}/assets/apps/advisor/fed-mods.json`,
10
+ cdnPath: `${window.location.origin}/assets/apps/advisor/`,
11
+ },
12
+ inventory: {
13
+ name: 'inventory',
14
+ manifestLocation: `${window.location.origin}/assets/apps/inventory/fed-mods.json`,
15
+ cdnPath: `${window.location.origin}/assets/apps/inventory/`,
16
+ },
7
17
  };
8
18
 
9
19
  export const mockUser = {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.5
4
+ version: 12.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
@@ -292,6 +292,9 @@ files:
292
292
  - webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js
293
293
  - webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js
294
294
  - webpack/CVEsHostDetailsTab/index.js
295
+ - webpack/CveDetailsPage/CveDetailsPage.js
296
+ - webpack/CveDetailsPage/CveDetailsPage.test.js
297
+ - webpack/CveDetailsPage/index.js
295
298
  - webpack/ForemanColumnExtensions/index.js
296
299
  - webpack/ForemanInventoryUpload/Components/AccountList/AccountList.fixtures.js
297
300
  - webpack/ForemanInventoryUpload/Components/AccountList/AccountList.js
@@ -621,6 +624,7 @@ files:
621
624
  - webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js
622
625
  - webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js
623
626
  - webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js
627
+ - webpack/IopRecommendationDetails/IopRecommendationDetails.js
624
628
  - webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js
625
629
  - webpack/__mocks__/foremanReact/common/I18n.js
626
630
  - webpack/__mocks__/foremanReact/common/MountingService.js