mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fixes index pattern wizard when there are remote clusters but no local indices (#24339)
* don't hide wizard if clusters exist * catch errors * add toast notifs if unable to load data
This commit is contained in:
parent
ca1d280818
commit
bb250560ec
13 changed files with 406 additions and 122 deletions
|
@ -30,6 +30,7 @@ import { managementApi } from './server/routes/api/management';
|
|||
import { scriptsApi } from './server/routes/api/scripts';
|
||||
import { registerSuggestionsApi } from './server/routes/api/suggestions';
|
||||
import { registerKqlTelemetryApi } from './server/routes/api/kql_telemetry';
|
||||
import { registerClustersRoute } from './server/routes/api/remote_info';
|
||||
import { registerFieldFormats } from './server/field_formats/register';
|
||||
import { registerTutorials } from './server/tutorials/register';
|
||||
import * as systemApi from './server/lib/system_api';
|
||||
|
@ -167,6 +168,7 @@ export default function (kibana) {
|
|||
registerFieldFormats(server);
|
||||
registerTutorials(server);
|
||||
makeKQLUsageCollector(server);
|
||||
registerClustersRoute(server);
|
||||
server.expose('systemApi', systemApi);
|
||||
server.expose('handleEsError', handleEsError);
|
||||
server.injectUiAppVars('kibana', () => injectVars(server));
|
||||
|
|
|
@ -1,132 +1,205 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CreateIndexPatternWizard defaults to the loading state 1`] = `
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<LoadingState />
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
<LoadingState />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders index pattern step when there are indices 1`] = `
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepIndexPattern
|
||||
allIndices={
|
||||
Array [
|
||||
Object {
|
||||
"name": "myIndexPattern",
|
||||
},
|
||||
]
|
||||
}
|
||||
esService={Object {}}
|
||||
goToNextStep={[Function]}
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepIndexPattern
|
||||
allIndices={
|
||||
Array [
|
||||
Object {
|
||||
"name": "myIndexPattern",
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
initialQuery=""
|
||||
isIncludingSystemIndices={false}
|
||||
savedObjectsClient={Object {}}
|
||||
esService={Object {}}
|
||||
goToNextStep={[Function]}
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
}
|
||||
}
|
||||
initialQuery=""
|
||||
isIncludingSystemIndices={false}
|
||||
savedObjectsClient={Object {}}
|
||||
/>
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders the empty state when there are no indices 1`] = `
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<EmptyState
|
||||
onRefresh={[Function]}
|
||||
/>
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
<EmptyState
|
||||
onRefresh={[Function]}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders time field step when step is set to 2 1`] = `
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepTimeField
|
||||
createIndexPattern={[Function]}
|
||||
goToPreviousStep={[Function]}
|
||||
indexPattern=""
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepTimeField
|
||||
createIndexPattern={[Function]}
|
||||
goToPreviousStep={[Function]}
|
||||
indexPattern=""
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
}
|
||||
}
|
||||
}
|
||||
indexPatternsService={Object {}}
|
||||
indexPatternsService={Object {}}
|
||||
/>
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard renders when there are no indices but there are remote clusters 1`] = `
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={false}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepIndexPattern
|
||||
allIndices={Array []}
|
||||
esService={Object {}}
|
||||
goToNextStep={[Function]}
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
}
|
||||
}
|
||||
initialQuery=""
|
||||
isIncludingSystemIndices={false}
|
||||
savedObjectsClient={Object {}}
|
||||
/>
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CreateIndexPatternWizard shows system indices even if there are no other indices if the include system indices is toggled 1`] = `
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={true}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepIndexPattern
|
||||
allIndices={
|
||||
Array [
|
||||
Object {
|
||||
"name": ".kibana ",
|
||||
},
|
||||
]
|
||||
}
|
||||
esService={Object {}}
|
||||
goToNextStep={[Function]}
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Header
|
||||
indexPatternName="name"
|
||||
isBeta={false}
|
||||
isIncludingSystemIndices={true}
|
||||
onChangeIncludingSystemIndices={[Function]}
|
||||
showSystemIndices={false}
|
||||
/>
|
||||
<StepIndexPattern
|
||||
allIndices={
|
||||
Array [
|
||||
Object {
|
||||
"name": ".kibana ",
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
initialQuery=""
|
||||
isIncludingSystemIndices={true}
|
||||
savedObjectsClient={Object {}}
|
||||
esService={Object {}}
|
||||
goToNextStep={[Function]}
|
||||
indexPatternCreationType={
|
||||
Object {
|
||||
"checkIndicesForErrors": [Function],
|
||||
"getIndexPatternMappings": [Function],
|
||||
"getIndexPatternName": [Function],
|
||||
"getIndexPatternType": [Function],
|
||||
"getIsBeta": [Function],
|
||||
"getShowSystemIndices": [Function],
|
||||
"renderPrompt": [Function],
|
||||
}
|
||||
}
|
||||
initialQuery=""
|
||||
isIncludingSystemIndices={true}
|
||||
savedObjectsClient={Object {}}
|
||||
/>
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
dismissToast={[Function]}
|
||||
toastLifeTimeMs={6000}
|
||||
toasts={Array []}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
|
|
@ -42,6 +42,9 @@ jest.mock('../lib/get_indices', () => ({
|
|||
];
|
||||
},
|
||||
}));
|
||||
jest.mock('ui/chrome', () => ({
|
||||
addBasePath: () => { },
|
||||
}));
|
||||
|
||||
const loadingDataDocUrl = '';
|
||||
const initialQuery = '';
|
||||
|
@ -80,6 +83,26 @@ describe('CreateIndexPatternWizard', () => {
|
|||
component.setState({
|
||||
isInitiallyLoadingIndices: false,
|
||||
allIndices: [],
|
||||
remoteClustersExist: false
|
||||
});
|
||||
|
||||
await component.update();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders when there are no indices but there are remote clusters', async () => {
|
||||
const component = shallow(
|
||||
<CreateIndexPatternWizard
|
||||
loadingDataDocUrl={loadingDataDocUrl}
|
||||
initialQuery={initialQuery}
|
||||
services={services}
|
||||
/>
|
||||
);
|
||||
|
||||
component.setState({
|
||||
isInitiallyLoadingIndices: false,
|
||||
allIndices: [],
|
||||
remoteClustersExist: true
|
||||
});
|
||||
|
||||
await component.update();
|
||||
|
|
|
@ -32,6 +32,7 @@ jest.mock('ui/chrome', () => ({
|
|||
getUiSettingsClient: () => ({
|
||||
get: () => '',
|
||||
}),
|
||||
addBasePath: () => { },
|
||||
}));
|
||||
|
||||
const { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } = require('../render');
|
||||
|
|
|
@ -41,6 +41,7 @@ jest.mock('ui/chrome', () => ({
|
|||
getUiSettingsClient: () => ({
|
||||
get: () => '',
|
||||
}),
|
||||
addBasePath: () => { },
|
||||
}));
|
||||
|
||||
jest.mock('../../../lib/get_indices', () => ({
|
||||
|
@ -62,7 +63,7 @@ const esService = {};
|
|||
const savedObjectsClient = {
|
||||
find: () => ({ savedObjects: [] })
|
||||
};
|
||||
const goToNextStep = () => {};
|
||||
const goToNextStep = () => { };
|
||||
|
||||
const createComponent = props => {
|
||||
return shallowWithIntl(
|
||||
|
|
|
@ -29,6 +29,9 @@ jest.mock('../components/action_buttons', () => ({ ActionButtons: 'ActionButtons
|
|||
jest.mock('../../../lib/extract_time_fields', () => ({
|
||||
extractTimeFields: fields => fields,
|
||||
}));
|
||||
jest.mock('ui/chrome', () => ({
|
||||
addBasePath: () => { },
|
||||
}));
|
||||
|
||||
const mockIndexPatternCreationType = {
|
||||
getIndexPatternType: () => 'default',
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
EuiGlobalToastList
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { StepIndexPattern } from './components/step_index_pattern';
|
||||
import { StepTimeField } from './components/step_time_field';
|
||||
import { Header } from './components/header';
|
||||
|
@ -30,6 +35,7 @@ import { MAX_SEARCH_SIZE } from './constants';
|
|||
import {
|
||||
ensureMinimumTime,
|
||||
getIndices,
|
||||
getRemoteClusters
|
||||
} from './lib';
|
||||
|
||||
export class CreateIndexPatternWizard extends Component {
|
||||
|
@ -52,20 +58,62 @@ export class CreateIndexPatternWizard extends Component {
|
|||
step: 1,
|
||||
indexPattern: '',
|
||||
allIndices: [],
|
||||
remoteClustersExist: false,
|
||||
isInitiallyLoadingIndices: true,
|
||||
isIncludingSystemIndices: false,
|
||||
toasts: []
|
||||
};
|
||||
}
|
||||
|
||||
async componentWillMount() {
|
||||
this.fetchIndices();
|
||||
this.fetchData();
|
||||
}
|
||||
|
||||
fetchIndices = async () => {
|
||||
this.setState({ allIndices: [], isInitiallyLoadingIndices: true });
|
||||
catchAndWarn = async (asyncFn, errorValue, errorMsg) => {
|
||||
try {
|
||||
return await asyncFn;
|
||||
} catch (errors) {
|
||||
this.setState(prevState => ({
|
||||
toasts: prevState.toasts.concat([{
|
||||
title: errorMsg,
|
||||
id: errorMsg,
|
||||
color: 'warning',
|
||||
iconType: 'alert',
|
||||
}])
|
||||
}));
|
||||
return errorValue;
|
||||
}
|
||||
};
|
||||
|
||||
fetchData = async () => {
|
||||
const { services } = this.props;
|
||||
const allIndices = await ensureMinimumTime(getIndices(services.es, this.indexPatternCreationType, `*`, MAX_SEARCH_SIZE)); //
|
||||
this.setState({ allIndices, isInitiallyLoadingIndices: false });
|
||||
|
||||
this.setState({
|
||||
allIndices: [],
|
||||
isInitiallyLoadingIndices: true,
|
||||
remoteClustersExist: false
|
||||
});
|
||||
|
||||
const indicesFailMsg = (<FormattedMessage
|
||||
id="kbn.management.createIndexPattern.loadIndicesFailMsg"
|
||||
defaultMessage="Failed to load indices"
|
||||
/>);
|
||||
|
||||
const clustersFailMsg = (<FormattedMessage
|
||||
id="kbn.management.createIndexPattern.loadClustersFailMsg"
|
||||
defaultMessage="Failed to load remote clusters"
|
||||
/>);
|
||||
|
||||
const [allIndices, remoteClusters] = await ensureMinimumTime([
|
||||
this.catchAndWarn(getIndices(services.es, this.indexPatternCreationType, `*`, MAX_SEARCH_SIZE), [], indicesFailMsg),
|
||||
this.catchAndWarn(getRemoteClusters(services.$http), [], clustersFailMsg)
|
||||
]);
|
||||
|
||||
this.setState({
|
||||
allIndices,
|
||||
isInitiallyLoadingIndices: false,
|
||||
remoteClustersExist: remoteClusters.length !== 0
|
||||
});
|
||||
}
|
||||
|
||||
createIndexPattern = async (timeFieldName, indexPatternId) => {
|
||||
|
@ -127,6 +175,7 @@ export class CreateIndexPatternWizard extends Component {
|
|||
isIncludingSystemIndices,
|
||||
step,
|
||||
indexPattern,
|
||||
remoteClustersExist
|
||||
} = this.state;
|
||||
|
||||
if (isInitiallyLoadingIndices) {
|
||||
|
@ -134,8 +183,10 @@ export class CreateIndexPatternWizard extends Component {
|
|||
}
|
||||
|
||||
const hasDataIndices = allIndices.some(({ name }) => !name.startsWith('.'));
|
||||
if (!hasDataIndices && !isIncludingSystemIndices) {
|
||||
return <EmptyState onRefresh={this.fetchIndices} />;
|
||||
if (!hasDataIndices &&
|
||||
!isIncludingSystemIndices &&
|
||||
!remoteClustersExist) {
|
||||
return <EmptyState onRefresh={this.fetchData} />;
|
||||
}
|
||||
|
||||
if (step === 1) {
|
||||
|
@ -169,15 +220,28 @@ export class CreateIndexPatternWizard extends Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
removeToast = (removedToast) => {
|
||||
this.setState(prevState => ({
|
||||
toasts: prevState.toasts.filter(toast => toast.id !== removedToast.id),
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const header = this.renderHeader();
|
||||
const content = this.renderContent();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{header}
|
||||
{content}
|
||||
</div>
|
||||
<React.Fragment>
|
||||
<div>
|
||||
{header}
|
||||
{content}
|
||||
</div>
|
||||
<EuiGlobalToastList
|
||||
toasts={this.state.toasts}
|
||||
dismissToast={this.removeToast}
|
||||
toastLifeTimeMs={6000}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ uiRoutes.when('/management/kibana/index', {
|
|||
config: $injector.get('config'),
|
||||
es: $injector.get('es'),
|
||||
indexPatterns: $injector.get('indexPatterns'),
|
||||
$http: $injector.get('$http'),
|
||||
savedObjectsClient: Private(SavedObjectsClientProvider),
|
||||
indexPatternCreationType,
|
||||
changeUrl: url => {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
const apiPrefix = chrome.addBasePath('/api/kibana');
|
||||
|
||||
export async function getRemoteClusters($http) {
|
||||
const response = await $http.get(`${apiPrefix}/clusters`);
|
||||
return response.data;
|
||||
}
|
|
@ -28,3 +28,5 @@ export { getMatchedIndices } from './get_matched_indices';
|
|||
export { containsIllegalCharacters } from './contains_illegal_characters';
|
||||
|
||||
export { extractTimeFields } from './extract_time_fields';
|
||||
|
||||
export { getRemoteClusters } from './get_remote_clusters';
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { once } from 'lodash';
|
||||
|
||||
const callWithRequest = once(server => {
|
||||
const cluster = server.plugins.elasticsearch.getCluster('data');
|
||||
return cluster.callWithRequest;
|
||||
});
|
||||
|
||||
export const callWithRequestFactory = (server, request) => {
|
||||
return (...args) => {
|
||||
return callWithRequest(server)(request, ...args);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { callWithRequestFactory } from './call_with_request_factory';
|
||||
import handleEsError from '../../../lib/handle_es_error';
|
||||
|
||||
async function fetchRemoteClusters(callWithRequest) {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
path: '_remote/info'
|
||||
};
|
||||
const remoteInfo = await callWithRequest('transport.request', options);
|
||||
return Object.keys(remoteInfo);
|
||||
}
|
||||
|
||||
export function registerClustersRoute(server) {
|
||||
server.route({
|
||||
path: '/api/kibana/clusters',
|
||||
method: 'GET',
|
||||
handler: async request => {
|
||||
const callWithRequest = callWithRequestFactory(server, request);
|
||||
try {
|
||||
return await fetchRemoteClusters(callWithRequest);
|
||||
} catch (error) {
|
||||
throw handleEsError(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
import { callWithRequestFactory } from '../../../lib/call_with_request_factory';
|
||||
import { isEsErrorFactory } from '../../../lib/is_es_error_factory';
|
||||
import { wrapEsError, wrapUnknownError } from '../../../lib/error_wrappers';
|
||||
import { licensePreRoutingFactory } from'../../../lib/license_pre_routing_factory';
|
||||
import { licensePreRoutingFactory } from '../../../lib/license_pre_routing_factory';
|
||||
import { fetchAliases } from './fetch_aliases';
|
||||
|
||||
function formatHits(hits, aliases) {
|
||||
|
@ -60,7 +60,7 @@ export function registerListRoute(server) {
|
|||
}
|
||||
},
|
||||
config: {
|
||||
pre: [ licensePreRouting ]
|
||||
pre: [licensePreRouting]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue