mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Consume elasticsearch.publicBaseUrl where possible (#192741)
## Summary This actually consumes the public base url in the cloud plugin and the places depending on the `elasticsearchUrl` value populated there. --------- Co-authored-by: Rodney Norris <rodney@tattdcodemonkey.com>
This commit is contained in:
parent
88163b063a
commit
b4a7b2e216
31 changed files with 234 additions and 73 deletions
|
@ -21,6 +21,7 @@ const createOpts = async (props: KibanaConnectionDetailsProviderProps) => {
|
|||
const { http, docLinks, analytics } = start.core;
|
||||
const locator = start.plugins?.share?.url?.locators.get('MANAGEMENT_APP_LOCATOR');
|
||||
const manageKeysLink = await locator?.getUrl({ sectionId: 'security', appId: 'api_keys' });
|
||||
const elasticsearchConfig = await start.plugins?.cloud?.fetchElasticsearchConfig();
|
||||
const result: ConnectionDetailsOpts = {
|
||||
...options,
|
||||
navigateToUrl: start.core.application
|
||||
|
@ -35,7 +36,7 @@ const createOpts = async (props: KibanaConnectionDetailsProviderProps) => {
|
|||
},
|
||||
endpoints: {
|
||||
id: start.plugins?.cloud?.cloudId,
|
||||
url: start.plugins?.cloud?.elasticsearchUrl,
|
||||
url: elasticsearchConfig?.elasticsearchUrl,
|
||||
cloudIdLearMoreLink: docLinks?.links?.cloud?.beatsAndLogstashConfiguration,
|
||||
...options?.endpoints,
|
||||
},
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import React, { FC, PropsWithChildren, useContext } from 'react';
|
||||
import React, { FC, PropsWithChildren, useContext, useEffect } from 'react';
|
||||
|
||||
export interface DeploymentDetailsContextValue {
|
||||
cloudId?: string;
|
||||
|
@ -58,7 +57,7 @@ export interface DeploymentDetailsKibanaDependencies {
|
|||
cloud: {
|
||||
isCloudEnabled: boolean;
|
||||
cloudId?: string;
|
||||
elasticsearchUrl?: string;
|
||||
fetchElasticsearchConfig: () => Promise<{ elasticsearchUrl?: string }>;
|
||||
};
|
||||
/** DocLinksStart contract */
|
||||
docLinks: {
|
||||
|
@ -79,11 +78,19 @@ export interface DeploymentDetailsKibanaDependencies {
|
|||
export const DeploymentDetailsKibanaProvider: FC<
|
||||
PropsWithChildren<DeploymentDetailsKibanaDependencies>
|
||||
> = ({ children, ...services }) => {
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = React.useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
services.cloud.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config.elasticsearchUrl || '');
|
||||
});
|
||||
}, [services.cloud]);
|
||||
|
||||
const {
|
||||
core: {
|
||||
application: { navigateToUrl },
|
||||
},
|
||||
cloud: { isCloudEnabled, cloudId, elasticsearchUrl },
|
||||
cloud: { isCloudEnabled, cloudId },
|
||||
share: {
|
||||
url: { locators },
|
||||
},
|
||||
|
|
|
@ -47,6 +47,7 @@ test('set correct defaults', () => {
|
|||
"maxSockets": 800,
|
||||
"password": undefined,
|
||||
"pingTimeout": "PT30S",
|
||||
"publicBaseUrl": undefined,
|
||||
"requestHeadersWhitelist": Array [
|
||||
"authorization",
|
||||
"es-client-authentication",
|
||||
|
|
|
@ -359,6 +359,13 @@ export class ElasticsearchConfig implements IElasticsearchConfig {
|
|||
*/
|
||||
public readonly hosts: string[];
|
||||
|
||||
/**
|
||||
* Optional host that users can use to connect to your Elasticsearch cluster,
|
||||
* this URL will be shown in Kibana as the Elasticsearch URL
|
||||
*/
|
||||
|
||||
public readonly publicBaseUrl?: string;
|
||||
|
||||
/**
|
||||
* List of Kibana client-side headers to send to Elasticsearch when request
|
||||
* scoped cluster client is used. If this is an empty array then *no* client-side
|
||||
|
@ -473,6 +480,7 @@ export class ElasticsearchConfig implements IElasticsearchConfig {
|
|||
this.skipStartupConnectionCheck = rawConfig.skipStartupConnectionCheck;
|
||||
this.apisToRedactInLogs = rawConfig.apisToRedactInLogs;
|
||||
this.dnsCacheTtl = rawConfig.dnsCacheTtl;
|
||||
this.publicBaseUrl = rawConfig.publicBaseUrl;
|
||||
|
||||
const { alwaysPresentCertificate, verificationMode } = rawConfig.ssl;
|
||||
const { key, keyPassphrase, certificate, certificateAuthorities } = readKeyAndCerts(rawConfig);
|
||||
|
|
|
@ -135,6 +135,7 @@ export class ElasticsearchService
|
|||
agentStatsProvider: {
|
||||
getAgentsStats: agentManager.getAgentsStats.bind(agentManager),
|
||||
},
|
||||
publicBaseUrl: config.publicBaseUrl,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -194,6 +195,7 @@ export class ElasticsearchService
|
|||
metrics: {
|
||||
elasticsearchWaitTime,
|
||||
},
|
||||
publicBaseUrl: config.publicBaseUrl,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,12 @@ export interface ElasticsearchServiceStart {
|
|||
* Returns the capabilities for the default cluster.
|
||||
*/
|
||||
getCapabilities: () => ElasticsearchCapabilities;
|
||||
|
||||
/**
|
||||
* The public base URL (if any) that should be used by end users to access the Elasticsearch cluster.
|
||||
*/
|
||||
|
||||
readonly publicBaseUrl?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -212,6 +212,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>({
|
|||
docLinks: deps.docLinks,
|
||||
elasticsearch: {
|
||||
legacy: deps.elasticsearch.legacy,
|
||||
publicBaseUrl: deps.elasticsearch.publicBaseUrl,
|
||||
setUnauthorizedErrorHandler: deps.elasticsearch.setUnauthorizedErrorHandler,
|
||||
},
|
||||
executionContext: {
|
||||
|
|
|
@ -11,3 +11,5 @@ export const ELASTIC_SUPPORT_LINK = 'https://support.elastic.co/';
|
|||
* This is the page for managing your snapshots on Cloud.
|
||||
*/
|
||||
export const CLOUD_SNAPSHOTS_PATH = 'elasticsearch/snapshots/';
|
||||
|
||||
export const ELASTICSEARCH_CONFIG_ROUTE = '/api/internal/cloud/elasticsearch_config';
|
||||
|
|
|
@ -6,3 +6,7 @@
|
|||
*/
|
||||
|
||||
export type OnBoardingDefaultSolution = 'es' | 'oblt' | 'security';
|
||||
|
||||
export interface ElasticsearchConfigType {
|
||||
elasticsearch_url?: string;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ function createSetupMock(): jest.Mocked<CloudSetup> {
|
|||
deploymentUrl: 'deployment-url',
|
||||
profileUrl: 'profile-url',
|
||||
organizationUrl: 'organization-url',
|
||||
elasticsearchUrl: 'elasticsearch-url',
|
||||
fetchElasticsearchConfig: jest
|
||||
.fn()
|
||||
.mockResolvedValue({ elasticsearchUrl: 'elasticsearch-url' }),
|
||||
kibanaUrl: 'kibana-url',
|
||||
cloudHost: 'cloud-host',
|
||||
cloudDefaultPort: '443',
|
||||
|
@ -53,6 +55,7 @@ const createStartMock = (): jest.Mocked<CloudStart> => ({
|
|||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: jest.fn().mockResolvedValue({ elasticsearchUrl: 'elasticsearch-url' }),
|
||||
});
|
||||
|
||||
export const cloudMock = {
|
||||
|
|
|
@ -37,6 +37,7 @@ describe('Cloud Plugin', () => {
|
|||
const plugin = new CloudPlugin(initContext);
|
||||
|
||||
const coreSetup = coreMock.createSetup();
|
||||
coreSetup.http.get.mockResolvedValue({ elasticsearch_url: 'elasticsearch-url' });
|
||||
const setup = plugin.setup(coreSetup);
|
||||
|
||||
return { setup };
|
||||
|
@ -110,8 +111,8 @@ describe('Cloud Plugin', () => {
|
|||
it('exposes components decoded from the cloudId', () => {
|
||||
const decodedId: DecodedCloudId = {
|
||||
defaultPort: '9000',
|
||||
host: 'host',
|
||||
elasticsearchUrl: 'elasticsearch-url',
|
||||
host: 'host',
|
||||
kibanaUrl: 'kibana-url',
|
||||
};
|
||||
decodeCloudIdMock.mockReturnValue(decodedId);
|
||||
|
@ -120,7 +121,6 @@ describe('Cloud Plugin', () => {
|
|||
expect.objectContaining({
|
||||
cloudDefaultPort: '9000',
|
||||
cloudHost: 'host',
|
||||
elasticsearchUrl: 'elasticsearch-url',
|
||||
kibanaUrl: 'kibana-url',
|
||||
})
|
||||
);
|
||||
|
@ -184,6 +184,11 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
expect(setup.serverless.projectType).toBe('security');
|
||||
});
|
||||
it('exposes fetchElasticsearchConfig', async () => {
|
||||
const { setup } = setupPlugin();
|
||||
const result = await setup.fetchElasticsearchConfig();
|
||||
expect(result).toEqual({ elasticsearchUrl: 'elasticsearch-url' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -307,5 +312,13 @@ describe('Cloud Plugin', () => {
|
|||
const start = plugin.start(coreStart);
|
||||
expect(start.serverless.projectName).toBe('My Awesome Project');
|
||||
});
|
||||
it('exposes fetchElasticsearchConfig', async () => {
|
||||
const { plugin } = startPlugin();
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.get.mockResolvedValue({ elasticsearch_url: 'elasticsearch-url' });
|
||||
const start = plugin.start(coreStart);
|
||||
const result = await start.fetchElasticsearchConfig();
|
||||
expect(result).toEqual({ elasticsearchUrl: 'elasticsearch-url' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,12 +12,13 @@ import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kb
|
|||
import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context';
|
||||
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
|
||||
import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url';
|
||||
import { CLOUD_SNAPSHOTS_PATH } from '../common/constants';
|
||||
import { CLOUD_SNAPSHOTS_PATH, ELASTICSEARCH_CONFIG_ROUTE } from '../common/constants';
|
||||
import { decodeCloudId, type DecodedCloudId } from '../common/decode_cloud_id';
|
||||
import { getFullCloudUrl } from '../common/utils';
|
||||
import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution';
|
||||
import type { CloudSetup, CloudStart } from './types';
|
||||
import type { CloudSetup, CloudStart, PublicElasticsearchConfigType } from './types';
|
||||
import { getSupportUrl } from './utils';
|
||||
import { ElasticsearchConfigType } from '../common/types';
|
||||
|
||||
export interface CloudConfigType {
|
||||
id?: string;
|
||||
|
@ -66,12 +67,14 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
private readonly isServerlessEnabled: boolean;
|
||||
private readonly contextProviders: Array<FC<PropsWithChildren<unknown>>> = [];
|
||||
private readonly logger: Logger;
|
||||
private elasticsearchConfig?: PublicElasticsearchConfigType;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.config = this.initializerContext.config.get<CloudConfigType>();
|
||||
this.isCloudEnabled = getIsCloudEnabled(this.config.id);
|
||||
this.isServerlessEnabled = !!this.config.serverless?.project_id;
|
||||
this.logger = initializerContext.logger.get();
|
||||
this.elasticsearchConfig = undefined;
|
||||
}
|
||||
|
||||
public setup(core: CoreSetup): CloudSetup {
|
||||
|
@ -99,7 +102,6 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
csp,
|
||||
baseUrl,
|
||||
...this.getCloudUrls(),
|
||||
elasticsearchUrl: decodedId?.elasticsearchUrl,
|
||||
kibanaUrl: decodedId?.kibanaUrl,
|
||||
cloudHost: decodedId?.host,
|
||||
cloudDefaultPort: decodedId?.defaultPort,
|
||||
|
@ -119,6 +121,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
registerCloudService: (contextProvider) => {
|
||||
this.contextProviders.push(contextProvider);
|
||||
},
|
||||
fetchElasticsearchConfig: this.fetchElasticsearchConfig.bind(this, core.http),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -166,7 +169,6 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
profileUrl,
|
||||
organizationUrl,
|
||||
projectsUrl,
|
||||
elasticsearchUrl: decodedId?.elasticsearchUrl,
|
||||
kibanaUrl: decodedId?.kibanaUrl,
|
||||
isServerlessEnabled: this.isServerlessEnabled,
|
||||
serverless: {
|
||||
|
@ -176,6 +178,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
},
|
||||
performanceUrl,
|
||||
usersAndRolesUrl,
|
||||
fetchElasticsearchConfig: this.fetchElasticsearchConfig.bind(this, coreStart.http),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -216,4 +219,26 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
projectsUrl: fullCloudProjectsUrl,
|
||||
};
|
||||
}
|
||||
|
||||
private async fetchElasticsearchConfig(
|
||||
http: CoreStart['http']
|
||||
): Promise<PublicElasticsearchConfigType> {
|
||||
if (this.elasticsearchConfig !== undefined) {
|
||||
// This config should be fully populated on first fetch, so we should avoid refetching from server
|
||||
return this.elasticsearchConfig;
|
||||
}
|
||||
try {
|
||||
const result = await http.get<ElasticsearchConfigType>(ELASTICSEARCH_CONFIG_ROUTE, {
|
||||
version: '1',
|
||||
});
|
||||
|
||||
this.elasticsearchConfig = { elasticsearchUrl: result.elasticsearch_url || undefined };
|
||||
return this.elasticsearchConfig;
|
||||
} catch {
|
||||
this.logger.error('Failed to fetch Elasticsearch config');
|
||||
return {
|
||||
elasticsearchUrl: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ export interface CloudStart {
|
|||
*/
|
||||
projectsUrl?: string;
|
||||
/**
|
||||
* The full URL to the elasticsearch cluster.
|
||||
* Fetches the full URL to the elasticsearch cluster.
|
||||
*/
|
||||
elasticsearchUrl?: string;
|
||||
fetchElasticsearchConfig: () => Promise<PublicElasticsearchConfigType>;
|
||||
/**
|
||||
* The full URL to the Kibana deployment.
|
||||
*/
|
||||
|
@ -150,9 +150,9 @@ export interface CloudSetup {
|
|||
*/
|
||||
snapshotsUrl?: string;
|
||||
/**
|
||||
* The full URL to the elasticsearch cluster.
|
||||
* Fetches the full URL to the elasticsearch cluster.
|
||||
*/
|
||||
elasticsearchUrl?: string;
|
||||
fetchElasticsearchConfig: () => Promise<PublicElasticsearchConfigType>;
|
||||
/**
|
||||
* The full URL to the Kibana deployment.
|
||||
*/
|
||||
|
@ -225,3 +225,12 @@ export interface CloudSetup {
|
|||
orchestratorTarget?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PublicElasticsearchConfigType {
|
||||
/**
|
||||
* The URL to the Elasticsearch cluster, derived from xpack.elasticsearch.publicBaseUrl if populated
|
||||
* Otherwise this is based on the cloudId
|
||||
* If neither is populated, this will be undefined
|
||||
*/
|
||||
elasticsearchUrl?: string;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { decodeCloudId, DecodedCloudId } from '../common/decode_cloud_id';
|
|||
import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution';
|
||||
import { getFullCloudUrl } from '../common/utils';
|
||||
import { readInstanceSizeMb } from './env';
|
||||
import { defineRoutes } from './routes/elasticsearch_routes';
|
||||
|
||||
interface PluginsSetup {
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
|
@ -201,6 +202,9 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
if (this.config.id) {
|
||||
decodedId = decodeCloudId(this.config.id, this.logger);
|
||||
}
|
||||
const router = core.http.createRouter();
|
||||
const elasticsearchUrl = core.elasticsearch.publicBaseUrl || decodedId?.elasticsearchUrl;
|
||||
defineRoutes({ logger: this.logger, router, elasticsearchUrl });
|
||||
|
||||
return {
|
||||
...this.getCloudUrls(),
|
||||
|
@ -209,7 +213,7 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
organizationId,
|
||||
instanceSizeMb: readInstanceSizeMb(),
|
||||
deploymentId,
|
||||
elasticsearchUrl: core.elasticsearch.publicBaseUrl || decodedId?.elasticsearchUrl,
|
||||
elasticsearchUrl,
|
||||
kibanaUrl: decodedId?.kibanaUrl,
|
||||
cloudHost: decodedId?.host,
|
||||
cloudDefaultPort: decodedId?.defaultPort,
|
||||
|
|
35
x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts
Normal file
35
x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { Logger } from '@kbn/logging';
|
||||
import { ElasticsearchConfigType } from '../../common/types';
|
||||
import { ELASTICSEARCH_CONFIG_ROUTE } from '../../common/constants';
|
||||
|
||||
export function defineRoutes({
|
||||
elasticsearchUrl,
|
||||
logger,
|
||||
router,
|
||||
}: {
|
||||
elasticsearchUrl?: string;
|
||||
logger: Logger;
|
||||
router: IRouter;
|
||||
}) {
|
||||
router.versioned
|
||||
.get({
|
||||
path: ELASTICSEARCH_CONFIG_ROUTE,
|
||||
access: 'internal',
|
||||
})
|
||||
.addVersion({ version: '1', validate: {} }, async (context, request, response) => {
|
||||
const body: ElasticsearchConfigType = {
|
||||
elasticsearch_url: elasticsearchUrl,
|
||||
};
|
||||
return response.ok({
|
||||
body,
|
||||
});
|
||||
});
|
||||
}
|
|
@ -22,6 +22,12 @@ jest.mock('../../../../shared/enterprise_search_url', () => ({
|
|||
getEnterpriseSearchUrl: () => 'http://localhost:3002',
|
||||
}));
|
||||
|
||||
jest.mock('../../../../shared/cloud_details/cloud_details', () => ({
|
||||
useCloudDetails: () => ({
|
||||
elasticsearchUrl: 'your_deployment_url',
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('AnalyticsCollectionIntegrate', () => {
|
||||
const analyticsCollections: AnalyticsCollection = {
|
||||
events_datastream: 'analytics-events-example',
|
||||
|
@ -55,7 +61,7 @@ describe('AnalyticsCollectionIntegrate', () => {
|
|||
.toMatchInlineSnapshot(`
|
||||
"<script type=\\"text/javascript\\">
|
||||
window.elasticAnalytics.createTracker({
|
||||
endpoint: \\"elasticsearch-url\\",
|
||||
endpoint: \\"your_deployment_url\\",
|
||||
collectionName: \\"example\\",
|
||||
apiKey: \\"########\\",
|
||||
// Optional: sampling rate percentage: 0-1, 0 = no events, 1 = all events
|
||||
|
|
|
@ -90,6 +90,7 @@ http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-L
|
|||
)}
|
||||
</p>
|
||||
<EuiLink
|
||||
data-test-subj="enterpriseSearchCORSStepLearnMoreAboutCorsForBehavioralAnalyticsLink"
|
||||
href={docLinks.behavioralAnalyticsCORS}
|
||||
data-telemetry-id="entSearchContent-analytics-cors-learnMoreLink"
|
||||
external
|
||||
|
@ -130,6 +131,7 @@ const apiKeyStep = (
|
|||
}
|
||||
)}{' '}
|
||||
<EuiLink
|
||||
data-test-subj="enterpriseSearchApiKeyStepLearnMoreAboutApiKeysLink"
|
||||
href={docLinks.apiKeys}
|
||||
data-telemetry-id="entSearchContent-analytics-apiKey-learnMoreLink"
|
||||
external
|
||||
|
@ -148,6 +150,7 @@ const apiKeyStep = (
|
|||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="enterpriseSearchApiKeyStepCreateApiKeyButton"
|
||||
iconSide="left"
|
||||
iconType="plusInCircleFilled"
|
||||
onClick={openApiKeyModal}
|
||||
|
@ -163,6 +166,7 @@ const apiKeyStep = (
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="enterpriseSearchApiKeyStepViewKeysButton"
|
||||
iconSide="left"
|
||||
iconType="popout"
|
||||
data-telemetry-id="entSearchContent-analytics-apiKey-viewKeysButton"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
import { KibanaLogic } from '../kibana';
|
||||
|
@ -18,10 +20,18 @@ export interface CloudDetails {
|
|||
|
||||
export const useCloudDetails = (): CloudDetails => {
|
||||
const { cloud } = useValues(KibanaLogic);
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = useState<string | undefined>('');
|
||||
|
||||
useEffect(() => {
|
||||
cloud?.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config.elasticsearchUrl);
|
||||
});
|
||||
}, [cloud]);
|
||||
|
||||
return {
|
||||
cloudId: cloud?.cloudId,
|
||||
deploymentUrl: cloud?.deploymentUrl,
|
||||
elasticsearchUrl: cloud?.elasticsearchUrl,
|
||||
elasticsearchUrl,
|
||||
kibanaUrl: cloud?.kibanaUrl,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
|
||||
import { getCloudEnterpriseSearchHost } from './get_cloud_enterprise_search_host';
|
||||
|
||||
const defaultPortCloud = {
|
||||
|
@ -20,7 +22,8 @@ const defaultPortCloud = {
|
|||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
// 9243
|
||||
const customPortCloud = {
|
||||
cloudId:
|
||||
|
@ -35,7 +38,8 @@ const customPortCloud = {
|
|||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
const missingDeploymentIdCloud = {
|
||||
cloudId:
|
||||
'dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=',
|
||||
|
@ -46,7 +50,8 @@ const missingDeploymentIdCloud = {
|
|||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
const noCloud = {
|
||||
cloudId: undefined,
|
||||
isCloudEnabled: false,
|
||||
|
@ -56,7 +61,8 @@ const noCloud = {
|
|||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
|
||||
describe('getCloudEnterpriseSearchHost', () => {
|
||||
it('uses the default port', () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { FC } from 'react';
|
|||
import { kea, MakeLogicType } from 'kea';
|
||||
|
||||
import { ChartsPluginStart } from '@kbn/charts-plugin/public';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public';
|
||||
import { ConsolePluginStart } from '@kbn/console-plugin/public';
|
||||
import {
|
||||
ApplicationStart,
|
||||
|
@ -48,7 +48,7 @@ export interface KibanaLogicProps {
|
|||
application: ApplicationStart;
|
||||
capabilities: Capabilities;
|
||||
charts?: ChartsPluginStart;
|
||||
cloud?: CloudSetup;
|
||||
cloud?: CloudSetup & CloudStart;
|
||||
config: ClientConfigType;
|
||||
connectorTypes?: ConnectorDefinition[];
|
||||
console?: ConsolePluginStart;
|
||||
|
@ -83,7 +83,7 @@ export interface KibanaValues {
|
|||
application: ApplicationStart;
|
||||
capabilities: Capabilities;
|
||||
charts: ChartsPluginStart | null;
|
||||
cloud: CloudSetup | null;
|
||||
cloud: (CloudSetup & CloudStart) | null;
|
||||
config: ClientConfigType;
|
||||
connectorTypes: ConnectorDefinition[];
|
||||
consolePlugin: ConsolePluginStart | null;
|
||||
|
@ -168,7 +168,10 @@ export const KibanaLogic = kea<MakeLogicType<KibanaValues>>({
|
|||
],
|
||||
}),
|
||||
selectors: ({ selectors }) => ({
|
||||
isCloud: [() => [selectors.cloud], (cloud?: CloudSetup) => Boolean(cloud?.isCloudEnabled)],
|
||||
isCloud: [
|
||||
() => [selectors.cloud],
|
||||
(cloud?: CloudSetup & CloudStart) => Boolean(cloud?.isCloudEnabled),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ export const mockKibanaProps: KibanaLogicProps = {
|
|||
charts: chartPluginMock.createStartContract(),
|
||||
cloud: {
|
||||
...cloudMock.createSetup(),
|
||||
...cloudMock.createStart(),
|
||||
isCloudEnabled: false,
|
||||
},
|
||||
config: {
|
||||
|
|
|
@ -24,6 +24,8 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
|
|||
projectId: undefined,
|
||||
projectName: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: () =>
|
||||
Promise.resolve({ elasticsearchUrl: 'https://elastisearch-url' }),
|
||||
};
|
||||
|
||||
return cloud;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
|
@ -62,12 +62,16 @@ export const DetailsPageOverview: React.FunctionComponent<Props> = ({ indexDetai
|
|||
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<LanguageDefinition>(curlDefinition);
|
||||
|
||||
const elasticsearchURL = useMemo(() => {
|
||||
return plugins.cloud?.elasticsearchUrl ?? 'https://your_deployment_url';
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
plugins.cloud?.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config.elasticsearchUrl || 'https://your_deployment_url');
|
||||
});
|
||||
}, [plugins.cloud]);
|
||||
|
||||
const codeSnippetArguments: LanguageDefinitionSnippetArguments = {
|
||||
url: elasticsearchURL,
|
||||
url: elasticsearchUrl,
|
||||
apiKey: 'your_api_key',
|
||||
indexName: name,
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useKibana } from './use_kibana';
|
||||
|
||||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '../constants';
|
||||
|
@ -14,5 +15,13 @@ export const useElasticsearchUrl = (): string => {
|
|||
services: { cloud },
|
||||
} = useKibana();
|
||||
|
||||
return cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER;
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = useState<string>(ELASTICSEARCH_URL_PLACEHOLDER);
|
||||
|
||||
useEffect(() => {
|
||||
cloud?.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config?.elasticsearchUrl || ELASTICSEARCH_URL_PLACEHOLDER);
|
||||
});
|
||||
}, [cloud]);
|
||||
|
||||
return elasticsearchUrl;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { render } from '@testing-library/react';
|
||||
import { PY_LANG_CLIENT } from './py_lang_client'; // Adjust the import path according to your project structure
|
||||
import { ES_CLIENT_DETAILS } from '../view_code_flyout';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { ChatForm } from '../../../types';
|
||||
|
||||
describe('PY_LANG_CLIENT function', () => {
|
||||
|
@ -24,9 +23,7 @@ describe('PY_LANG_CLIENT function', () => {
|
|||
summarization_model: 'Your-new-model',
|
||||
} as unknown as ChatForm;
|
||||
|
||||
const clientDetails = ES_CLIENT_DETAILS({
|
||||
elasticsearchUrl: 'http://my-local-cloud-instance',
|
||||
} as unknown as CloudSetup);
|
||||
const clientDetails = ES_CLIENT_DETAILS('http://my-local-cloud-instance');
|
||||
|
||||
const { container } = render(PY_LANG_CLIENT(formValues, clientDetails));
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
import { render } from '@testing-library/react';
|
||||
import { ES_CLIENT_DETAILS } from '../view_code_flyout';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { ChatForm } from '../../../types';
|
||||
import { LANGCHAIN_PYTHON } from './py_langchain_python';
|
||||
|
||||
|
@ -24,9 +23,7 @@ describe('PY_LANGCHAIN function', () => {
|
|||
summarization_model: 'Your-new-model',
|
||||
} as unknown as ChatForm;
|
||||
|
||||
const clientDetails = ES_CLIENT_DETAILS({
|
||||
elasticsearchUrl: 'http://my-local-cloud-instance',
|
||||
} as unknown as CloudSetup);
|
||||
const clientDetails = ES_CLIENT_DETAILS('http://my-local-cloud-instance');
|
||||
|
||||
const { container } = render(LANGCHAIN_PYTHON(formValues, clientDetails));
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { AnalyticsEvents } from '../../analytics/constants';
|
||||
import { useUsageTracker } from '../../hooks/use_usage_tracker';
|
||||
import { ChatForm, PlaygroundPageMode } from '../../types';
|
||||
|
@ -35,21 +34,13 @@ interface ViewCodeFlyoutProps {
|
|||
selectedPageMode: PlaygroundPageMode;
|
||||
}
|
||||
|
||||
export const ES_CLIENT_DETAILS = (cloud: CloudSetup | undefined) => {
|
||||
if (cloud) {
|
||||
return `
|
||||
export const ES_CLIENT_DETAILS = (elasticsearchUrl: string) => {
|
||||
return `
|
||||
es_client = Elasticsearch(
|
||||
"${cloud.elasticsearchUrl}",
|
||||
"${elasticsearchUrl || '<your-elasticsearch-url>'}",
|
||||
api_key=os.environ["ES_API_KEY"]
|
||||
)
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
es_client = Elasticsearch(
|
||||
"<your-elasticsearch-url>"
|
||||
)
|
||||
`;
|
||||
};
|
||||
|
||||
export const ViewCodeFlyout: React.FC<ViewCodeFlyoutProps> = ({ onClose, selectedPageMode }) => {
|
||||
|
@ -60,8 +51,13 @@ export const ViewCodeFlyout: React.FC<ViewCodeFlyoutProps> = ({ onClose, selecte
|
|||
const {
|
||||
services: { cloud, http },
|
||||
} = useKibana();
|
||||
|
||||
const CLIENT_STEP = ES_CLIENT_DETAILS(cloud);
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = useState<string>('');
|
||||
useEffect(() => {
|
||||
cloud?.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config.elasticsearchUrl || '');
|
||||
});
|
||||
}, [cloud]);
|
||||
const CLIENT_STEP = ES_CLIENT_DETAILS(elasticsearchUrl);
|
||||
|
||||
const steps: Record<string, React.ReactElement> = {
|
||||
'lc-py': LANGCHAIN_PYTHON(formValues, CLIENT_STEP),
|
||||
|
|
|
@ -42,13 +42,10 @@ import { LanguageGrid } from '../languages/language_grid';
|
|||
import { useIngestPipelines } from '../../hooks/api/use_ingest_pipelines';
|
||||
import { DEFAULT_INGESTION_PIPELINE } from '../../../../common';
|
||||
|
||||
import {
|
||||
API_KEY_PLACEHOLDER,
|
||||
CLOUD_ID_PLACEHOLDER,
|
||||
ELASTICSEARCH_URL_PLACEHOLDER,
|
||||
} from '../../constants';
|
||||
import { API_KEY_PLACEHOLDER, CLOUD_ID_PLACEHOLDER } from '../../constants';
|
||||
|
||||
import { ApiKeyPanel } from '../api_key/api_key';
|
||||
import { useElasticsearchUrl } from '../../hooks/use_elastisearch_url';
|
||||
|
||||
export interface APIIndexEmptyPromptProps {
|
||||
indexName: string;
|
||||
|
@ -63,14 +60,14 @@ export const APIIndexEmptyPrompt = ({ indexName, onBackClick }: APIIndexEmptyPro
|
|||
|
||||
const [selectedPipeline, setSelectedPipeline] = React.useState<string>('');
|
||||
const [clientApiKey, setClientApiKey] = useState<string>(API_KEY_PLACEHOLDER);
|
||||
const { elasticsearchURL, cloudId } = useMemo(() => {
|
||||
const { elasticsearchUrl } = useElasticsearchUrl();
|
||||
const { cloudId } = useMemo(() => {
|
||||
return {
|
||||
elasticsearchURL: cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER,
|
||||
cloudId: cloud?.cloudId ?? CLOUD_ID_PLACEHOLDER,
|
||||
};
|
||||
}, [cloud]);
|
||||
const codeSnippetArguments: LanguageDefinitionSnippetArguments = {
|
||||
url: elasticsearchURL,
|
||||
url: elasticsearchUrl,
|
||||
apiKey: clientApiKey,
|
||||
cloudId,
|
||||
indexName,
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('<Overview />', () => {
|
|||
});
|
||||
});
|
||||
const pathname = '/app/elasticsearch';
|
||||
(useLocation as jest.Mock).mockImplementationOnce(() => ({
|
||||
(useLocation as jest.Mock).mockImplementation(() => ({
|
||||
pathname,
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -41,11 +41,7 @@ import { DEFAULT_INGESTION_PIPELINE } from '../../../common';
|
|||
import { docLinks } from '../../../common/doc_links';
|
||||
import { useKibanaServices } from '../hooks/use_kibana';
|
||||
import { useAssetBasePath } from '../hooks/use_asset_base_path';
|
||||
import {
|
||||
API_KEY_PLACEHOLDER,
|
||||
CLOUD_ID_PLACEHOLDER,
|
||||
ELASTICSEARCH_URL_PLACEHOLDER,
|
||||
} from '../constants';
|
||||
import { API_KEY_PLACEHOLDER, CLOUD_ID_PLACEHOLDER } from '../constants';
|
||||
import { javaDefinition } from './languages/java';
|
||||
import { languageDefinitions } from './languages/languages';
|
||||
import { LanguageGrid } from './languages/language_grid';
|
||||
|
@ -57,14 +53,16 @@ import { SelectClientCallouts } from './select_client_callouts';
|
|||
import { PipelineManageButton } from './pipeline_manage_button';
|
||||
import { OPTIONAL_LABEL } from '../../../common/i18n_string';
|
||||
import { useIngestPipelines } from '../hooks/api/use_ingest_pipelines';
|
||||
import { useElasticsearchUrl } from '../hooks/use_elastisearch_url';
|
||||
|
||||
export const ElasticsearchOverview = () => {
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<LanguageDefinition>(javaDefinition);
|
||||
const [clientApiKey, setClientApiKey] = useState<string>(API_KEY_PLACEHOLDER);
|
||||
const { application, cloud, user, share, console: consolePlugin } = useKibanaServices();
|
||||
const { elasticsearchURL, cloudId } = useMemo(() => {
|
||||
const { elasticsearchUrl } = useElasticsearchUrl();
|
||||
|
||||
const { cloudId } = useMemo(() => {
|
||||
return {
|
||||
elasticsearchURL: cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER,
|
||||
cloudId: cloud?.cloudId ?? CLOUD_ID_PLACEHOLDER,
|
||||
};
|
||||
}, [cloud]);
|
||||
|
@ -87,7 +85,7 @@ export const ElasticsearchOverview = () => {
|
|||
const [selectedPipeline, setSelectedPipeline] = React.useState<string>('');
|
||||
|
||||
const codeSnippetArguments: LanguageDefinitionSnippetArguments = {
|
||||
url: elasticsearchURL,
|
||||
url: elasticsearchUrl,
|
||||
apiKey: clientApiKey,
|
||||
cloudId,
|
||||
ingestPipeline: selectedPipeline,
|
||||
|
@ -167,7 +165,10 @@ export const ElasticsearchOverview = () => {
|
|||
bottomBorder="extended"
|
||||
data-test-subj="cloud-details-section"
|
||||
>
|
||||
<CloudDetailsPanel cloudId={cloud.cloudId} elasticsearchUrl={cloud.elasticsearchUrl} />
|
||||
<CloudDetailsPanel
|
||||
cloudId={cloud.cloudId}
|
||||
elasticsearchUrl={elasticsearchUrl || undefined}
|
||||
/>
|
||||
</EuiPageTemplate.Section>
|
||||
<EuiPageTemplate.Section
|
||||
color="subdued"
|
||||
|
|
|
@ -5,11 +5,18 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { ELASTICSEARCH_URL_PLACEHOLDER } from '../constants';
|
||||
import { useKibanaServices } from './use_kibana';
|
||||
|
||||
export const useElasticsearchUrl = () => {
|
||||
const { cloud } = useKibanaServices();
|
||||
const [elasticsearchUrl, setElasticsearchUrl] = useState<string>(ELASTICSEARCH_URL_PLACEHOLDER);
|
||||
useEffect(() => {
|
||||
cloud?.fetchElasticsearchConfig().then((config) => {
|
||||
setElasticsearchUrl(config.elasticsearchUrl || ELASTICSEARCH_URL_PLACEHOLDER);
|
||||
});
|
||||
});
|
||||
|
||||
return { elasticsearchUrl: cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER };
|
||||
return { elasticsearchUrl };
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue