diff --git a/app/controllers/api/v2/rh_cloud/advisor_engine_config_controller.rb b/app/controllers/api/v2/rh_cloud/advisor_engine_config_controller.rb new file mode 100644 index 000000000..002652b1b --- /dev/null +++ b/app/controllers/api/v2/rh_cloud/advisor_engine_config_controller.rb @@ -0,0 +1,16 @@ +module Api + module V2 + module RhCloud + class AdvisorEngineConfigController < ::Api::V2::BaseController + include ::Api::Version2 + + api :GET, "/rh_cloud/advisor_engine_config", N_("Show if system is configured to use local iop-advisor-engine.") + def show + render json: { + use_local_advisor_engine: ForemanRhCloud.with_local_advisor_engine?, + }, status: :ok + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index d495c95fc..82dc5d907 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,8 +62,8 @@ namespace 'rh_cloud' do post 'enable_connector', to: 'inventory#enable_cloud_connector' - post 'cloud_request', to: 'cloud_request#update' + get 'advisor_engine_config', to: 'advisor_engine_config#show' end namespace 'advisor_engine' do diff --git a/lib/foreman_rh_cloud/engine.rb b/lib/foreman_rh_cloud/engine.rb index a4ae25d71..f0707c8c5 100644 --- a/lib/foreman_rh_cloud/engine.rb +++ b/lib/foreman_rh_cloud/engine.rb @@ -74,6 +74,7 @@ def self.register_scheduled_task(task_class, cronline) 'foreman_inventory_upload/cloud_status': [:index], 'foreman_inventory_upload/uploads_settings': [:index], 'foreman_inventory_upload/missing_hosts': [:index], + 'api/v2/rh_cloud/advisor_engine_config': [:show], 'react': [:index] ) permission( @@ -107,7 +108,13 @@ def self.register_scheduled_task(task_class, cronline) # Adding a sub menu after hosts menu divider :top_menu, caption: N_('Insights'), parent: :configure_menu - menu :top_menu, :inventory_upload, caption: N_('Inventory Upload'), url: '/foreman_rh_cloud/inventory_upload', url_hash: { controller: :react, action: :index }, parent: :configure_menu + menu :top_menu, + :inventory_upload, + caption: N_('Inventory Upload'), + url: '/foreman_rh_cloud/inventory_upload', + url_hash: { controller: :react, action: :index }, + parent: :configure_menu, + if: -> { !ForemanRhCloud.with_local_advisor_engine? } menu :top_menu, :insights_hits, caption: N_('Recommendations'), url: '/foreman_rh_cloud/insights_cloud', url_hash: { controller: :react, action: :index }, parent: :configure_menu register_facet InsightsFacet, :insights do @@ -200,4 +207,8 @@ def self.register_scheduled_task(task_class, cronline) end end end + + def self.with_local_advisor_engine? + SETTINGS.dig(:foreman_rh_cloud, :use_local_advisor_engine) || false + end end diff --git a/test/controllers/insights_sync/settings_controller_test.rb b/test/controllers/insights_sync/settings_controller_test.rb index 23301a8f3..a0e313ef3 100644 --- a/test/controllers/insights_sync/settings_controller_test.rb +++ b/test/controllers/insights_sync/settings_controller_test.rb @@ -2,6 +2,9 @@ class SettingsControllerTest < ActionController::TestCase tests InsightsCloud::SettingsController + def setup + ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(false) + end test 'should return allow_auto_insights_sync setting' do Setting[:allow_auto_insights_sync] = false diff --git a/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss b/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss deleted file mode 100644 index d1974f921..000000000 --- a/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss +++ /dev/null @@ -1,8 +0,0 @@ -.insights-header { - overflow: auto; - margin-bottom: 30px; - - p { - font-size: 16px; - } -} diff --git a/webpack/InsightsCloudSync/Components/InsightsHeader/index.js b/webpack/InsightsCloudSync/Components/InsightsHeader/index.js deleted file mode 100644 index a55f976f8..000000000 --- a/webpack/InsightsCloudSync/Components/InsightsHeader/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { Text, TextVariants } from '@patternfly/react-core'; -import { translate as __ } from 'foremanReact/common/I18n'; -import './InsightsHeader.scss'; - -const InsightsHeader = () => ( -
- - {__( - 'Insights synchronization process is used to provide Insights recommendations output for hosts managed here.' - )} - -
-); - -export default InsightsHeader; diff --git a/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js b/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js index bd8cb733b..eba59be83 100644 --- a/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +++ b/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js @@ -1,32 +1,36 @@ -import React, { Component } from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { translate as __ } from 'foremanReact/common/I18n'; import SwitcherPF4 from '../../../common/Switcher/SwitcherPF4'; import './insightsSettings.scss'; +import { useAdvisorEngineConfig } from '../../../common/Hooks/ConfigHooks'; -class InsightsSettings extends Component { - componentDidMount() { - const { getInsightsSyncSettings } = this.props; +const InsightsSettings = ({ + insightsSyncEnabled, + getInsightsSyncSettings, + setInsightsSyncEnabled, +}) => { + const isLocalAdvisorEngine = useAdvisorEngineConfig(); + useEffect(() => { getInsightsSyncSettings(); - } + }, [getInsightsSyncSettings]); - render() { - const { insightsSyncEnabled, setInsightsSyncEnabled } = this.props; - return ( -
- setInsightsSyncEnabled(!insightsSyncEnabled)} - /> -
- ); - } -} + if (isLocalAdvisorEngine) return null; + + return ( +
+ setInsightsSyncEnabled(!insightsSyncEnabled)} + /> +
+ ); +}; InsightsSettings.propTypes = { insightsSyncEnabled: PropTypes.bool.isRequired, diff --git a/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js b/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js index 4e7f3d805..83bed5577 100644 --- a/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js +++ b/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js @@ -19,7 +19,8 @@ export const getInsightsSyncSettings = () => async dispatch => { }, }, }); - } catch ({ message }) { + } catch (err) { + const { message } = err; dispatch( addToast({ sticky: true, diff --git a/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettings.test.js b/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettings.test.js deleted file mode 100644 index f504a0da2..000000000 --- a/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettings.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { testComponentSnapshotsWithFixtures } from '@theforeman/test'; -import { noop } from 'foremanReact/common/helpers'; - -import InsightsSettings from '../InsightsSettings'; - -const fixtures = { - 'render without Props': { - insightsSyncEnabled: false, - getInsightsSyncSettings: noop, - setInsightsSyncEnabled: noop, - }, - /** fixtures, props for the component */ -}; - -describe('InsightsSettings', () => { - describe('rendering', () => - testComponentSnapshotsWithFixtures(InsightsSettings, fixtures)); -}); diff --git a/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap b/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap deleted file mode 100644 index 4b4441f57..000000000 --- a/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`InsightsSettings rendering render without Props 1`] = ` -
- -
-`; diff --git a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js index ed0d83f15..625524ee3 100644 --- a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +++ b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js @@ -12,6 +12,7 @@ import TableEmptyState from '../../../common/table/EmptyState'; import { modifySelectedRows, getSortColumnIndex } from './InsightsTableHelpers'; import Pagination from './Pagination'; import './table.scss'; +import { useAdvisorEngineConfig } from '../../../common/Hooks/ConfigHooks'; const InsightsTable = ({ page, @@ -43,9 +44,17 @@ const InsightsTable = ({ fetchInsights({ page, perPage, query, sortBy, sortOrder }); }, [hostname]); + const isLocalAdvisorEngine = useAdvisorEngineConfig(); + useEffect(() => { setRows( - modifySelectedRows(hits, selectedIds, showSelectAllAlert, hideHost) + modifySelectedRows( + hits, + selectedIds, + showSelectAllAlert, + hideHost, + isLocalAdvisorEngine + ) ); if (hideHost) setColumns(getColumnsWithoutHostname()); diff --git a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js index 946462bb8..001bbe172 100644 --- a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +++ b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js @@ -31,10 +31,11 @@ export const hasPlaybookFormatter = ({ title: hasPlaybook }) => ({ }); export const actionsFormatter = (props, { rowData = {} }) => { - const { recommendationUrl, accessRHUrl } = rowData; + const { recommendationUrl, accessRHUrl, isLocalAdvisorEngine } = rowData; const dropdownItems = []; recommendationUrl && + !isLocalAdvisorEngine && dropdownItems.push( @@ -121,4 +122,10 @@ export const INSIGHTS_SET_SELECT_ALL_ALERT = 'INSIGHTS_SET_SELECT_ALL_ALERT'; export const INSIGHTS_SET_SELECT_ALL = 'INSIGHTS_SET_SELECT_ALL'; +export const ADVISOR_ENGINE_CONFIG_KEY = 'ADVISOR_ENGINE_CONFIG'; + +export const ADVISOR_ENGINE_CONFIG_PATH = foremanUrl( + '/api/v2/rh_cloud/advisor_engine_config' +); + export const NEW_HOST_PATH = '/new/hosts/'; diff --git a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js index 14e4dc83b..624e71a76 100644 --- a/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +++ b/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js @@ -6,7 +6,8 @@ export const modifySelectedRows = ( hits, selectedIds, showSelectAllAlert, - hideHost + hideHost, + isLocalAdvisorEngine ) => { if (hits.length === 0) return []; @@ -34,6 +35,7 @@ export const modifySelectedRows = ( selected: selectedIds[id] || (disableCheckbox && showSelectAllAlert), recommendationUrl: results_url, accessRHUrl: solution_url, + isLocalAdvisorEngine, }; } ); diff --git a/webpack/InsightsCloudSync/Components/ToolbarDropdown.js b/webpack/InsightsCloudSync/Components/ToolbarDropdown.js index f6c82ad58..f4e029b50 100644 --- a/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +++ b/webpack/InsightsCloudSync/Components/ToolbarDropdown.js @@ -4,9 +4,14 @@ import { translate as __ } from 'foremanReact/common/I18n'; import { Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core'; import { ExternalLinkAltIcon } from '@patternfly/react-icons'; import { redHatAdvisorSystems } from '../InsightsCloudSyncHelpers'; +import { useAdvisorEngineConfig } from '../../common/Hooks/ConfigHooks'; const ToolbarDropdown = ({ onRecommendationSync }) => { const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const isLocalAdvisorEngine = useAdvisorEngineConfig(); + if (isLocalAdvisorEngine) { + return null; + } const dropdownItems = [ - testComponentSnapshotsWithFixtures(InsightsHeader, fixtures)); diff --git a/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap b/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap deleted file mode 100644 index b0a6fa57b..000000000 --- a/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`InsightsHeader render 1`] = ` -
- - Insights synchronization process is used to provide Insights recommendations output for hosts managed here. - -
-`; diff --git a/webpack/InsightsCloudSync/InsightsCloudSync.js b/webpack/InsightsCloudSync/InsightsCloudSync.js index e031d128c..1ce43b7e4 100644 --- a/webpack/InsightsCloudSync/InsightsCloudSync.js +++ b/webpack/InsightsCloudSync/InsightsCloudSync.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout'; -import InsightsHeader from './Components/InsightsHeader'; import InsightsTable from './Components/InsightsTable'; import RemediationModal from './Components/RemediationModal'; import { @@ -37,7 +36,7 @@ const InsightsCloudSync = ({ syncInsights, query, fetchInsights }) => { header={INSIGHTS_SYNC_PAGE_TITLE} toolbarButtons={toolbarButtons} searchQuery={query} - beforeToolbarComponent={} + beforeToolbarComponent={null} > diff --git a/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap b/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap index 531bf5295..33fd3ecb8 100644 --- a/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +++ b/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap @@ -6,7 +6,7 @@ exports[`InsightsCloudSync render 1`] = ` > } + beforeToolbarComponent={null} header="Red Hat Insights" onSearch={[Function]} searchProps={ diff --git a/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js b/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js index 689197262..68921471f 100644 --- a/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +++ b/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js @@ -21,11 +21,13 @@ import { selectHits, } from '../InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors'; import { redHatAdvisorSystems } from '../InsightsCloudSync/InsightsCloudSyncHelpers'; +import { useAdvisorEngineConfig } from '../common/Hooks/ConfigHooks'; const NewHostDetailsTab = ({ hostName, router }) => { const dispatch = useDispatch(); const query = useSelector(selectSearch); const hits = useSelector(selectHits); + const isLocalAdvisorEngine = useAdvisorEngineConfig(); useEffect(() => () => router.replace({ search: null }), [router]); @@ -41,7 +43,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
, ]; - if (hits.length) { + if (hits.length && !isLocalAdvisorEngine) { const { host_uuid: uuid } = hits[0]; dropdownItems.push( diff --git a/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js b/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js new file mode 100644 index 000000000..b93501d6e --- /dev/null +++ b/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js @@ -0,0 +1,3 @@ +export const useAPI = jest.fn(() => ({ + response: {}, +})); diff --git a/webpack/common/Hooks/ConfigHooks.js b/webpack/common/Hooks/ConfigHooks.js new file mode 100644 index 000000000..bc32360dc --- /dev/null +++ b/webpack/common/Hooks/ConfigHooks.js @@ -0,0 +1,19 @@ +import { useAPI } from 'foremanReact/common/hooks/API/APIHooks'; +import { + ADVISOR_ENGINE_CONFIG_KEY, + ADVISOR_ENGINE_CONFIG_PATH, +} from '../../InsightsCloudSync/Components/InsightsTable/InsightsTableConstants'; + +export const useAdvisorEngineConfig = () => { + const { response: advisorEngineConfig } = useAPI( + 'get', + ADVISOR_ENGINE_CONFIG_PATH, + { + key: ADVISOR_ENGINE_CONFIG_KEY, + } + ); + + // eslint-disable-next-line camelcase + const isLocalAdvisorEngine = advisorEngineConfig?.use_local_advisor_engine; + return isLocalAdvisorEngine; +};