@@ -240,16 +245,17 @@ function EditorUI({ initialTextValue, dataSourceId }: EditorProps) {
diff --git a/src/plugins/data/server/search/opensearch_search/decide_client.ts b/src/plugins/data/server/search/opensearch_search/decide_client.ts
index 9e0306d1926..2ff2339add4 100644
--- a/src/plugins/data/server/search/opensearch_search/decide_client.ts
+++ b/src/plugins/data/server/search/opensearch_search/decide_client.ts
@@ -9,14 +9,14 @@ import { IOpenSearchSearchRequest } from '..';
export const decideClient = async (
context: RequestHandlerContext,
request: IOpenSearchSearchRequest,
- withDataSourceEnabled: boolean = false,
withLongNumeralsSupport: boolean = false
): Promise => {
- const defaultOpenSearchClient = withLongNumeralsSupport
- ? context.core.opensearch.client.asCurrentUserWithLongNumeralsSupport
- : context.core.opensearch.client.asCurrentUser;
-
- return withDataSourceEnabled && request.dataSourceId && context.dataSource
- ? await context.dataSource.opensearch.getClient(request.dataSourceId)
- : defaultOpenSearchClient;
+ // if data source feature is disabled, return default opensearch client of current user
+ const client =
+ request.dataSourceId && context.dataSource
+ ? await context.dataSource.opensearch.getClient(request.dataSourceId)
+ : withLongNumeralsSupport
+ ? context.core.opensearch.client.asCurrentUserWithLongNumeralsSupport
+ : context.core.opensearch.client.asCurrentUser;
+ return client;
};
diff --git a/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.test.ts b/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.test.ts
index 6bd4eea5d17..39c367a04a4 100644
--- a/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.test.ts
+++ b/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.test.ts
@@ -33,20 +33,11 @@ import { pluginInitializerContextConfigMock } from '../../../../../core/server/m
import { opensearchSearchStrategyProvider } from './opensearch_search_strategy';
import { DataSourceError } from '../../../../data_source/server/lib/error';
import { DataSourcePluginSetup } from '../../../../data_source/server';
-import { SearchUsage } from '../collectors';
describe('OpenSearch search strategy', () => {
const mockLogger: any = {
debug: () => {},
};
- const mockSearchUsage: SearchUsage = {
- trackError(): Promise {
- return Promise.resolve(undefined);
- },
- trackSuccess(duration: number): Promise {
- return Promise.resolve(undefined);
- },
- };
const body = {
body: {
_shards: {
@@ -140,21 +131,8 @@ describe('OpenSearch search strategy', () => {
expect(response).toHaveProperty('rawResponse');
});
- it('dataSource enabled and default cluster disabled, send request with dataSourceId get data source client', async () => {
- const mockDataSourcePluginSetupWithDataSourceEnabled: DataSourcePluginSetup = {
- createDataSourceError(err: any): DataSourceError {
- return new DataSourceError({});
- },
- dataSourceEnabled: jest.fn(() => true),
- defaultClusterEnabled: jest.fn(() => false),
- };
-
- const opensearchSearch = await opensearchSearchStrategyProvider(
- mockConfig$,
- mockLogger,
- mockSearchUsage,
- mockDataSourcePluginSetupWithDataSourceEnabled
- );
+ it('dataSource enabled, send request with dataSourceId get data source client', async () => {
+ const opensearchSearch = await opensearchSearchStrategyProvider(mockConfig$, mockLogger);
await opensearchSearch.search(
(mockDataSourceEnabledContext as unknown) as RequestHandlerContext,
@@ -166,35 +144,6 @@ describe('OpenSearch search strategy', () => {
expect(mockOpenSearchApiCaller).not.toBeCalled();
});
- it('dataSource enabled and default cluster disabled, send request with empty dataSourceId should throw exception', async () => {
- const mockDataSourcePluginSetupWithDataSourceEnabled: DataSourcePluginSetup = {
- createDataSourceError(err: any): DataSourceError {
- return new DataSourceError({});
- },
- dataSourceEnabled: jest.fn(() => true),
- defaultClusterEnabled: jest.fn(() => false),
- };
-
- try {
- const opensearchSearch = opensearchSearchStrategyProvider(
- mockConfig$,
- mockLogger,
- mockSearchUsage,
- mockDataSourcePluginSetupWithDataSourceEnabled
- );
-
- await opensearchSearch.search(
- (mockDataSourceEnabledContext as unknown) as RequestHandlerContext,
- {
- dataSourceId: '',
- }
- );
- } catch (e) {
- expect(e).toBeTruthy();
- expect(e).toBeInstanceOf(DataSourceError);
- }
- });
-
it('dataSource disabled, send request with dataSourceId get default client', async () => {
const opensearchSearch = await opensearchSearchStrategyProvider(mockConfig$, mockLogger);
@@ -205,47 +154,8 @@ describe('OpenSearch search strategy', () => {
expect(mockDataSourceApiCaller).not.toBeCalled();
});
- it('dataSource enabled and default cluster enabled, send request with dataSourceId get datasource client', async () => {
- const mockDataSourcePluginSetupWithDataSourceEnabled: DataSourcePluginSetup = {
- createDataSourceError(err: any): DataSourceError {
- return new DataSourceError({});
- },
- dataSourceEnabled: jest.fn(() => true),
- defaultClusterEnabled: jest.fn(() => true),
- };
-
- const opensearchSearch = await opensearchSearchStrategyProvider(
- mockConfig$,
- mockLogger,
- mockSearchUsage,
- mockDataSourcePluginSetupWithDataSourceEnabled
- );
-
- await opensearchSearch.search(
- (mockDataSourceEnabledContext as unknown) as RequestHandlerContext,
- {
- dataSourceId,
- }
- );
- expect(mockDataSourceApiCaller).toBeCalled();
- expect(mockOpenSearchApiCaller).not.toBeCalled();
- });
-
- it('dataSource enabled and default cluster enabled, send request without dataSourceId get default client', async () => {
- const mockDataSourcePluginSetupWithDataSourceEnabled: DataSourcePluginSetup = {
- createDataSourceError(err: any): DataSourceError {
- return new DataSourceError({});
- },
- dataSourceEnabled: jest.fn(() => true),
- defaultClusterEnabled: jest.fn(() => true),
- };
-
- const opensearchSearch = await opensearchSearchStrategyProvider(
- mockConfig$,
- mockLogger,
- mockSearchUsage,
- mockDataSourcePluginSetupWithDataSourceEnabled
- );
+ it('dataSource enabled, send request without dataSourceId get default client', async () => {
+ const opensearchSearch = await opensearchSearchStrategyProvider(mockConfig$, mockLogger);
await opensearchSearch.search((mockContext as unknown) as RequestHandlerContext, {});
expect(mockOpenSearchApiCaller).toBeCalled();
diff --git a/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.ts b/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.ts
index 00507faaf0f..5eb29051779 100644
--- a/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.ts
+++ b/src/plugins/data/server/search/opensearch_search/opensearch_search_strategy.ts
@@ -73,20 +73,7 @@ export const opensearchSearchStrategyProvider = (
});
try {
- if (
- dataSource?.dataSourceEnabled() &&
- !dataSource?.defaultClusterEnabled() &&
- !request.dataSourceId
- ) {
- throw new Error(`Data source id is required when no openseach hosts config provided`);
- }
-
- const client = await decideClient(
- context,
- request,
- dataSource?.dataSourceEnabled(),
- withLongNumeralsSupport
- );
+ const client = await decideClient(context, request, withLongNumeralsSupport);
const promise = shimAbortSignal(client.search(params), options?.abortSignal);
const { body: rawResponse } = (await promise) as ApiResponse>;
@@ -105,7 +92,7 @@ export const opensearchSearchStrategyProvider = (
} catch (e) {
if (usage) usage.trackError();
- if (dataSource?.dataSourceEnabled()) {
+ if (dataSource && request.dataSourceId) {
throw dataSource.createDataSourceError(e);
}
throw e;
diff --git a/src/plugins/data_source/config.ts b/src/plugins/data_source/config.ts
index 1131c500162..d5412d32f0f 100644
--- a/src/plugins/data_source/config.ts
+++ b/src/plugins/data_source/config.ts
@@ -13,7 +13,7 @@ const WRAPPING_KEY_SIZE: number = 32;
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: false }),
- defaultCluster: schema.boolean({ defaultValue: true }),
+ hideLocalCluster: schema.boolean({ defaultValue: false }),
encryption: schema.object({
wrappingKeyName: schema.string({
minLength: KEY_NAME_MIN_LENGTH,
diff --git a/src/plugins/data_source/public/index.ts b/src/plugins/data_source/public/index.ts
index b69e07784ff..56bcd4c8bb1 100644
--- a/src/plugins/data_source/public/index.ts
+++ b/src/plugins/data_source/public/index.ts
@@ -3,12 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
+import { PluginInitializerContext } from 'opensearch-dashboards/public';
import { DataSourcePlugin } from './plugin';
// This exports static code and TypeScript types,
// as well as, OpenSearch Dashboards Platform `plugin()` initializer.
-export function plugin() {
- return new DataSourcePlugin();
+export function plugin(initializerContext: PluginInitializerContext) {
+ return new DataSourcePlugin(initializerContext);
}
export { DataSourcePluginSetup, DataSourcePluginStart } from './types';
diff --git a/src/plugins/data_source/public/plugin.ts b/src/plugins/data_source/public/plugin.ts
index 672db78e15c..65bee912255 100644
--- a/src/plugins/data_source/public/plugin.ts
+++ b/src/plugins/data_source/public/plugin.ts
@@ -3,16 +3,34 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
+import {
+ CoreSetup,
+ CoreStart,
+ Plugin,
+ PluginInitializerContext,
+} from 'opensearch-dashboards/public';
import { DataSourcePluginSetup, DataSourcePluginStart } from './types';
+import { DataSourcePluginConfigType } from '../config';
export class DataSourcePlugin implements Plugin {
+ constructor(
+ private readonly initializerContext: PluginInitializerContext
+ ) {}
+
public setup(core: CoreSetup): DataSourcePluginSetup {
- return {};
+ const config = this.initializerContext.config.get();
+ return {
+ dataSourceEnabled: config.enabled,
+ hideLocalCluster: config.hideLocalCluster,
+ };
}
public start(core: CoreStart): DataSourcePluginStart {
- return {};
+ const config = this.initializerContext.config.get();
+ return {
+ dataSourceEnabled: config.enabled,
+ hideLocalCluster: config.hideLocalCluster,
+ };
}
public stop() {}
diff --git a/src/plugins/data_source/public/types.ts b/src/plugins/data_source/public/types.ts
index 0c57dd1ea1b..030ea5b7709 100644
--- a/src/plugins/data_source/public/types.ts
+++ b/src/plugins/data_source/public/types.ts
@@ -3,8 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface DataSourcePluginSetup {}
+export interface DataSourcePluginSetup {
+ dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
+}
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface DataSourcePluginStart {}
+export interface DataSourcePluginStart {
+ dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
+}
diff --git a/src/plugins/data_source/server/index.ts b/src/plugins/data_source/server/index.ts
index f05b833817d..b88b1beb863 100644
--- a/src/plugins/data_source/server/index.ts
+++ b/src/plugins/data_source/server/index.ts
@@ -8,6 +8,10 @@ import { DataSourcePlugin } from './plugin';
import { configSchema, DataSourcePluginConfigType } from '../config';
export const config: PluginConfigDescriptor = {
+ exposeToBrowser: {
+ enabled: true,
+ hideLocalCluster: true,
+ },
schema: configSchema,
};
diff --git a/src/plugins/data_source/server/plugin.ts b/src/plugins/data_source/server/plugin.ts
index 1a90d22960e..5eaafc29000 100644
--- a/src/plugins/data_source/server/plugin.ts
+++ b/src/plugins/data_source/server/plugin.ts
@@ -134,8 +134,6 @@ export class DataSourcePlugin implements Plugin createDataSourceError(e),
- dataSourceEnabled: () => config.enabled,
- defaultClusterEnabled: () => config.defaultCluster,
registerCredentialProvider,
};
}
diff --git a/src/plugins/data_source/server/types.ts b/src/plugins/data_source/server/types.ts
index b54eb5db0eb..146a28eb8cf 100644
--- a/src/plugins/data_source/server/types.ts
+++ b/src/plugins/data_source/server/types.ts
@@ -76,8 +76,6 @@ declare module 'src/core/server' {
export interface DataSourcePluginSetup {
createDataSourceError: (err: any) => DataSourceError;
- dataSourceEnabled: () => boolean;
- defaultClusterEnabled: () => boolean;
registerCredentialProvider: (method: AuthenticationMethod) => void;
}
diff --git a/src/plugins/data_source_management/public/components/cluster_selector/__snapshots__/cluster_selector.test.tsx.snap b/src/plugins/data_source_management/public/components/cluster_selector/__snapshots__/cluster_selector.test.tsx.snap
index 3012d5c61bc..34c1df89f05 100644
--- a/src/plugins/data_source_management/public/components/cluster_selector/__snapshots__/cluster_selector.test.tsx.snap
+++ b/src/plugins/data_source_management/public/components/cluster_selector/__snapshots__/cluster_selector.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`ClusterSelector should render normally 1`] = `
+exports[`ClusterSelector should render normally with local cluster is hidden 1`] = `
+`;
+
+exports[`ClusterSelector should render normally with local cluster not hidden 1`] = `
+
+`;
+
+exports[`ClusterSelector: check dataSource options should always place local cluster option as the first option when local cluster not hidden 1`] = `
+ {
let component: ShallowWrapper, React.Component<{}, {}, any>>;
@@ -19,18 +20,39 @@ describe('ClusterSelector', () => {
client = {
find: jest.fn().mockResolvedValue([]),
} as any;
+ });
+
+ it('should render normally with local cluster not hidden', () => {
component = shallow(
);
+ expect(component).toMatchSnapshot();
+ expect(client.find).toBeCalledWith({
+ fields: ['id', 'description', 'title'],
+ perPage: 10000,
+ type: 'data-source',
+ });
+ expect(toasts.addWarning).toBeCalledTimes(0);
});
- it('should render normally', () => {
+ it('should render normally with local cluster is hidden', () => {
+ component = shallow(
+
+ );
expect(component).toMatchSnapshot();
expect(client.find).toBeCalledWith({
fields: ['id', 'description', 'title'],
@@ -40,3 +62,36 @@ describe('ClusterSelector', () => {
expect(toasts.addWarning).toBeCalledTimes(0);
});
});
+
+describe('ClusterSelector: check dataSource options', () => {
+ let component: ShallowWrapper, React.Component<{}, {}, any>>;
+ let client: SavedObjectsClientContract;
+ const { toasts } = notificationServiceMock.createStartContract();
+ const nextTick = () => new Promise((res) => process.nextTick(res));
+
+ beforeEach(async () => {
+ client = {
+ find: jest.fn().mockResolvedValue([]),
+ } as any;
+
+ mockResponseForSavedObjectsCalls(client, 'find', getDataSourcesResponse);
+ });
+
+ it('should always place local cluster option as the first option when local cluster not hidden', async () => {
+ component = shallow(
+
+ );
+
+ component.instance().componentDidMount!();
+ await nextTick();
+ expect(component).toMatchSnapshot();
+ expect(toasts.addWarning).toBeCalledTimes(0);
+ });
+});
diff --git a/src/plugins/data_source_management/public/components/cluster_selector/cluster_selector.tsx b/src/plugins/data_source_management/public/components/cluster_selector/cluster_selector.tsx
index c30c7624d51..59f73f1b879 100644
--- a/src/plugins/data_source_management/public/components/cluster_selector/cluster_selector.tsx
+++ b/src/plugins/data_source_management/public/components/cluster_selector/cluster_selector.tsx
@@ -21,6 +21,7 @@ interface ClusterSelectorProps {
notifications: ToastsStart;
onSelectedDataSource: (clusterOption: ClusterOption[]) => void;
disabled: boolean;
+ hideLocalCluster: boolean;
fullWidth: boolean;
}
@@ -41,8 +42,8 @@ export class ClusterSelector extends React.Component(null);
@@ -136,6 +138,7 @@ function DevToolsWrapper({
notifications={toasts}
onSelectedDataSource={onChange}
disabled={!dataSourceEnabled}
+ hideLocalCluster={hideLocalCluster}
fullWidth={false}
/>
@@ -153,7 +156,12 @@ function DevToolsWrapper({
mountedTool.current.devTool !== activeDevTool ||
mountedTool.current.mountpoint !== element)
) {
- await remount(element);
+ let initialDataSourceId;
+ if (!dataSourceEnabled || (dataSourceEnabled && !hideLocalCluster)) {
+ initialDataSourceId = '';
+ }
+
+ await remount(element, initialDataSourceId);
}
}}
/>
@@ -212,6 +220,7 @@ export function renderApp(
{ dataSource }: DevToolsSetupDependencies
) {
const dataSourceEnabled = !!dataSource;
+ const hideLocalCluster = dataSource?.hideLocalCluster ?? false;
if (redirectOnMissingCapabilities(application)) {
return () => {};
}
@@ -241,6 +250,7 @@ export function renderApp(
savedObjects={savedObjects}
notifications={notifications}
dataSourceEnabled={dataSourceEnabled}
+ hideLocalCluster={hideLocalCluster}
/>
)}
/>
diff --git a/src/plugins/home/public/application/components/sample_data_set_card.js b/src/plugins/home/public/application/components/sample_data_set_card.js
index 7d8b97a1c98..086484fa12c 100644
--- a/src/plugins/home/public/application/components/sample_data_set_card.js
+++ b/src/plugins/home/public/application/components/sample_data_set_card.js
@@ -65,6 +65,15 @@ export class SampleDataSetCard extends React.Component {
};
renderBtn = () => {
+ const dataSourceEnabled = this.props.isDataSourceEnabled;
+ const hideLocalCluster = this.props.isLocalClusterHidden;
+ const dataSourceId = this.props.dataSourceId;
+
+ let buttonDisabled = false;
+ if (dataSourceEnabled && hideLocalCluster) {
+ buttonDisabled = dataSourceId === undefined;
+ }
+
switch (this.props.status) {
case INSTALLED_STATUS:
return (
@@ -121,6 +130,7 @@ export class SampleDataSetCard extends React.Component {
);
diff --git a/src/plugins/home/public/application/components/tutorial_directory.js b/src/plugins/home/public/application/components/tutorial_directory.js
index 9f71652bfd8..45da6b07fd9 100644
--- a/src/plugins/home/public/application/components/tutorial_directory.js
+++ b/src/plugins/home/public/application/components/tutorial_directory.js
@@ -83,6 +83,7 @@ class TutorialDirectoryUi extends React.Component {
tutorialCards: [],
notices: getServices().tutorialService.getDirectoryNotices(),
isDataSourceEnabled: !!getServices().dataSource,
+ isLocalClusterHidden: getServices().dataSource?.hideLocalCluster ?? false,
};
}
@@ -185,6 +186,7 @@ class TutorialDirectoryUi extends React.Component {
addBasePath={this.props.addBasePath}
dataSourceId={this.state.selectedDataSourceId}
isDataSourceEnabled={this.state.isDataSourceEnabled}
+ isLocalClusterHidden={this.state.isLocalClusterHidden}
/>
);
}
@@ -224,7 +226,7 @@ class TutorialDirectoryUi extends React.Component {
};
renderDataSourceSelector = () => {
- const { isDataSourceEnabled } = this.state;
+ const { isDataSourceEnabled, isLocalClusterHidden } = this.state;
return isDataSourceEnabled ? (
@@ -233,6 +235,7 @@ class TutorialDirectoryUi extends React.Component {
notifications={getServices().toastNotifications}
onSelectedDataSource={this.onSelectedDataSourceChange}
disabled={!isDataSourceEnabled}
+ hideLocalCluster={isLocalClusterHidden}
/>
) : null;
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/__snapshots__/step_data_source.test.tsx.snap b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/__snapshots__/step_data_source.test.tsx.snap
index ba690127435..4f8ef0404f5 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/__snapshots__/step_data_source.test.tsx.snap
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/__snapshots__/step_data_source.test.tsx.snap
@@ -1,6 +1,44 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`StepDataSource should render normally 1`] = `
+exports[`StepDataSource should render normally with hideLocalCluster false 1`] = `
+
+
+
+
+
+`;
+
+exports[`StepDataSource should render normally with hideLocalCluster true 1`] = `
+
+
+
+
+
+`;
+
+exports[`StepDataSource should render normally with hideLocalCluster undefined 1`] = `
{
goToNextStep={() => {}}
isNextStepDisabled={true}
stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={false}
/>
);
@@ -53,6 +54,7 @@ describe('Header', () => {
goToNextStep={() => {}}
isNextStepDisabled={true}
stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={false}
/>
);
@@ -79,6 +81,7 @@ describe('Header', () => {
goToNextStep={() => {}}
isNextStepDisabled={true}
stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={false}
/>
);
@@ -96,4 +99,23 @@ describe('Header', () => {
.prop('isDisabled')
).toEqual(false);
});
+
+ it('should disable next step when local cluster option is hidden and no other option selected', () => {
+ const component = shallowWithIntl(
+ {}}
+ dataSourceRef={{ type: 'type', id: 'id', title: 'title' }!}
+ goToNextStep={() => {}}
+ isNextStepDisabled={true}
+ stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={true}
+ />
+ );
+
+ expect(
+ component
+ .find('[data-test-subj="createIndexPatternStepDataSourceNextStepButton"]')
+ .prop('isDisabled')
+ ).toEqual(true);
+ });
});
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx
index e5a6fdf60c0..bf011d5d14b 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx
@@ -34,14 +34,22 @@ interface HeaderProps {
goToNextStep: (dataSourceRef: DataSourceRef) => void;
isNextStepDisabled: boolean;
stepInfo: StepInfo;
+ hideLocalCluster: boolean;
}
export const Header: React.FC = (props: HeaderProps) => {
- const { dataSourceRef, onDataSourceSelected, goToNextStep, isNextStepDisabled, stepInfo } = props;
+ const {
+ dataSourceRef,
+ onDataSourceSelected,
+ goToNextStep,
+ isNextStepDisabled,
+ stepInfo,
+ hideLocalCluster,
+ } = props;
const { currentStepNumber, totalStepNumber } = stepInfo;
- const [defaultChecked, setDefaultChecked] = useState(true);
- const [dataSourceChecked, setDataSourceChecked] = useState(false);
+ const [defaultChecked, setDefaultChecked] = useState(!hideLocalCluster);
+ const [dataSourceChecked, setDataSourceChecked] = useState(hideLocalCluster);
const [dataSources, setDataSources] = useState([]);
const [isLoading, setIsLoading] = useState(false);
@@ -113,34 +121,38 @@ export const Header: React.FC = (props: HeaderProps) => {
defaultMessage="Pick a data source within which to configure index patterns."
/>
-
-
+
+
+ }
+ checked={defaultChecked}
+ onChange={(e) => onChangeDefaultChecked(e)}
+ compressed
/>
- }
- checked={defaultChecked}
- onChange={(e) => onChangeDefaultChecked(e)}
- compressed
- />
-
-
+
+ }
+ checked={dataSourceChecked}
+ onChange={(e) => onChangeDataSourceChecked(e)}
+ compressed
/>
- }
- checked={dataSourceChecked}
- onChange={(e) => onChangeDataSourceChecked(e)}
- compressed
- />
+
+ )}
{dataSourceChecked && (
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.test.tsx
index 42c5ffa4cee..3ce1e5f441b 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.test.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.test.tsx
@@ -8,7 +8,7 @@ import { shallow } from 'enzyme';
import { StepDataSource } from './step_data_source';
describe('StepDataSource', () => {
- it('should render normally', () => {
+ it('should render normally with hideLocalCluster undefined', () => {
const component = shallow(
{}}
@@ -18,4 +18,28 @@ describe('StepDataSource', () => {
expect(component).toMatchSnapshot();
});
+
+ it('should render normally with hideLocalCluster false', () => {
+ const component = shallow(
+ {}}
+ stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={false}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
+ it('should render normally with hideLocalCluster true', () => {
+ const component = shallow(
+ {}}
+ stepInfo={{ totalStepNumber: 0, currentStepNumber: 0 }}
+ hideLocalCluster={true}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
});
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.tsx
index fa91b455ae6..4dcd4661884 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/step_data_source.tsx
@@ -13,10 +13,11 @@ import { Header } from './components/header';
interface StepDataSourceProps {
goToNextStep: (dataSourceRef: DataSourceRef) => void;
stepInfo: StepInfo;
+ hideLocalCluster: boolean;
}
export const StepDataSource = (props: StepDataSourceProps) => {
- const { goToNextStep, stepInfo } = props;
+ const { goToNextStep, stepInfo, hideLocalCluster } = props;
const [selectedDataSource, setSelectedDataSource] = useState();
const [isNextStepDisabled, setIsNextStepDisabled] = useState(true);
@@ -37,6 +38,7 @@ export const StepDataSource = (props: StepDataSourceProps) => {
goToNextStep={() => goToNextStep(selectedDataSource!)}
isNextStepDisabled={isNextStepDisabled}
stepInfo={stepInfo}
+ hideLocalCluster={hideLocalCluster}
/>
);
diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
index 37669ba43e9..337efa752ae 100644
--- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
+++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx
@@ -280,6 +280,8 @@ export class CreateIndexPatternWizard extends Component<
currentStepNumber: getCurrentStepNumber(step, this.dataSourceEnabled),
};
+ const hideLocalCluster = this.context.services.hideLocalCluster;
+
if (isInitiallyLoadingIndices) {
return ;
}
@@ -291,7 +293,11 @@ export class CreateIndexPatternWizard extends Component<
{header}
-
+
);
}
diff --git a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
index 162d1d0876c..af37e6ddb71 100644
--- a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
+++ b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx
@@ -36,6 +36,7 @@ import { i18n } from '@osd/i18n';
import { I18nProvider } from '@osd/i18n/react';
import { StartServicesAccessor } from 'src/core/public';
+import { DataSourcePluginSetup } from 'src/plugins/data_source/public';
import { OpenSearchDashboardsContextProvider } from '../../../opensearch_dashboards_react/public';
import { ManagementAppMountParams } from '../../../management/public';
import {
@@ -60,15 +61,17 @@ const readOnlyBadge = {
export async function mountManagementSection(
getStartServices: StartServicesAccessor,
params: ManagementAppMountParams,
- getMlCardState: () => MlCardState
+ getMlCardState: () => MlCardState,
+ dataSource?: DataSourcePluginSetup
) {
const [
{ chrome, application, savedObjects, uiSettings, notifications, overlays, http, docLinks },
- { data, dataSource },
+ { data },
indexPatternManagementStart,
] = await getStartServices();
const canSave = Boolean(application.capabilities.indexPatterns.save);
- const dataSourceEnabled = !!dataSource;
+ const dataSourceEnabled = dataSource?.dataSourceEnabled ?? false;
+ const hideLocalCluster = dataSource?.hideLocalCluster ?? false;
if (!canSave) {
chrome.setBadge(readOnlyBadge);
@@ -88,6 +91,7 @@ export async function mountManagementSection(
setBreadcrumbs: params.setBreadcrumbs,
getMlCardState,
dataSourceEnabled,
+ hideLocalCluster,
};
ReactDOM.render(
diff --git a/src/plugins/index_pattern_management/public/plugin.ts b/src/plugins/index_pattern_management/public/plugin.ts
index cf68e043b76..98eaab6160e 100644
--- a/src/plugins/index_pattern_management/public/plugin.ts
+++ b/src/plugins/index_pattern_management/public/plugin.ts
@@ -31,7 +31,7 @@
import { i18n } from '@osd/i18n';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
-import { DataSourcePluginStart } from 'src/plugins/data_source/public';
+import { DataSourcePluginSetup, DataSourcePluginStart } from 'src/plugins/data_source/public';
import { UrlForwardingSetup } from '../../url_forwarding/public';
import {
IndexPatternManagementService,
@@ -44,6 +44,7 @@ import { ManagementSetup } from '../../management/public';
export interface IndexPatternManagementSetupDependencies {
management: ManagementSetup;
urlForwarding: UrlForwardingSetup;
+ dataSource?: DataSourcePluginSetup;
}
export interface IndexPatternManagementStartDependencies {
@@ -75,8 +76,10 @@ export class IndexPatternManagementPlugin
public setup(
core: CoreSetup,
- { management, urlForwarding }: IndexPatternManagementSetupDependencies
+ dependencies: IndexPatternManagementSetupDependencies
) {
+ const { urlForwarding, management, dataSource } = dependencies;
+
const opensearchDashboardsSection = management.sections.section.opensearchDashboards;
if (!opensearchDashboardsSection) {
@@ -103,8 +106,11 @@ export class IndexPatternManagementPlugin
mount: async (params) => {
const { mountManagementSection } = await import('./management_app');
- return mountManagementSection(core.getStartServices, params, () =>
- this.indexPatternManagementService.environmentService.getEnvironment().ml()
+ return mountManagementSection(
+ core.getStartServices,
+ params,
+ () => this.indexPatternManagementService.environmentService.getEnvironment().ml(),
+ dataSource
);
},
});
diff --git a/src/plugins/index_pattern_management/public/types.ts b/src/plugins/index_pattern_management/public/types.ts
index 24dc2cd59c3..7b2cd8575a7 100644
--- a/src/plugins/index_pattern_management/public/types.ts
+++ b/src/plugins/index_pattern_management/public/types.ts
@@ -59,6 +59,7 @@ export interface IndexPatternManagmentContext {
setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
getMlCardState: () => MlCardState;
dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
}
export type IndexPatternManagmentContextValue = OpenSearchDashboardsReactContextValue<
diff --git a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx
index f56ece8b51d..967dd93290d 100644
--- a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx
@@ -45,6 +45,7 @@ interface MountParams {
serviceRegistry: ISavedObjectsManagementServiceRegistry;
mountParams: ManagementAppMountParams;
dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
}
let allowedObjectTypes: string[] | undefined;
@@ -60,6 +61,7 @@ export const mountManagementSection = async ({
mountParams,
serviceRegistry,
dataSourceEnabled,
+ hideLocalCluster,
}: MountParams) => {
const [coreStart, { data, uiActions }, pluginStart] = await core.getStartServices();
const { element, history, setBreadcrumbs } = mountParams;
@@ -111,6 +113,7 @@ export const mountManagementSection = async ({
allowedTypes={allowedObjectTypes}
setBreadcrumbs={setBreadcrumbs}
dataSourceEnabled={dataSourceEnabled}
+ hideLocalCluster={hideLocalCluster}
/>
diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap
index b40211fffe3..e15e72d6a2c 100644
--- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap
+++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap
@@ -526,7 +526,7 @@ Array [
]
`;
-exports[`Flyout should render cluster selector and import options 1`] = `
+exports[`Flyout should render cluster selector and import options when local cluster option is hidden 1`] = `
+
+
+
+
+
+
+`;
+
+exports[`Flyout should render cluster selector and import options when local cluster option is not hidden 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ }
+ labelType="label"
+ >
+
+ }
+ onChange={[Function]}
+ />
+
+
+
+
+
+ Import options
+
+ ,
+ }
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
expect(component).toMatchSnapshot();
});
- it('should render cluster selector and import options', async () => {
+ it('should render cluster selector and import options when local cluster option is not hidden', async () => {
const component = shallowRender({
...defaultProps,
dataSourceEnabled: true,
+ hideLocalCluster: false,
+ notifications: notificationServiceMock.createStartContract(),
+ });
+
+ // Ensure all promises resolve
+ await new Promise((resolve) => process.nextTick(resolve));
+ // Ensure the state changes are reflected
+ component.update();
+
+ expect(component).toMatchSnapshot();
+ });
+
+ it('should render cluster selector and import options when local cluster option is hidden', async () => {
+ const component = shallowRender({
+ ...defaultProps,
+ dataSourceEnabled: true,
+ hideLocalCluster: true,
notifications: notificationServiceMock.createStartContract(),
});
diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx
index 82b763d18db..f170713e023 100644
--- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx
@@ -94,6 +94,7 @@ export interface FlyoutProps {
http: HttpStart;
search: DataPublicPluginStart['search'];
dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
savedObjects: SavedObjectsClientContract;
notifications: NotificationsStart;
}
@@ -821,6 +822,7 @@ export class Flyout extends Component {
notifications={this.props.notifications.toasts}
onSelectedDataSource={this.onSelectedDataSourceChange}
disabled={!this.props.dataSourceEnabled}
+ hideLocalCluster={this.props.hideLocalCluster}
fullWidth={true}
/>
@@ -841,11 +843,16 @@ export class Flyout extends Component {
}
renderFooter() {
- const { isLegacyFile, status } = this.state;
+ const { isLegacyFile, status, selectedDataSourceId } = this.state;
const { done, close } = this.props;
let confirmButton;
+ let importButtonDisabled = false;
+ if (this.props.dataSourceEnabled && this.props.hideLocalCluster && !selectedDataSourceId) {
+ importButtonDisabled = true;
+ }
+
if (status === 'success') {
confirmButton = (
@@ -877,6 +884,7 @@ export class Flyout extends Component {
size="s"
fill
isLoading={status === 'loading'}
+ disabled={importButtonDisabled}
data-test-subj="importSavedObjectsImportBtn"
>
boolean;
dateFormat: string;
dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
}
export interface SavedObjectsTableState {
@@ -560,6 +561,7 @@ export class SavedObjectsTable extends Component
diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx
index 1776f3e7bfd..b3ef976d828 100644
--- a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx
@@ -50,6 +50,7 @@ const SavedObjectsTablePage = ({
namespaceRegistry,
setBreadcrumbs,
dataSourceEnabled,
+ hideLocalCluster,
}: {
coreStart: CoreStart;
dataStart: DataPublicPluginStart;
@@ -60,6 +61,7 @@ const SavedObjectsTablePage = ({
namespaceRegistry: SavedObjectsManagementNamespaceServiceStart;
setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void;
dataSourceEnabled: boolean;
+ hideLocalCluster: boolean;
}) => {
const capabilities = coreStart.application.capabilities;
const itemsPerPage = coreStart.uiSettings.get('savedObjects:perPage', 50);
@@ -105,6 +107,7 @@ const SavedObjectsTablePage = ({
return inAppUrl ? Boolean(get(capabilities, inAppUrl.uiCapabilitiesPath)) : false;
}}
dataSourceEnabled={dataSourceEnabled}
+ hideLocalCluster={hideLocalCluster}
/>
);
};
diff --git a/src/plugins/saved_objects_management/public/plugin.ts b/src/plugins/saved_objects_management/public/plugin.ts
index 690dee9c21e..d03342a4f1d 100644
--- a/src/plugins/saved_objects_management/public/plugin.ts
+++ b/src/plugins/saved_objects_management/public/plugin.ts
@@ -139,6 +139,7 @@ export class SavedObjectsManagementPlugin
serviceRegistry: this.serviceRegistry,
mountParams,
dataSourceEnabled: !!dataSource,
+ hideLocalCluster: dataSource?.hideLocalCluster ?? false,
});
},
});