diff --git a/opensearch_dashboards.json b/opensearch_dashboards.json index ca2032fa..a7bdd76d 100644 --- a/opensearch_dashboards.json +++ b/opensearch_dashboards.json @@ -6,5 +6,7 @@ "requiredPlugins": ["data"], "optionalPlugins": ["dataSource", "dataSourceManagement"], "server": true, - "ui": true + "ui": true, + "supportedOSDataSourceVersions": ">=2.16.0", + "requiredOSDataSourcePlugins": ["opensearch_security_analytics"] } diff --git a/public/components/MDS/DataSourceMenuWrapper.tsx b/public/components/MDS/DataSourceMenuWrapper.tsx index 533900d8..7589c127 100644 --- a/public/components/MDS/DataSourceMenuWrapper.tsx +++ b/public/components/MDS/DataSourceMenuWrapper.tsx @@ -10,9 +10,10 @@ import { DataSourceSelectableConfig, DataSourceViewConfig, } from '../../../../../src/plugins/data_source_management/public'; -import { AppMountParameters, CoreStart } from 'opensearch-dashboards/public'; +import { AppMountParameters, CoreStart, SavedObject } from 'opensearch-dashboards/public'; import { ROUTES } from '../../utils/constants'; import { DataSourceContext } from '../../services/DataSourceContext'; +import { DataSourceAttributes } from 'src/plugins/data_source/common/data_sources'; export interface DataSourceMenuWrapperProps { core: CoreStart; @@ -20,6 +21,7 @@ export interface DataSourceMenuWrapperProps { dataSourceMenuReadOnly: boolean; dataSourceLoading: boolean; setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; + dataSourceFilterFn: (dataSource: SavedObject) => boolean; } export const DataSourceMenuWrapper: React.FC = ({ @@ -28,6 +30,7 @@ export const DataSourceMenuWrapper: React.FC = ({ dataSourceMenuReadOnly, dataSourceLoading, setHeaderActionMenu, + dataSourceFilterFn, }) => { if (!dataSourceManagement) { return null; @@ -64,6 +67,7 @@ export const DataSourceMenuWrapper: React.FC = ({ componentConfig={{ fullWidth: false, activeOption: [dataSource], + dataSourceFilter: dataSourceFilterFn, }} componentType="DataSourceView" setMenuMountPoint={setHeaderActionMenu} @@ -79,6 +83,7 @@ export const DataSourceMenuWrapper: React.FC = ({ componentConfig={{ fullWidth: false, activeOption: [dataSource], + dataSourceFilter: dataSourceFilterFn, }} componentType="DataSourceView" setMenuMountPoint={setHeaderActionMenu} @@ -93,6 +98,7 @@ export const DataSourceMenuWrapper: React.FC = ({ notifications: core.notifications, onSelectedDataSources: setDataSource, savedObjects: core.savedObjects.client, + dataSourceFilter: dataSourceFilterFn, }} /> ); @@ -126,6 +132,7 @@ export const DataSourceMenuWrapper: React.FC = ({ notifications: core.notifications, onSelectedDataSources: setDataSource, savedObjects: core.savedObjects.client, + dataSourceFilter: dataSourceFilterFn, }} /> ); diff --git a/public/pages/Main/Main.tsx b/public/pages/Main/Main.tsx index a9e2642c..2f0bef35 100644 --- a/public/pages/Main/Main.tsx +++ b/public/pages/Main/Main.tsx @@ -18,7 +18,7 @@ import { EuiFlexItem, } from '@elastic/eui'; import { Toast } from '@opensearch-project/oui/src/eui_components/toast/global_toast_list'; -import { AppMountParameters, CoreStart } from 'opensearch-dashboards/public'; +import { AppMountParameters, CoreStart, SavedObject } from 'opensearch-dashboards/public'; import { SaContextConsumer } from '../../services'; import { DEFAULT_DATE_RANGE, DATE_TIME_FILTER_KEY, ROUTES } from '../../utils/constants'; import { CoreServicesConsumer } from '../../components/core_services'; @@ -61,6 +61,9 @@ import { ThreatIntelOverview } from '../ThreatIntel/containers/Overview/ThreatIn import { AddThreatIntelSource } from '../ThreatIntel/containers/AddThreatIntelSource/AddThreatIntelSource'; import { ThreatIntelScanConfigForm } from '../ThreatIntel/containers/ScanConfiguration/ThreatIntelScanConfigForm'; import { ThreatIntelSource } from '../ThreatIntel/containers/ThreatIntelSource/ThreatIntelSource'; +import * as pluginManifest from "../../../opensearch_dashboards.json"; +import { DataSourceAttributes } from "../../../../../src/plugins/data_source/common/data_sources"; +import semver from "semver"; enum Navigation { SecurityAnalytics = 'Security Analytics', @@ -373,6 +376,15 @@ export default class Main extends Component { ]; }; + dataSourceFilterFn = (dataSource: SavedObject) => { + const dataSourceVersion = dataSource?.attributes?.dataSourceVersion || ""; + const installedPlugins = dataSource?.attributes?.installedPlugins || []; + return ( + semver.satisfies(dataSourceVersion, pluginManifest.supportedOSDataSourceVersions) && + pluginManifest.requiredOSDataSourcePlugins.every((plugin) => installedPlugins.includes(plugin)) + ); + }; + render() { const { landingPage, @@ -419,6 +431,7 @@ export default class Main extends Component { dataSourceLoading={this.state.dataSourceLoading} dataSourceMenuReadOnly={dataSourceMenuReadOnly} setHeaderActionMenu={setActionMenu} + dataSourceFilterFn={this.dataSourceFilterFn} /> )} {!dataSourceLoading && services && (