mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[Cloud] ES endpoint discovery (#167122)
This commit is contained in:
parent
b90b2114a0
commit
92a92fff67
36 changed files with 662 additions and 198 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -67,6 +67,7 @@ packages/kbn-ci-stats-performance-metrics @elastic/kibana-operations
|
||||||
packages/kbn-ci-stats-reporter @elastic/kibana-operations
|
packages/kbn-ci-stats-reporter @elastic/kibana-operations
|
||||||
packages/kbn-ci-stats-shipper-cli @elastic/kibana-operations
|
packages/kbn-ci-stats-shipper-cli @elastic/kibana-operations
|
||||||
packages/kbn-cli-dev-mode @elastic/kibana-operations
|
packages/kbn-cli-dev-mode @elastic/kibana-operations
|
||||||
|
packages/cloud @elastic/kibana-core
|
||||||
x-pack/plugins/cloud_integrations/cloud_chat @elastic/kibana-core
|
x-pack/plugins/cloud_integrations/cloud_chat @elastic/kibana-core
|
||||||
x-pack/plugins/cloud_integrations/cloud_chat_provider @elastic/kibana-core
|
x-pack/plugins/cloud_integrations/cloud_chat_provider @elastic/kibana-core
|
||||||
x-pack/plugins/cloud_integrations/cloud_data_migration @elastic/platform-onboarding
|
x-pack/plugins/cloud_integrations/cloud_data_migration @elastic/platform-onboarding
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"customIntegrations": "src/plugins/custom_integrations",
|
"customIntegrations": "src/plugins/custom_integrations",
|
||||||
"customIntegrationsPackage": "packages/kbn-custom-integrations",
|
"customIntegrationsPackage": "packages/kbn-custom-integrations",
|
||||||
"dashboard": "src/plugins/dashboard",
|
"dashboard": "src/plugins/dashboard",
|
||||||
|
"cloud": "packages/cloud",
|
||||||
"domDragDrop": "packages/kbn-dom-drag-drop",
|
"domDragDrop": "packages/kbn-dom-drag-drop",
|
||||||
"controls": "src/plugins/controls",
|
"controls": "src/plugins/controls",
|
||||||
"data": "src/plugins/data",
|
"data": "src/plugins/data",
|
||||||
|
|
|
@ -54,8 +54,9 @@ Details for each programming language library that Elastic provides are in the
|
||||||
https://www.elastic.co/guide/en/elasticsearch/client/index.html[{es} Client documentation].
|
https://www.elastic.co/guide/en/elasticsearch/client/index.html[{es} Client documentation].
|
||||||
|
|
||||||
If you are running {kib} on our hosted {es} Service,
|
If you are running {kib} on our hosted {es} Service,
|
||||||
click *View deployment details* on the *Integrations* view
|
click *Endpoints* on the *Integrations* view
|
||||||
to verify your {es} endpoint and Cloud ID, and create API keys for integration.
|
to verify your {es} endpoint and Cloud ID, and create API keys for integration.
|
||||||
|
Alternatively, the *Endpoints* are also accessible through the top bar help menu.
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
=== Add sample data
|
=== Add sample data
|
||||||
|
|
|
@ -173,6 +173,7 @@
|
||||||
"@kbn/chart-expressions-common": "link:src/plugins/chart_expressions/common",
|
"@kbn/chart-expressions-common": "link:src/plugins/chart_expressions/common",
|
||||||
"@kbn/chart-icons": "link:packages/kbn-chart-icons",
|
"@kbn/chart-icons": "link:packages/kbn-chart-icons",
|
||||||
"@kbn/charts-plugin": "link:src/plugins/charts",
|
"@kbn/charts-plugin": "link:src/plugins/charts",
|
||||||
|
"@kbn/cloud": "link:packages/cloud",
|
||||||
"@kbn/cloud-chat-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat",
|
"@kbn/cloud-chat-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat",
|
||||||
"@kbn/cloud-chat-provider-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat_provider",
|
"@kbn/cloud-chat-provider-plugin": "link:x-pack/plugins/cloud_integrations/cloud_chat_provider",
|
||||||
"@kbn/cloud-data-migration-plugin": "link:x-pack/plugins/cloud_integrations/cloud_data_migration",
|
"@kbn/cloud-data-migration-plugin": "link:x-pack/plugins/cloud_integrations/cloud_data_migration",
|
||||||
|
|
3
packages/cloud/README.md
Normal file
3
packages/cloud/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# @kbn/cloud
|
||||||
|
|
||||||
|
Empty package generated by @kbn/generate
|
81
packages/cloud/deployment_details/deployment_details.tsx
Normal file
81
packages/cloud/deployment_details/deployment_details.tsx
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
EuiForm,
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
EuiLink,
|
||||||
|
EuiButtonEmpty,
|
||||||
|
EuiSpacer,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { useDeploymentDetails } from './services';
|
||||||
|
import { DeploymentDetailsEsInput } from './deployment_details_es_input';
|
||||||
|
import { DeploymentDetailsCloudIdInput } from './deployment_details_cloudid_input';
|
||||||
|
|
||||||
|
const hasActiveModifierKey = (event: React.MouseEvent): boolean => {
|
||||||
|
return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DeploymentDetails = ({ closeModal }: { closeModal?: () => void }) => {
|
||||||
|
const { cloudId, elasticsearchUrl, managementUrl, learnMoreUrl, navigateToUrl } =
|
||||||
|
useDeploymentDetails();
|
||||||
|
const isInsideModal = !!closeModal;
|
||||||
|
|
||||||
|
if (!cloudId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EuiForm component="div">
|
||||||
|
{/* Elastic endpoint */}
|
||||||
|
{elasticsearchUrl && <DeploymentDetailsEsInput elasticsearchUrl={elasticsearchUrl} />}
|
||||||
|
|
||||||
|
{/* Cloud ID */}
|
||||||
|
<DeploymentDetailsCloudIdInput cloudId={cloudId} />
|
||||||
|
|
||||||
|
<EuiSpacer size="m" />
|
||||||
|
|
||||||
|
{managementUrl && (
|
||||||
|
<EuiFlexGroup gutterSize="m" justifyContent="spaceBetween" alignItems="center">
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
|
||||||
|
<EuiButtonEmpty
|
||||||
|
href={managementUrl}
|
||||||
|
onClick={(e: React.MouseEvent) => {
|
||||||
|
if (!hasActiveModifierKey(e)) {
|
||||||
|
e.preventDefault();
|
||||||
|
navigateToUrl(managementUrl);
|
||||||
|
}
|
||||||
|
if (closeModal) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
flush="left"
|
||||||
|
>
|
||||||
|
{i18n.translate('cloud.deploymentDetails.createManageApiKeysButtonLabel', {
|
||||||
|
defaultMessage: 'Create and manage API keys',
|
||||||
|
})}
|
||||||
|
</EuiButtonEmpty>
|
||||||
|
</EuiFlexItem>
|
||||||
|
{!isInsideModal && (
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiLink external href={learnMoreUrl} target="_blank">
|
||||||
|
{i18n.translate('cloud.deploymentDetails.learnMoreButtonLabel', {
|
||||||
|
defaultMessage: 'Learn more',
|
||||||
|
})}
|
||||||
|
</EuiLink>
|
||||||
|
</EuiFlexItem>
|
||||||
|
)}
|
||||||
|
</EuiFlexGroup>
|
||||||
|
)}
|
||||||
|
</EuiForm>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
import React, { type FC } from 'react';
|
||||||
|
import {
|
||||||
|
EuiFormRow,
|
||||||
|
EuiFieldText,
|
||||||
|
EuiCopy,
|
||||||
|
EuiButtonIcon,
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
export const DeploymentDetailsCloudIdInput: FC<{ cloudId: string }> = ({ cloudId }) => {
|
||||||
|
return (
|
||||||
|
<EuiFormRow
|
||||||
|
label={i18n.translate('cloud.deploymentDetails.cloudIDLabel', {
|
||||||
|
defaultMessage: 'Cloud ID',
|
||||||
|
})}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<EuiFlexGroup gutterSize="s">
|
||||||
|
<EuiFlexItem>
|
||||||
|
<EuiFieldText
|
||||||
|
value={cloudId}
|
||||||
|
fullWidth
|
||||||
|
disabled
|
||||||
|
data-test-subj="deploymentDetailsCloudID"
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiCopy textToCopy={cloudId}>
|
||||||
|
{(copy) => (
|
||||||
|
<EuiButtonIcon onClick={copy} iconType="copyClipboard" display="base" size="m" />
|
||||||
|
)}
|
||||||
|
</EuiCopy>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFormRow>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
import React, { type FC } from 'react';
|
||||||
|
import {
|
||||||
|
EuiFormRow,
|
||||||
|
EuiFieldText,
|
||||||
|
EuiCopy,
|
||||||
|
EuiButtonIcon,
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
export const DeploymentDetailsEsInput: FC<{ elasticsearchUrl: string }> = ({
|
||||||
|
elasticsearchUrl,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<EuiFormRow
|
||||||
|
label={i18n.translate('cloud.deploymentDetails.elasticEndpointLabel', {
|
||||||
|
defaultMessage: 'Elastic endpoint',
|
||||||
|
})}
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<EuiFlexGroup gutterSize="s">
|
||||||
|
<EuiFlexItem>
|
||||||
|
<EuiFieldText
|
||||||
|
value={elasticsearchUrl}
|
||||||
|
fullWidth
|
||||||
|
disabled
|
||||||
|
data-test-subj="deploymentDetailsEsEndpoint"
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiCopy textToCopy={elasticsearchUrl}>
|
||||||
|
{(copy) => (
|
||||||
|
<EuiButtonIcon onClick={copy} iconType="copyClipboard" display="base" size="m" />
|
||||||
|
)}
|
||||||
|
</EuiCopy>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFormRow>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
import React, { type FC } from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import {
|
||||||
|
EuiButton,
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
EuiLink,
|
||||||
|
EuiModal,
|
||||||
|
EuiModalBody,
|
||||||
|
EuiModalFooter,
|
||||||
|
EuiModalHeader,
|
||||||
|
EuiModalHeaderTitle,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { useDeploymentDetails } from './services';
|
||||||
|
import { DeploymentDetails } from './deployment_details';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
closeModal: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DeploymentDetailsModal: FC<Props> = ({ closeModal }) => {
|
||||||
|
const { learnMoreUrl } = useDeploymentDetails();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EuiModal
|
||||||
|
onClose={() => {
|
||||||
|
closeModal();
|
||||||
|
}}
|
||||||
|
style={{ width: 600 }}
|
||||||
|
data-test-subj="deploymentDetailsModal"
|
||||||
|
>
|
||||||
|
<EuiModalHeader>
|
||||||
|
<EuiModalHeaderTitle>
|
||||||
|
{i18n.translate('cloud.deploymentDetails.helpMenuLinks.endpoints', {
|
||||||
|
defaultMessage: 'Endpoints',
|
||||||
|
})}
|
||||||
|
</EuiModalHeaderTitle>
|
||||||
|
</EuiModalHeader>
|
||||||
|
<EuiModalBody>
|
||||||
|
<DeploymentDetails closeModal={closeModal} />
|
||||||
|
</EuiModalBody>
|
||||||
|
<EuiModalFooter>
|
||||||
|
<EuiFlexGroup alignItems="baseline" justifyContent="flexEnd">
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiLink external href={learnMoreUrl} target="_blank">
|
||||||
|
{i18n.translate('cloud.deploymentDetails.modal.learnMoreButtonLabel', {
|
||||||
|
defaultMessage: 'Learn more',
|
||||||
|
})}
|
||||||
|
</EuiLink>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiButton onClick={closeModal} fill>
|
||||||
|
{i18n.translate('cloud.deploymentDetails.modal.closeButtonLabel', {
|
||||||
|
defaultMessage: 'Close',
|
||||||
|
})}
|
||||||
|
</EuiButton>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiModalFooter>
|
||||||
|
</EuiModal>
|
||||||
|
);
|
||||||
|
};
|
11
packages/cloud/deployment_details/index.ts
Normal file
11
packages/cloud/deployment_details/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { DeploymentDetailsKibanaProvider, DeploymentDetailsProvider } from './services';
|
||||||
|
export { DeploymentDetails } from './deployment_details';
|
||||||
|
export { DeploymentDetailsModal } from './deployment_details_modal';
|
123
packages/cloud/deployment_details/services.tsx
Normal file
123
packages/cloud/deployment_details/services.tsx
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FC, useContext } from 'react';
|
||||||
|
|
||||||
|
export interface DeploymentDetailsContextValue {
|
||||||
|
cloudId?: string;
|
||||||
|
elasticsearchUrl?: string;
|
||||||
|
managementUrl?: string;
|
||||||
|
learnMoreUrl: string;
|
||||||
|
navigateToUrl(url: string): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeploymentDetailsContext = React.createContext<DeploymentDetailsContextValue | null>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract external service Provider.
|
||||||
|
*/
|
||||||
|
export const DeploymentDetailsProvider: FC<DeploymentDetailsContextValue> = ({
|
||||||
|
children,
|
||||||
|
...services
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<DeploymentDetailsContext.Provider value={services}>
|
||||||
|
{children}
|
||||||
|
</DeploymentDetailsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kibana-specific service types.
|
||||||
|
*/
|
||||||
|
export interface DeploymentDetailsKibanaDependencies {
|
||||||
|
/** CoreStart contract */
|
||||||
|
core: {
|
||||||
|
application: {
|
||||||
|
navigateToUrl(url: string): Promise<void>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** SharePluginStart contract */
|
||||||
|
share: {
|
||||||
|
url: {
|
||||||
|
locators: {
|
||||||
|
get(
|
||||||
|
id: string
|
||||||
|
): undefined | { useUrl: (params: { sectionId: string; appId: string }) => string };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** CloudSetup contract */
|
||||||
|
cloud: {
|
||||||
|
isCloudEnabled: boolean;
|
||||||
|
cloudId?: string;
|
||||||
|
elasticsearchUrl?: string;
|
||||||
|
};
|
||||||
|
/** DocLinksStart contract */
|
||||||
|
docLinks: {
|
||||||
|
links: {
|
||||||
|
fleet: {
|
||||||
|
apiKeysLearnMore: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kibana-specific Provider that maps to known dependency types.
|
||||||
|
*/
|
||||||
|
export const DeploymentDetailsKibanaProvider: FC<DeploymentDetailsKibanaDependencies> = ({
|
||||||
|
children,
|
||||||
|
...services
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
core: {
|
||||||
|
application: { navigateToUrl },
|
||||||
|
},
|
||||||
|
cloud: { isCloudEnabled, cloudId, elasticsearchUrl },
|
||||||
|
share: {
|
||||||
|
url: { locators },
|
||||||
|
},
|
||||||
|
docLinks: {
|
||||||
|
links: {
|
||||||
|
fleet: { apiKeysLearnMore },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} = services;
|
||||||
|
|
||||||
|
const managementUrl = locators
|
||||||
|
.get('MANAGEMENT_APP_LOCATOR')
|
||||||
|
?.useUrl({ sectionId: 'security', appId: 'api_keys' });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DeploymentDetailsProvider
|
||||||
|
cloudId={isCloudEnabled ? cloudId : undefined}
|
||||||
|
elasticsearchUrl={elasticsearchUrl}
|
||||||
|
managementUrl={managementUrl}
|
||||||
|
learnMoreUrl={apiKeysLearnMore}
|
||||||
|
navigateToUrl={navigateToUrl}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</DeploymentDetailsProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React hook for accessing pre-wired services.
|
||||||
|
*/
|
||||||
|
export function useDeploymentDetails() {
|
||||||
|
const context = useContext(DeploymentDetailsContext);
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
throw new Error(
|
||||||
|
'DeploymentDetailsContext is missing. Ensure your component or React root is wrapped with <DeploymentDetailsProvider /> or <DeploymentDetailsKibanaProvider />.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
13
packages/cloud/jest.config.js
Normal file
13
packages/cloud/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preset: '@kbn/test',
|
||||||
|
rootDir: '../..',
|
||||||
|
roots: ['<rootDir>/packages/cloud'],
|
||||||
|
};
|
5
packages/cloud/kibana.jsonc
Normal file
5
packages/cloud/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type": "shared-common",
|
||||||
|
"id": "@kbn/cloud",
|
||||||
|
"owner": "@elastic/kibana-core"
|
||||||
|
}
|
6
packages/cloud/package.json
Normal file
6
packages/cloud/package.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "@kbn/cloud",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||||
|
}
|
21
packages/cloud/tsconfig.json
Normal file
21
packages/cloud/tsconfig.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "target/types",
|
||||||
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node",
|
||||||
|
"react"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"target/**/*"
|
||||||
|
],
|
||||||
|
"kbn_references": [
|
||||||
|
"@kbn/i18n",
|
||||||
|
]
|
||||||
|
}
|
|
@ -67,6 +67,7 @@ const buildDefaultContentLinks = ({
|
||||||
defaultMessage: 'Open an issue in GitHub',
|
defaultMessage: 'Open an issue in GitHub',
|
||||||
}),
|
}),
|
||||||
href: docLinks.links.kibana.createGithubIssue,
|
href: docLinks.links.kibana.createGithubIssue,
|
||||||
|
iconType: 'logoGithub',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -201,17 +202,40 @@ export class HeaderHelpMenu extends Component<Props, State> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{defaultContentLinks.map(({ href, title, iconType }, i) => {
|
{defaultContentLinks.map(
|
||||||
|
({ href, title, iconType, onClick: _onClick, dataTestSubj }, i) => {
|
||||||
const isLast = i === defaultContentLinks.length - 1;
|
const isLast = i === defaultContentLinks.length - 1;
|
||||||
|
|
||||||
|
if (href && _onClick) {
|
||||||
|
throw new Error(
|
||||||
|
'Only one of `href` and `onClick` should be provided for the help menu link.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hrefProps = href ? { href, target: '_blank' } : {};
|
||||||
|
const onClick = () => {
|
||||||
|
if (!_onClick) return;
|
||||||
|
_onClick();
|
||||||
|
this.closeMenu();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={i}>
|
<Fragment key={i}>
|
||||||
<EuiButtonEmpty href={href} target="_blank" size="s" flush="left" iconType={iconType}>
|
<EuiButtonEmpty
|
||||||
|
{...hrefProps}
|
||||||
|
onClick={onClick}
|
||||||
|
size="s"
|
||||||
|
flush="left"
|
||||||
|
iconType={iconType}
|
||||||
|
data-test-subj={dataTestSubj}
|
||||||
|
>
|
||||||
{title}
|
{title}
|
||||||
</EuiButtonEmpty>
|
</EuiButtonEmpty>
|
||||||
{!isLast && <EuiSpacer size="xs" />}
|
{!isLast && <EuiSpacer size="xs" />}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,10 @@ export interface ChromeNavControl {
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface ChromeHelpMenuLink {
|
export interface ChromeHelpMenuLink {
|
||||||
title: string;
|
title: string;
|
||||||
href: string;
|
href?: string;
|
||||||
iconType?: string;
|
iconType?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
dataTestSubj?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -128,6 +128,8 @@
|
||||||
"@kbn/ci-stats-shipper-cli/*": ["packages/kbn-ci-stats-shipper-cli/*"],
|
"@kbn/ci-stats-shipper-cli/*": ["packages/kbn-ci-stats-shipper-cli/*"],
|
||||||
"@kbn/cli-dev-mode": ["packages/kbn-cli-dev-mode"],
|
"@kbn/cli-dev-mode": ["packages/kbn-cli-dev-mode"],
|
||||||
"@kbn/cli-dev-mode/*": ["packages/kbn-cli-dev-mode/*"],
|
"@kbn/cli-dev-mode/*": ["packages/kbn-cli-dev-mode/*"],
|
||||||
|
"@kbn/cloud": ["packages/cloud"],
|
||||||
|
"@kbn/cloud/*": ["packages/cloud/*"],
|
||||||
"@kbn/cloud-chat-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat"],
|
"@kbn/cloud-chat-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat"],
|
||||||
"@kbn/cloud-chat-plugin/*": ["x-pack/plugins/cloud_integrations/cloud_chat/*"],
|
"@kbn/cloud-chat-plugin/*": ["x-pack/plugins/cloud_integrations/cloud_chat/*"],
|
||||||
"@kbn/cloud-chat-provider-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat_provider"],
|
"@kbn/cloud-chat-provider-plugin": ["x-pack/plugins/cloud_integrations/cloud_chat_provider"],
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
],
|
],
|
||||||
"requiredBundles": [
|
"requiredBundles": [
|
||||||
"kibanaReact"
|
"kibanaReact"
|
||||||
|
],
|
||||||
|
"requiredPlugins": [
|
||||||
|
"share"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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 React from 'react';
|
||||||
|
import type { CoreStart } from '@kbn/core/public';
|
||||||
|
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
||||||
|
import type { CloudStart } from '@kbn/cloud-plugin/public';
|
||||||
|
import type { SharePluginStart } from '@kbn/share-plugin/public';
|
||||||
|
import {
|
||||||
|
DeploymentDetailsKibanaProvider,
|
||||||
|
DeploymentDetailsModal,
|
||||||
|
} from '@kbn/cloud/deployment_details';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
closeModal: () => void;
|
||||||
|
core: CoreStart;
|
||||||
|
docLinks: DocLinksStart;
|
||||||
|
cloud: CloudStart;
|
||||||
|
share: SharePluginStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EndpointsModal = ({ core, share, cloud, docLinks, closeModal }: Props) => {
|
||||||
|
return (
|
||||||
|
<DeploymentDetailsKibanaProvider core={core} share={share} cloud={cloud} docLinks={docLinks}>
|
||||||
|
<DeploymentDetailsModal closeModal={closeModal} />
|
||||||
|
</DeploymentDetailsKibanaProvider>
|
||||||
|
);
|
||||||
|
};
|
|
@ -4,17 +4,32 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
import React from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { ChromeHelpMenuLink } from '@kbn/core-chrome-browser';
|
import { ChromeHelpMenuLink } from '@kbn/core-chrome-browser';
|
||||||
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
||||||
|
import type { CoreStart } from '@kbn/core/public';
|
||||||
|
import type { CloudStart } from '@kbn/cloud-plugin/public';
|
||||||
|
import type { SharePluginStart } from '@kbn/share-plugin/public';
|
||||||
|
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||||
|
|
||||||
|
import { EndpointsModal } from './endpoints_modal';
|
||||||
|
|
||||||
export const createHelpMenuLinks = ({
|
export const createHelpMenuLinks = ({
|
||||||
docLinks,
|
docLinks,
|
||||||
helpSupportUrl,
|
helpSupportUrl,
|
||||||
|
core,
|
||||||
|
cloud,
|
||||||
|
share,
|
||||||
}: {
|
}: {
|
||||||
docLinks: DocLinksStart;
|
docLinks: DocLinksStart;
|
||||||
|
core: CoreStart;
|
||||||
|
cloud: CloudStart;
|
||||||
|
share: SharePluginStart;
|
||||||
helpSupportUrl: string;
|
helpSupportUrl: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
const { overlays } = core;
|
||||||
|
|
||||||
const helpMenuLinks: ChromeHelpMenuLink[] = [
|
const helpMenuLinks: ChromeHelpMenuLink[] = [
|
||||||
{
|
{
|
||||||
title: i18n.translate('xpack.cloudLinks.helpMenuLinks.documentation', {
|
title: i18n.translate('xpack.cloudLinks.helpMenuLinks.documentation', {
|
||||||
|
@ -34,6 +49,27 @@ export const createHelpMenuLinks = ({
|
||||||
}),
|
}),
|
||||||
href: docLinks.links.kibana.feedback,
|
href: docLinks.links.kibana.feedback,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18n.translate('xpack.cloudLinks.helpMenuLinks.endpoints', {
|
||||||
|
defaultMessage: 'Endpoints',
|
||||||
|
}),
|
||||||
|
iconType: 'console',
|
||||||
|
dataTestSubj: 'endpointsHelpLink',
|
||||||
|
onClick: () => {
|
||||||
|
const modal = overlays.openModal(
|
||||||
|
toMountPoint(
|
||||||
|
<EndpointsModal
|
||||||
|
core={core}
|
||||||
|
share={share}
|
||||||
|
cloud={cloud}
|
||||||
|
docLinks={docLinks}
|
||||||
|
closeModal={() => modal.close()}
|
||||||
|
/>,
|
||||||
|
{ theme: core.theme, i18n: core.i18n }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return helpMenuLinks;
|
return helpMenuLinks;
|
|
@ -8,6 +8,7 @@
|
||||||
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
|
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
|
||||||
import { coreMock } from '@kbn/core/public/mocks';
|
import { coreMock } from '@kbn/core/public/mocks';
|
||||||
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
||||||
|
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||||
|
|
||||||
import { maybeAddCloudLinks } from './maybe_add_cloud_links';
|
import { maybeAddCloudLinks } from './maybe_add_cloud_links';
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ describe('maybeAddCloudLinks', () => {
|
||||||
maybeAddCloudLinks({
|
maybeAddCloudLinks({
|
||||||
core,
|
core,
|
||||||
security,
|
security,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
cloud: { ...cloudMock.createStart(), isCloudEnabled: false },
|
cloud: { ...cloudMock.createStart(), isCloudEnabled: false },
|
||||||
});
|
});
|
||||||
// Since there's a promise, let's wait for the next tick
|
// Since there's a promise, let's wait for the next tick
|
||||||
|
@ -35,6 +37,7 @@ describe('maybeAddCloudLinks', () => {
|
||||||
maybeAddCloudLinks({
|
maybeAddCloudLinks({
|
||||||
security,
|
security,
|
||||||
core,
|
core,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
||||||
});
|
});
|
||||||
// Since there's a promise, let's wait for the next tick
|
// Since there's a promise, let's wait for the next tick
|
||||||
|
@ -90,6 +93,12 @@ describe('maybeAddCloudLinks', () => {
|
||||||
"href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback",
|
"href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback",
|
||||||
"title": "Give feedback",
|
"title": "Give feedback",
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"dataTestSubj": "endpointsHelpLink",
|
||||||
|
"iconType": "console",
|
||||||
|
"onClick": [Function],
|
||||||
|
"title": "Endpoints",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
|
@ -103,6 +112,7 @@ describe('maybeAddCloudLinks', () => {
|
||||||
maybeAddCloudLinks({
|
maybeAddCloudLinks({
|
||||||
security,
|
security,
|
||||||
core,
|
core,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
||||||
});
|
});
|
||||||
// Since there's a promise, let's wait for the next tick
|
// Since there's a promise, let's wait for the next tick
|
||||||
|
@ -157,6 +167,12 @@ describe('maybeAddCloudLinks', () => {
|
||||||
"href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback",
|
"href": "https://www.elastic.co/products/kibana/feedback?blade=kibanafeedback",
|
||||||
"title": "Give feedback",
|
"title": "Give feedback",
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"dataTestSubj": "endpointsHelpLink",
|
||||||
|
"iconType": "console",
|
||||||
|
"onClick": [Function],
|
||||||
|
"title": "Endpoints",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
|
@ -172,6 +188,7 @@ describe('maybeAddCloudLinks', () => {
|
||||||
maybeAddCloudLinks({
|
maybeAddCloudLinks({
|
||||||
security,
|
security,
|
||||||
core,
|
core,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
cloud: { ...cloudMock.createStart(), isCloudEnabled: true },
|
||||||
});
|
});
|
||||||
// Since there's a promise, let's wait for the next tick
|
// Since there's a promise, let's wait for the next tick
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n';
|
||||||
import type { CloudStart } from '@kbn/cloud-plugin/public';
|
import type { CloudStart } from '@kbn/cloud-plugin/public';
|
||||||
import type { CoreStart } from '@kbn/core/public';
|
import type { CoreStart } from '@kbn/core/public';
|
||||||
import type { SecurityPluginStart } from '@kbn/security-plugin/public';
|
import type { SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||||
|
import type { SharePluginStart } from '@kbn/share-plugin/public';
|
||||||
import { createUserMenuLinks } from './user_menu_links';
|
import { createUserMenuLinks } from './user_menu_links';
|
||||||
import { createHelpMenuLinks } from './help_menu_links';
|
import { createHelpMenuLinks } from './help_menu_links';
|
||||||
|
|
||||||
|
@ -18,9 +19,10 @@ export interface MaybeAddCloudLinksDeps {
|
||||||
core: CoreStart;
|
core: CoreStart;
|
||||||
security: SecurityPluginStart;
|
security: SecurityPluginStart;
|
||||||
cloud: CloudStart;
|
cloud: CloudStart;
|
||||||
|
share: SharePluginStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function maybeAddCloudLinks({ core, security, cloud }: MaybeAddCloudLinksDeps): void {
|
export function maybeAddCloudLinks({ core, security, cloud, share }: MaybeAddCloudLinksDeps): void {
|
||||||
const userObservable = defer(() => security.authc.getCurrentUser()).pipe(
|
const userObservable = defer(() => security.authc.getCurrentUser()).pipe(
|
||||||
// Check if user is a cloud user.
|
// Check if user is a cloud user.
|
||||||
map((user) => user.elastic_cloud_user),
|
map((user) => user.elastic_cloud_user),
|
||||||
|
@ -54,6 +56,9 @@ export function maybeAddCloudLinks({ core, security, cloud }: MaybeAddCloudLinks
|
||||||
const helpMenuLinks = createHelpMenuLinks({
|
const helpMenuLinks = createHelpMenuLinks({
|
||||||
docLinks: core.docLinks,
|
docLinks: core.docLinks,
|
||||||
helpSupportUrl,
|
helpSupportUrl,
|
||||||
|
core,
|
||||||
|
share,
|
||||||
|
cloud,
|
||||||
});
|
});
|
||||||
|
|
||||||
core.chrome.setHelpMenuLinks(helpMenuLinks);
|
core.chrome.setHelpMenuLinks(helpMenuLinks);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { coreMock } from '@kbn/core/public/mocks';
|
||||||
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
|
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
|
||||||
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
import { securityMock } from '@kbn/security-plugin/public/mocks';
|
||||||
import { guidedOnboardingMock } from '@kbn/guided-onboarding-plugin/public/mocks';
|
import { guidedOnboardingMock } from '@kbn/guided-onboarding-plugin/public/mocks';
|
||||||
|
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
|
||||||
|
|
||||||
describe('Cloud Links Plugin - public', () => {
|
describe('Cloud Links Plugin - public', () => {
|
||||||
let plugin: CloudLinksPlugin;
|
let plugin: CloudLinksPlugin;
|
||||||
|
@ -40,7 +41,11 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
|
|
||||||
plugin.start(coreStart, { cloud, guidedOnboarding });
|
plugin.start(coreStart, {
|
||||||
|
cloud,
|
||||||
|
guidedOnboarding,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
|
});
|
||||||
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).toHaveBeenCalledTimes(1);
|
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,14 +53,22 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
const coreStart = coreMock.createStart();
|
const coreStart = coreMock.createStart();
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
plugin.start(coreStart, { cloud, guidedOnboarding });
|
plugin.start(coreStart, {
|
||||||
|
cloud,
|
||||||
|
guidedOnboarding,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
|
});
|
||||||
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not register the Onboarding Setup Guide link when cloud is not enabled', () => {
|
test('does not register the Onboarding Setup Guide link when cloud is not enabled', () => {
|
||||||
const coreStart = coreMock.createStart();
|
const coreStart = coreMock.createStart();
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: false };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: false };
|
||||||
plugin.start(coreStart, { cloud, guidedOnboarding });
|
plugin.start(coreStart, {
|
||||||
|
cloud,
|
||||||
|
guidedOnboarding,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
|
});
|
||||||
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -72,7 +85,11 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
|
|
||||||
plugin.start(coreStart, { cloud, guidedOnboarding });
|
plugin.start(coreStart, {
|
||||||
|
cloud,
|
||||||
|
guidedOnboarding,
|
||||||
|
share: sharePluginMock.createStartContract(),
|
||||||
|
});
|
||||||
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -83,7 +100,7 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
const security = securityMock.createStart();
|
const security = securityMock.createStart();
|
||||||
plugin.start(coreStart, { cloud, security });
|
plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() });
|
||||||
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(1);
|
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -91,7 +108,7 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
const coreStart = coreMock.createStart();
|
const coreStart = coreMock.createStart();
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
plugin.start(coreStart, { cloud });
|
plugin.start(coreStart, { cloud, share: sharePluginMock.createStartContract() });
|
||||||
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -100,7 +117,7 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: true };
|
||||||
const security = securityMock.createStart();
|
const security = securityMock.createStart();
|
||||||
plugin.start(coreStart, { cloud, security });
|
plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() });
|
||||||
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,7 +125,7 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
const coreStart = coreMock.createStart();
|
const coreStart = coreMock.createStart();
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const security = securityMock.createStart();
|
const security = securityMock.createStart();
|
||||||
plugin.start(coreStart, { security });
|
plugin.start(coreStart, { security, share: sharePluginMock.createStartContract() });
|
||||||
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -117,7 +134,7 @@ describe('Cloud Links Plugin - public', () => {
|
||||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false);
|
||||||
const cloud = { ...cloudMock.createStart(), isCloudEnabled: false };
|
const cloud = { ...cloudMock.createStart(), isCloudEnabled: false };
|
||||||
const security = securityMock.createStart();
|
const security = securityMock.createStart();
|
||||||
plugin.start(coreStart, { cloud, security });
|
plugin.start(coreStart, { cloud, security, share: sharePluginMock.createStartContract() });
|
||||||
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,7 @@ import type { CoreStart, Plugin } from '@kbn/core/public';
|
||||||
import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public';
|
import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public';
|
||||||
import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public';
|
import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||||
import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public';
|
import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public';
|
||||||
|
import type { SharePluginStart } from '@kbn/share-plugin/public';
|
||||||
import { maybeAddCloudLinks } from './maybe_add_cloud_links';
|
import { maybeAddCloudLinks } from './maybe_add_cloud_links';
|
||||||
|
|
||||||
interface CloudLinksDepsSetup {
|
interface CloudLinksDepsSetup {
|
||||||
|
@ -21,6 +22,7 @@ interface CloudLinksDepsSetup {
|
||||||
interface CloudLinksDepsStart {
|
interface CloudLinksDepsStart {
|
||||||
cloud?: CloudStart;
|
cloud?: CloudStart;
|
||||||
security?: SecurityPluginStart;
|
security?: SecurityPluginStart;
|
||||||
|
share: SharePluginStart;
|
||||||
guidedOnboarding?: GuidedOnboardingPluginStart;
|
guidedOnboarding?: GuidedOnboardingPluginStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +31,7 @@ export class CloudLinksPlugin
|
||||||
{
|
{
|
||||||
public setup() {}
|
public setup() {}
|
||||||
|
|
||||||
public start(core: CoreStart, { cloud, security, guidedOnboarding }: CloudLinksDepsStart) {
|
public start(core: CoreStart, { cloud, security, guidedOnboarding, share }: CloudLinksDepsStart) {
|
||||||
if (cloud?.isCloudEnabled && !core.http.anonymousPaths.isAnonymous(window.location.pathname)) {
|
if (cloud?.isCloudEnabled && !core.http.anonymousPaths.isAnonymous(window.location.pathname)) {
|
||||||
if (guidedOnboarding?.guidedOnboardingApi?.isEnabled) {
|
if (guidedOnboarding?.guidedOnboardingApi?.isEnabled) {
|
||||||
core.chrome.registerGlobalHelpExtensionMenuLink({
|
core.chrome.registerGlobalHelpExtensionMenuLink({
|
||||||
|
@ -42,11 +44,13 @@ export class CloudLinksPlugin
|
||||||
priority: 1000, // We want this link to be at the very top.
|
priority: 1000, // We want this link to be at the very top.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security) {
|
if (security) {
|
||||||
maybeAddCloudLinks({
|
maybeAddCloudLinks({
|
||||||
core,
|
core,
|
||||||
security,
|
security,
|
||||||
cloud,
|
cloud,
|
||||||
|
share,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
"@kbn/user-profile-components",
|
"@kbn/user-profile-components",
|
||||||
"@kbn/core-lifecycle-browser",
|
"@kbn/core-lifecycle-browser",
|
||||||
"@kbn/kibana-react-plugin",
|
"@kbn/kibana-react-plugin",
|
||||||
|
"@kbn/share-plugin",
|
||||||
|
"@kbn/cloud",
|
||||||
|
"@kbn/react-kibana-mount",
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"target/**/*",
|
"target/**/*",
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 React from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
import {
|
|
||||||
EuiPopover,
|
|
||||||
EuiText,
|
|
||||||
EuiForm,
|
|
||||||
EuiFormRow,
|
|
||||||
EuiFieldText,
|
|
||||||
EuiCopy,
|
|
||||||
EuiButtonIcon,
|
|
||||||
EuiFlexGroup,
|
|
||||||
EuiFlexItem,
|
|
||||||
EuiButton,
|
|
||||||
EuiLink,
|
|
||||||
EuiHeaderLink,
|
|
||||||
} from '@elastic/eui';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
cloudId: string;
|
|
||||||
managementUrl?: string;
|
|
||||||
learnMoreUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Description = styled(EuiText)`
|
|
||||||
margin-bottom: ${({ theme }) => theme.eui.euiSizeL};
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const DeploymentDetails = ({ cloudId, learnMoreUrl, managementUrl }: Props) => {
|
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
|
||||||
|
|
||||||
const button = (
|
|
||||||
<EuiHeaderLink onClick={() => setIsOpen(!isOpen)} iconType="iInCircle" iconSide="left" isActive>
|
|
||||||
{i18n.translate('xpack.fleet.integrations.deploymentButton', {
|
|
||||||
defaultMessage: 'View deployment details',
|
|
||||||
})}
|
|
||||||
</EuiHeaderLink>
|
|
||||||
);
|
|
||||||
|
|
||||||
const management = managementUrl ? (
|
|
||||||
<EuiFormRow label="API keys" fullWidth>
|
|
||||||
<EuiFlexGroup gutterSize="m" alignItems="center">
|
|
||||||
<EuiFlexItem>
|
|
||||||
<EuiButton href={managementUrl}>Create and manage API keys</EuiButton>
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem>
|
|
||||||
<EuiLink external href={learnMoreUrl} target="_blank">
|
|
||||||
Learn more
|
|
||||||
</EuiLink>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
</EuiFormRow>
|
|
||||||
) : null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EuiPopover
|
|
||||||
isOpen={isOpen}
|
|
||||||
closePopover={() => setIsOpen(false)}
|
|
||||||
button={button}
|
|
||||||
anchorPosition="downCenter"
|
|
||||||
>
|
|
||||||
<div style={{ width: 450 }}>
|
|
||||||
<Description>
|
|
||||||
{i18n.translate('xpack.fleet.integrations.deploymentDescription', {
|
|
||||||
defaultMessage:
|
|
||||||
'Send data to Elastic from your applications by referencing your deployment.',
|
|
||||||
})}
|
|
||||||
</Description>
|
|
||||||
<EuiForm component="div">
|
|
||||||
<EuiFormRow label="Cloud ID" fullWidth>
|
|
||||||
<EuiFlexGroup gutterSize="s">
|
|
||||||
<EuiFlexItem>
|
|
||||||
<EuiFieldText value={cloudId} fullWidth disabled />
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiCopy textToCopy={cloudId}>
|
|
||||||
{(copy) => (
|
|
||||||
<EuiButtonIcon
|
|
||||||
onClick={copy}
|
|
||||||
iconType="copyClipboard"
|
|
||||||
display="base"
|
|
||||||
size="m"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</EuiCopy>
|
|
||||||
</EuiFlexItem>
|
|
||||||
</EuiFlexGroup>
|
|
||||||
</EuiFormRow>
|
|
||||||
{management}
|
|
||||||
</EuiForm>
|
|
||||||
</div>
|
|
||||||
</EuiPopover>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 React from 'react';
|
|
||||||
import type { Meta } from '@storybook/react';
|
|
||||||
import { EuiHeader } from '@elastic/eui';
|
|
||||||
|
|
||||||
import { DeploymentDetails as ConnectedComponent } from './deployment_details';
|
|
||||||
import type { Props as PureComponentProps } from './deployment_details.component';
|
|
||||||
import { DeploymentDetails as PureComponent } from './deployment_details.component';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Sections/EPM/Deployment Details',
|
|
||||||
description: '',
|
|
||||||
decorators: [
|
|
||||||
(storyFn) => {
|
|
||||||
const sections = [{ items: [] }, { items: [storyFn()] }];
|
|
||||||
return <EuiHeader sections={sections} />;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as Meta;
|
|
||||||
|
|
||||||
export const DeploymentDetails = () => {
|
|
||||||
return <ConnectedComponent />;
|
|
||||||
};
|
|
||||||
|
|
||||||
DeploymentDetails.args = {
|
|
||||||
isCloudEnabled: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
DeploymentDetails.argTypes = {
|
|
||||||
isCloudEnabled: {
|
|
||||||
type: {
|
|
||||||
name: 'boolean',
|
|
||||||
},
|
|
||||||
defaultValue: true,
|
|
||||||
control: {
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Component = (props: PureComponentProps) => {
|
|
||||||
return <PureComponent {...props} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
Component.args = {
|
|
||||||
cloudId: 'cloud-id',
|
|
||||||
learnMoreUrl: 'https://learn-more-url',
|
|
||||||
managementUrl: 'https://management-url',
|
|
||||||
};
|
|
|
@ -6,13 +6,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { EuiPopover, EuiHeaderLink } from '@elastic/eui';
|
||||||
|
import {
|
||||||
|
DeploymentDetailsKibanaProvider,
|
||||||
|
DeploymentDetails as DeploymentDetailsComponent,
|
||||||
|
} from '@kbn/cloud/deployment_details';
|
||||||
|
|
||||||
import { useStartServices } from '../../hooks';
|
import { useStartServices } from '../../hooks';
|
||||||
|
|
||||||
import { DeploymentDetails as Component } from './deployment_details.component';
|
|
||||||
|
|
||||||
export const DeploymentDetails = () => {
|
export const DeploymentDetails = () => {
|
||||||
const { share, cloud, docLinks } = useStartServices();
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
|
const { share, cloud, docLinks, application } = useStartServices();
|
||||||
|
|
||||||
// If the cloud plugin isn't enabled, we can't display the flyout.
|
// If the cloud plugin isn't enabled, we can't display the flyout.
|
||||||
if (!cloud) {
|
if (!cloud) {
|
||||||
|
@ -21,16 +26,36 @@ export const DeploymentDetails = () => {
|
||||||
|
|
||||||
const { isCloudEnabled, cloudId } = cloud;
|
const { isCloudEnabled, cloudId } = cloud;
|
||||||
|
|
||||||
// If cloud isn't enabled or we don't have a cloudId we can't display the flyout.
|
// If cloud isn't enabled or we don't have a cloudId we don't render the button.
|
||||||
if (!isCloudEnabled || !cloudId) {
|
if (!isCloudEnabled || !cloudId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const managementUrl = share.url.locators
|
const button = (
|
||||||
.get('MANAGEMENT_APP_LOCATOR')
|
<EuiHeaderLink onClick={() => setIsOpen(!isOpen)} iconType="iInCircle" iconSide="left" isActive>
|
||||||
?.useUrl({ sectionId: 'security', appId: 'api_keys' });
|
{i18n.translate('xpack.fleet.integrations.endpointsButton', {
|
||||||
|
defaultMessage: 'Endpoints',
|
||||||
|
})}
|
||||||
|
</EuiHeaderLink>
|
||||||
|
);
|
||||||
|
|
||||||
const learnMoreUrl = docLinks.links.fleet.apiKeysLearnMore;
|
return (
|
||||||
|
<DeploymentDetailsKibanaProvider
|
||||||
return <Component {...{ cloudId, managementUrl, learnMoreUrl }} />;
|
core={{ application }}
|
||||||
|
share={share}
|
||||||
|
cloud={cloud}
|
||||||
|
docLinks={docLinks}
|
||||||
|
>
|
||||||
|
<EuiPopover
|
||||||
|
isOpen={isOpen}
|
||||||
|
closePopover={() => setIsOpen(false)}
|
||||||
|
button={button}
|
||||||
|
anchorPosition="downCenter"
|
||||||
|
>
|
||||||
|
<div style={{ width: 450 }}>
|
||||||
|
<DeploymentDetailsComponent />
|
||||||
|
</div>
|
||||||
|
</EuiPopover>
|
||||||
|
</DeploymentDetailsKibanaProvider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,5 +101,6 @@
|
||||||
"@kbn/core-saved-objects-base-server-internal",
|
"@kbn/core-saved-objects-base-server-internal",
|
||||||
"@kbn/core-http-common",
|
"@kbn/core-http-common",
|
||||||
"@kbn/dashboard-plugin",
|
"@kbn/dashboard-plugin",
|
||||||
|
"@kbn/cloud",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -16425,8 +16425,6 @@
|
||||||
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "Note",
|
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "Note",
|
||||||
"xpack.fleet.initializationErrorMessageTitle": "Initialisation de Fleet impossible",
|
"xpack.fleet.initializationErrorMessageTitle": "Initialisation de Fleet impossible",
|
||||||
"xpack.fleet.integrations.customInputsLink": "entrées personnalisées",
|
"xpack.fleet.integrations.customInputsLink": "entrées personnalisées",
|
||||||
"xpack.fleet.integrations.deploymentButton": "Voir les détails du déploiement",
|
|
||||||
"xpack.fleet.integrations.deploymentDescription": "Envoyez des données à Elastic à partir de vos applications en référençant votre déploiement.",
|
|
||||||
"xpack.fleet.integrations.discussForumLink": "forum",
|
"xpack.fleet.integrations.discussForumLink": "forum",
|
||||||
"xpack.fleet.integrations.installPackage.uploadedTooltip": "Cette intégration a été installée par le biais d'un chargement et ne peut pas être réinstallée automatiquement. Veuillez la charger à nouveau pour la réinstaller.",
|
"xpack.fleet.integrations.installPackage.uploadedTooltip": "Cette intégration a été installée par le biais d'un chargement et ne peut pas être réinstallée automatiquement. Veuillez la charger à nouveau pour la réinstaller.",
|
||||||
"xpack.fleet.integrations.integrationSaved": "Paramètres de l'intégration enregistrés",
|
"xpack.fleet.integrations.integrationSaved": "Paramètres de l'intégration enregistrés",
|
||||||
|
|
|
@ -16439,8 +16439,6 @@
|
||||||
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注",
|
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注",
|
||||||
"xpack.fleet.initializationErrorMessageTitle": "Fleet を初期化できません",
|
"xpack.fleet.initializationErrorMessageTitle": "Fleet を初期化できません",
|
||||||
"xpack.fleet.integrations.customInputsLink": "カスタム入力",
|
"xpack.fleet.integrations.customInputsLink": "カスタム入力",
|
||||||
"xpack.fleet.integrations.deploymentButton": "デプロイ詳細の表示",
|
|
||||||
"xpack.fleet.integrations.deploymentDescription": "デプロイを参照し、アプリケーションのデータをElasticに送信します。",
|
|
||||||
"xpack.fleet.integrations.discussForumLink": "フォーラム",
|
"xpack.fleet.integrations.discussForumLink": "フォーラム",
|
||||||
"xpack.fleet.integrations.installPackage.uploadedTooltip": "この統合はアップロードによってインストールされたため、自動的に再インストールできません。再インストールするには、もう一度アップロードしてください。",
|
"xpack.fleet.integrations.installPackage.uploadedTooltip": "この統合はアップロードによってインストールされたため、自動的に再インストールできません。再インストールするには、もう一度アップロードしてください。",
|
||||||
"xpack.fleet.integrations.integrationSaved": "統合設定が保存されました",
|
"xpack.fleet.integrations.integrationSaved": "統合設定が保存されました",
|
||||||
|
|
|
@ -16439,8 +16439,6 @@
|
||||||
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "备注",
|
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "备注",
|
||||||
"xpack.fleet.initializationErrorMessageTitle": "无法初始化 Fleet",
|
"xpack.fleet.initializationErrorMessageTitle": "无法初始化 Fleet",
|
||||||
"xpack.fleet.integrations.customInputsLink": "定制输入",
|
"xpack.fleet.integrations.customInputsLink": "定制输入",
|
||||||
"xpack.fleet.integrations.deploymentButton": "查看部署详情",
|
|
||||||
"xpack.fleet.integrations.deploymentDescription": "通过引用部署,将数据从应用程序发送到 Elastic。",
|
|
||||||
"xpack.fleet.integrations.discussForumLink": "论坛",
|
"xpack.fleet.integrations.discussForumLink": "论坛",
|
||||||
"xpack.fleet.integrations.installPackage.uploadedTooltip": "此集成通过上传进行安装,因此无法自动重新安装。请再次将其上传,以便重新安装。",
|
"xpack.fleet.integrations.installPackage.uploadedTooltip": "此集成通过上传进行安装,因此无法自动重新安装。请再次将其上传,以便重新安装。",
|
||||||
"xpack.fleet.integrations.integrationSaved": "已保存集成设置",
|
"xpack.fleet.integrations.integrationSaved": "已保存集成设置",
|
||||||
|
|
|
@ -44,7 +44,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||||
serverArgs: [
|
serverArgs: [
|
||||||
...functionalConfig.get('kbnTestServer.serverArgs'),
|
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||||
`--plugin-path=${samlIdPPlugin}`,
|
`--plugin-path=${samlIdPPlugin}`,
|
||||||
'--xpack.cloud.id=ftr_fake_cloud_id',
|
// Note: the base64 string in the cloud.id config contains the ES endpoint required in the functional tests
|
||||||
|
'--xpack.cloud.id=ftr_fake_cloud_id:aGVsbG8uY29tOjQ0MyRFUzEyM2FiYyRrYm4xMjNhYmM=',
|
||||||
'--xpack.cloud.base_url=https://cloud.elastic.co',
|
'--xpack.cloud.base_url=https://cloud.elastic.co',
|
||||||
'--xpack.cloud.deployment_url=/deployments/deploymentId',
|
'--xpack.cloud.deployment_url=/deployments/deploymentId',
|
||||||
'--xpack.cloud.organization_url=/organization/organizationId',
|
'--xpack.cloud.organization_url=/organization/organizationId',
|
||||||
|
|
|
@ -46,6 +46,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||||
await find.byCssSelector('[data-test-subj="cloudOnboardingSetupGuideLink"]')
|
await find.byCssSelector('[data-test-subj="cloudOnboardingSetupGuideLink"]')
|
||||||
).to.not.be(null);
|
).to.not.be(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('A button to open a modal to view the CloudID and ES endpoint is added', async () => {
|
||||||
|
await PageObjects.common.clickAndValidate('helpMenuButton', 'endpointsHelpLink');
|
||||||
|
expect(await find.byCssSelector('[data-test-subj="endpointsHelpLink"]')).to.not.be(null);
|
||||||
|
|
||||||
|
// Open the modal
|
||||||
|
await PageObjects.common.clickAndValidate('endpointsHelpLink', 'deploymentDetailsModal');
|
||||||
|
|
||||||
|
const esEndpointInput = await find.byCssSelector(
|
||||||
|
'[data-test-subj="deploymentDetailsEsEndpoint"]'
|
||||||
|
);
|
||||||
|
const esEndpointValue = await esEndpointInput.getAttribute('value');
|
||||||
|
expect(esEndpointValue).to.be('https://ES123abc.hello.com:443');
|
||||||
|
|
||||||
|
const cloudIdInput = await find.byCssSelector(
|
||||||
|
'[data-test-subj="deploymentDetailsCloudID"]'
|
||||||
|
);
|
||||||
|
const cloudIdInputValue = await cloudIdInput.getAttribute('value');
|
||||||
|
expect(cloudIdInputValue).to.be(
|
||||||
|
'ftr_fake_cloud_id:aGVsbG8uY29tOjQ0MyRFUzEyM2FiYyRrYm4xMjNhYmM='
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('"Manage this deployment" is appended to the nav list', async () => {
|
it('"Manage this deployment" is appended to the nav list', async () => {
|
||||||
|
|
|
@ -3243,6 +3243,10 @@
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
||||||
|
"@kbn/cloud@link:packages/cloud":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
"@kbn/code-editor-mocks@link:packages/shared-ux/code_editor/mocks":
|
"@kbn/code-editor-mocks@link:packages/shared-ux/code_editor/mocks":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue