[7.x] [Cloud] move cloud plugin to np (#51789) (#52289)

* merge conflicts with 7.x

* resolve conflict

* resolve eslint conflict
This commit is contained in:
Ahmad Bamieh 2019-12-05 13:59:35 -05:00 committed by GitHub
parent 15a425617b
commit 240dd1c520
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 471 additions and 294 deletions

View file

@ -39,6 +39,7 @@ export interface ChromeStart
| [setBrand(brand)](./kibana-plugin-public.chromestart.setbrand.md) | Set the brand configuration. |
| [setBreadcrumbs(newBreadcrumbs)](./kibana-plugin-public.chromestart.setbreadcrumbs.md) | Override the current set of breadcrumbs |
| [setHelpExtension(helpExtension)](./kibana-plugin-public.chromestart.sethelpextension.md) | Override the current set of custom help content |
| [setHelpSupportUrl(url)](./kibana-plugin-public.chromestart.sethelpsupporturl.md) | Override the default support URL shown in the help menu |
| [setIsCollapsed(isCollapsed)](./kibana-plugin-public.chromestart.setiscollapsed.md) | Set the collapsed state of the chrome navigation. |
| [setIsVisible(isVisible)](./kibana-plugin-public.chromestart.setisvisible.md) | Set the temporary visibility for the chrome. This does nothing if the chrome is hidden by default and should be used to hide the chrome for things like full-screen modes with an exit button. |

View file

@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-public](./kibana-plugin-public.md) &gt; [ChromeStart](./kibana-plugin-public.chromestart.md) &gt; [setHelpSupportUrl](./kibana-plugin-public.chromestart.sethelpsupporturl.md)
## ChromeStart.setHelpSupportUrl() method
Override the default support URL shown in the help menu
<b>Signature:</b>
```typescript
setHelpSupportUrl(url: string): void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| url | <code>string</code> | |
<b>Returns:</b>
`void`

View file

@ -72,6 +72,7 @@ const createStartContractMock = () => {
setBreadcrumbs: jest.fn(),
getHelpExtension$: jest.fn(),
setHelpExtension: jest.fn(),
setHelpSupportUrl: jest.fn(),
};
startContract.navLinks.getAll.mockReturnValue([]);
startContract.getBrand$.mockReturnValue(new BehaviorSubject({} as ChromeBrand));

View file

@ -37,6 +37,7 @@ import { DocTitleService, ChromeDocTitle } from './doc_title';
import { LoadingIndicator, HeaderWrapper as Header } from './ui';
import { DocLinksStart } from '../doc_links';
import { ChromeHelpExtensionMenuLink } from './ui/header/header_help_menu';
import { KIBANA_ASK_ELASTIC_LINK } from './constants';
export { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle };
@ -147,6 +148,7 @@ export class ChromeService {
const helpExtension$ = new BehaviorSubject<ChromeHelpExtension | undefined>(undefined);
const breadcrumbs$ = new BehaviorSubject<ChromeBreadcrumb[]>([]);
const badge$ = new BehaviorSubject<ChromeBadge | undefined>(undefined);
const helpSupportUrl$ = new BehaviorSubject<string>(KIBANA_ASK_ELASTIC_LINK);
const navControls = this.navControls.start();
const navLinks = this.navLinks.start({ application, http });
@ -172,7 +174,6 @@ export class ChromeService {
<LoadingIndicator loadingCount$={http.getLoadingCount$()} />
<Header
isCloudEnabled={injectedMetadata.getInjectedVar('isCloudEnabled') as boolean}
application={application}
appTitle$={appTitle$.pipe(takeUntil(this.stop$))}
badge$={badge$.pipe(takeUntil(this.stop$))}
@ -181,6 +182,7 @@ export class ChromeService {
kibanaDocLink={docLinks.links.kibana}
forceAppSwitcherNavigation$={navLinks.getForceAppSwitcherNavigation$()}
helpExtension$={helpExtension$.pipe(takeUntil(this.stop$))}
helpSupportUrl$={helpSupportUrl$.pipe(takeUntil(this.stop$))}
homeHref={http.basePath.prepend('/app/kibana#/home')}
isVisible$={this.isVisible$}
kibanaVersion={injectedMetadata.getKibanaVersion()}
@ -256,6 +258,8 @@ export class ChromeService {
setHelpExtension: (helpExtension?: ChromeHelpExtension) => {
helpExtension$.next(helpExtension);
},
setHelpSupportUrl: (url: string) => helpSupportUrl$.next(url),
};
}
@ -401,6 +405,12 @@ export interface ChromeStart {
* Override the current set of custom help content
*/
setHelpExtension(helpExtension?: ChromeHelpExtension): void;
/**
* Override the default support URL shown in the help menu
* @param url The updated support URL
*/
setHelpSupportUrl(url: string): void;
}
/** @internal */

View file

@ -17,7 +17,6 @@
* under the License.
*/
export const ELASTIC_SUPPORT_LINK = 'https://support.elastic.co/';
export const KIBANA_FEEDBACK_LINK = 'https://www.elastic.co/products/kibana/feedback';
export const KIBANA_ASK_ELASTIC_LINK = 'https://www.elastic.co/products/kibana/ask-elastic';
export const GITHUB_CREATE_ISSUE_LINK = 'https://github.com/elastic/kibana/issues/new/choose';

View file

@ -164,6 +164,7 @@ interface Props {
recentlyAccessed$: Rx.Observable<ChromeRecentlyAccessedHistoryItem[]>;
forceAppSwitcherNavigation$: Rx.Observable<boolean>;
helpExtension$: Rx.Observable<ChromeHelpExtension | undefined>;
helpSupportUrl$: Rx.Observable<string>;
legacyMode: boolean;
navControlsLeft$: Rx.Observable<readonly ChromeNavControl[]>;
navControlsRight$: Rx.Observable<readonly ChromeNavControl[]>;
@ -171,7 +172,6 @@ interface Props {
basePath: HttpStart['basePath'];
isLocked?: boolean;
onIsLockedUpdate?: (isLocked: boolean) => void;
isCloudEnabled: boolean;
}
interface State {
@ -283,13 +283,13 @@ class HeaderUI extends Component<Props, State> {
basePath,
breadcrumbs$,
helpExtension$,
helpSupportUrl$,
intl,
isLocked,
kibanaDocLink,
kibanaVersion,
onIsLockedUpdate,
legacyMode,
isCloudEnabled,
} = this.props;
const {
appTitle,
@ -389,7 +389,12 @@ class HeaderUI extends Component<Props, State> {
<EuiHeaderSection side="right">
<EuiHeaderSectionItem>
<HeaderHelpMenu
{...{ isCloudEnabled, helpExtension$, kibanaDocLink, kibanaVersion }}
{...{
helpExtension$,
helpSupportUrl$,
kibanaDocLink,
kibanaVersion,
}}
/>
</EuiHeaderSectionItem>

View file

@ -36,14 +36,10 @@ import {
} from '@elastic/eui';
import { ExclusiveUnion } from '@elastic/eui';
import { combineLatest } from 'rxjs';
import { HeaderExtension } from './header_extension';
import { ChromeHelpExtension } from '../../chrome_service';
import {
ELASTIC_SUPPORT_LINK,
GITHUB_CREATE_ISSUE_LINK,
KIBANA_ASK_ELASTIC_LINK,
KIBANA_FEEDBACK_LINK,
} from '../../constants';
import { GITHUB_CREATE_ISSUE_LINK, KIBANA_FEEDBACK_LINK } from '../../constants';
/** @public */
export type ChromeHelpExtensionMenuGitHubLink = EuiButtonEmptyProps & {
@ -110,16 +106,17 @@ export type ChromeHelpExtensionMenuLink = ExclusiveUnion<
interface Props {
helpExtension$: Rx.Observable<ChromeHelpExtension | undefined>;
helpSupportUrl$: Rx.Observable<string>;
intl: InjectedIntl;
kibanaVersion: string;
useDefaultContent?: boolean;
kibanaDocLink: string;
isCloudEnabled: boolean;
}
interface State {
isOpen: boolean;
helpExtension?: ChromeHelpExtension;
helpSupportUrl: string;
}
class HeaderHelpMenuUI extends Component<Props, State> {
@ -131,16 +128,19 @@ class HeaderHelpMenuUI extends Component<Props, State> {
this.state = {
isOpen: false,
helpExtension: undefined,
helpSupportUrl: '',
};
}
public componentDidMount() {
this.subscription = this.props.helpExtension$.subscribe({
next: helpExtension => {
this.setState({
helpExtension,
});
},
this.subscription = combineLatest(
this.props.helpExtension$,
this.props.helpSupportUrl$
).subscribe(([helpExtension, helpSupportUrl]) => {
this.setState({
helpExtension,
helpSupportUrl,
});
});
}
@ -183,7 +183,7 @@ class HeaderHelpMenuUI extends Component<Props, State> {
public render() {
const { intl, kibanaVersion, useDefaultContent, kibanaDocLink } = this.props;
const { helpExtension } = this.state;
const { helpExtension, helpSupportUrl } = this.state;
const defaultContent = useDefaultContent ? (
<Fragment>
@ -196,12 +196,7 @@ class HeaderHelpMenuUI extends Component<Props, State> {
<EuiSpacer size="xs" />
<EuiButtonEmpty
href={this.props.isCloudEnabled ? ELASTIC_SUPPORT_LINK : KIBANA_ASK_ELASTIC_LINK}
target="_blank"
size="xs"
flush="left"
>
<EuiButtonEmpty href={helpSupportUrl} target="_blank" size="xs" flush="left">
<FormattedMessage
id="core.ui.chrome.headerGlobalNav.helpMenuAskElasticTitle"
defaultMessage="Ask Elastic"

View file

@ -250,6 +250,7 @@ export interface ChromeStart {
setBrand(brand: ChromeBrand): void;
setBreadcrumbs(newBreadcrumbs: ChromeBreadcrumb[]): void;
setHelpExtension(helpExtension?: ChromeHelpExtension): void;
setHelpSupportUrl(url: string): void;
setIsCollapsed(isCollapsed: boolean): void;
setIsVisible(isVisible: boolean): void;
}

View file

@ -28,6 +28,7 @@ import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom'
import { getTutorial } from '../load_tutorials';
import { replaceTemplateStrings } from './tutorial/replace_template_strings';
import { getServices } from '../kibana_services';
import { npSetup } from 'ui/new_platform';
export function HomeApp({ directories }) {
const {
@ -39,8 +40,9 @@ export function HomeApp({ directories }) {
setOptInNoticeSeen,
},
} = getServices();
const { cloud } = npSetup.plugins;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
const isCloudEnabled = getInjected('isCloudEnabled', false);
const apmUiEnabled = getInjected('apmUiEnabled', true);
const mlEnabled = getInjected('mlEnabled', false);
const defaultAppId = getInjected('kbnDefaultAppId', 'discover');

View file

@ -17,6 +17,7 @@
* under the License.
*/
import { get, has } from 'lodash';
import { i18n } from '@kbn/i18n';
import { INSTRUCTION_VARIANT } from '../../../../common/tutorials/instruction_variant';
@ -32,27 +33,27 @@ import {
createDotNetAgentInstructions,
} from '../instructions/apm_agent_instructions';
function getIfExists(config, key) {
return config.has(key) && config.get(key);
function getIfExists(obj, key) {
return has(obj, key) && get(obj, key);
}
export function createElasticCloudInstructions(config) {
const apmServerUrl = getIfExists(config, 'xpack.cloud.apm.url');
export function createElasticCloudInstructions(cloudSetup) {
const apmServerUrl = getIfExists(cloudSetup, 'apm.url');
const instructionSets = [];
if (!apmServerUrl) {
instructionSets.push(getApmServerInstructionSet(config));
instructionSets.push(getApmServerInstructionSet(cloudSetup));
}
instructionSets.push(getApmAgentInstructionSet(config));
instructionSets.push(getApmAgentInstructionSet(cloudSetup));
return {
instructionSets,
};
}
function getApmServerInstructionSet(config) {
const cloudId = getIfExists(config, 'xpack.cloud.id');
function getApmServerInstructionSet(cloudSetup) {
const cloudId = getIfExists(cloudSetup, 'cloudId');
return {
title: i18n.translate('kbn.server.tutorials.apm.apmServer.title', {
defaultMessage: 'APM Server',
@ -75,9 +76,9 @@ function getApmServerInstructionSet(config) {
};
}
function getApmAgentInstructionSet(config) {
const apmServerUrl = getIfExists(config, 'xpack.cloud.apm.url');
const secretToken = getIfExists(config, 'xpack.cloud.apm.secret_token');
function getApmAgentInstructionSet(cloudSetup) {
const apmServerUrl = getIfExists(cloudSetup, 'apm.url');
const secretToken = getIfExists(cloudSetup, 'apm.secretToken');
return {
title: i18n.translate('kbn.server.tutorials.apm.elasticCloudInstructions.title', {

View file

@ -39,6 +39,7 @@ function isEnabled(config) {
export function apmSpecProvider(server) {
const config = server.config();
const apmIndexPatternTitle = config.get('apm_oss.indexPattern');
const { cloud } = server.newPlatform.setup;
const savedObjects = [
{
@ -95,7 +96,7 @@ It allows you to monitor the performance of thousands of applications in real ti
euiIconType: 'logoAPM',
artifacts,
onPrem: onPremInstructions(apmIndexPatternTitle),
elasticCloud: createElasticCloudInstructions(config),
elasticCloud: createElasticCloudInstructions(cloud),
previewImagePath: '/plugins/kibana/home/tutorial_resources/apm/apm.png',
savedObjects,
savedObjectsInstallMsg: i18n.translate(

View file

@ -145,6 +145,7 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},
@ -775,6 +776,7 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},
@ -1393,6 +1395,7 @@ exports[`QueryStringInput Should pass the query language to the language switche
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},
@ -2020,6 +2023,7 @@ exports[`QueryStringInput Should pass the query language to the language switche
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},
@ -2638,6 +2642,7 @@ exports[`QueryStringInput Should render the given query 1`] = `
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},
@ -3265,6 +3270,7 @@ exports[`QueryStringInput Should render the given query 1`] = `
"setBrand": [MockFunction],
"setBreadcrumbs": [MockFunction],
"setHelpExtension": [MockFunction],
"setHelpSupportUrl": [MockFunction],
"setIsCollapsed": [MockFunction],
"setIsVisible": [MockFunction],
},

View file

@ -59,7 +59,7 @@ export interface Datatable {
rows: DatatableRow[];
}
interface SerializedDatatable extends Datatable {
export interface SerializedDatatable extends Datatable {
rows: string[][];
}

View file

@ -20,7 +20,6 @@ import { beats } from './legacy/plugins/beats_management';
import { apm } from './legacy/plugins/apm';
import { maps } from './legacy/plugins/maps';
import { licenseManagement } from './legacy/plugins/license_management';
import { cloud } from './legacy/plugins/cloud';
import { indexManagement } from './legacy/plugins/index_management';
import { indexLifecycleManagement } from './legacy/plugins/index_lifecycle_management';
import { consoleExtensions } from './legacy/plugins/console_extensions';
@ -64,7 +63,6 @@ module.exports = function (kibana) {
maps(kibana),
canvas(kibana),
licenseManagement(kibana),
cloud(kibana),
indexManagement(kibana),
consoleExtensions(kibana),
indexLifecycleManagement(kibana),

View file

@ -1,60 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import sinon from 'sinon';
import { Server } from 'hapi';
import { createCollectorFetch, createCloudUsageCollector } from './cloud_usage_collector';
const CLOUD_ID_STAGING =
'staging:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==';
const CLOUD_ID =
'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==';
const mockUsageCollection = () => ({
makeUsageCollector: sinon.stub(),
});
const getMockServer = (cloudId?: string) =>
({
config() {
return {
get(path: string) {
switch (path) {
case 'xpack.cloud':
return { id: cloudId };
default:
throw Error(`server.config().get(${path}) should not be called by this collector.`);
}
},
};
},
} as Server);
describe('Cloud usage collector', () => {
describe('collector', () => {
it('returns `isCloudEnabled: false` if `xpack.cloud.id` is not defined', async () => {
const mockServer = getMockServer();
const collector = await createCollectorFetch(mockServer)();
expect(collector.isCloudEnabled).toBe(false);
});
it('returns `isCloudEnabled: true` if `xpack.cloud.id` is defined', async () => {
const stagingCollector = await createCollectorFetch(getMockServer(CLOUD_ID))();
const collector = await createCollectorFetch(getMockServer(CLOUD_ID_STAGING))();
expect(collector.isCloudEnabled).toBe(true);
expect(stagingCollector.isCloudEnabled).toBe(true);
});
});
});
describe('createCloudUsageCollector', () => {
it('returns calls `makeUsageCollector`', () => {
const mockServer = getMockServer();
const usageCollection = mockUsageCollection();
createCloudUsageCollector(usageCollection as any, mockServer);
expect(usageCollection.makeUsageCollector.calledOnce).toBe(true);
});
});

View file

@ -1,36 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import { Server } from 'hapi';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { KIBANA_CLOUD_STATS_TYPE } from './constants';
export interface UsageStats {
isCloudEnabled: boolean;
}
export function createCollectorFetch(server: Server) {
return async function fetchUsageStats(): Promise<UsageStats> {
const { id } = server.config().get(`xpack.cloud`);
return {
isCloudEnabled: !!id,
};
};
}
export function createCloudUsageCollector(usageCollection: UsageCollectionSetup, server: Server) {
return usageCollection.makeUsageCollector({
type: KIBANA_CLOUD_STATS_TYPE,
isReady: () => true,
fetch: createCollectorFetch(server),
});
}
export function registerCloudUsageCollector(usageCollection: UsageCollectionSetup, server: Server) {
const collector = createCloudUsageCollector(usageCollection, server);
usageCollection.registerCollector(collector);
}

View file

@ -1,47 +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;
* you may not use this file except in compliance with the Elastic License.
*/
import { registerCloudUsageCollector } from './cloud_usage_collector';
export const cloud = kibana => {
return new kibana.Plugin({
id: 'cloud',
configPrefix: 'xpack.cloud',
require: ['kibana', 'elasticsearch', 'xpack_main'],
uiExports: {
injectDefaultVars(server, options) {
return {
isCloudEnabled: !!options.id,
cloudId: options.id
};
},
},
config(Joi) {
return Joi.object({
enabled: Joi.boolean().default(true),
id: Joi.string(),
apm: Joi.object({
url: Joi.string(),
secret_token: Joi.string(),
ui: Joi.object({
url: Joi.string(),
}).default(),
}).default(),
}).default();
},
init(server) {
const config = server.config().get(`xpack.cloud`);
server.expose('config', {
isCloudEnabled: !!config.id
});
const { usageCollection } = server.newPlatform.setup.plugins;
registerCloudUsageCollector(usageCollection, server);
}
});
};

View file

@ -7,7 +7,10 @@
import { resolve } from 'path';
import { i18n } from '@kbn/i18n';
import KbnServer, { Server } from 'src/legacy/server/kbn_server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { plugin } from './server/new_platform';
import { CloudSetup } from '../../../plugins/cloud/server';
import {
MlInitializerContext,
MlCoreSetup,
@ -80,13 +83,14 @@ export const ml = (kibana: any) => {
http: mlHttpService,
savedObjects: server.savedObjects,
};
const { usageCollection, cloud } = kbnServer.newPlatform.setup.plugins;
const plugins = {
elasticsearch: server.plugins.elasticsearch,
security: server.plugins.security,
xpackMain: server.plugins.xpack_main,
spaces: server.plugins.spaces,
usageCollection: kbnServer.newPlatform.setup.plugins.usageCollection,
usageCollection: usageCollection as UsageCollectionSetup,
cloud: cloud as CloudSetup,
ml: this,
};

View file

@ -16,9 +16,13 @@ import {
import { UsageInitialization } from '../../new_platform/plugin';
export function makeMlUsageCollector(
usageCollection: UsageCollectionSetup,
usageCollection: UsageCollectionSetup | undefined,
{ elasticsearchPlugin, savedObjects }: UsageInitialization
): void {
if (!usageCollection) {
return;
}
const mlUsageCollector = usageCollection.makeUsageCollector({
type: 'ml',
isReady: () => true,

View file

@ -11,6 +11,7 @@ import { KibanaConfig, SavedObjectsLegacyService } from 'src/legacy/server/kbn_s
import { Logger, PluginInitializerContext, CoreSetup } from 'src/core/server';
import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { CloudSetup } from '../../../../../plugins/cloud/server';
import { XPackMainPlugin } from '../../../xpack_main/xpack_main';
import { addLinksToSampleDatasets } from '../lib/sample_data_sets';
import { checkLicense } from '../lib/check_license';
@ -79,7 +80,8 @@ export interface PluginsSetup {
xpackMain: MlXpackMainPlugin;
security: any;
spaces: any;
usageCollection: UsageCollectionSetup;
usageCollection?: UsageCollectionSetup;
cloud?: CloudSetup;
// TODO: this is temporary for `mirrorPluginStatus`
ml: any;
}
@ -91,6 +93,7 @@ export interface RouteInitialization {
xpackMainPlugin?: MlXpackMainPlugin;
savedObjects?: SavedObjectsLegacyService;
spacesPlugin: any;
cloud?: CloudSetup;
}
export interface UsageInitialization {
elasticsearchPlugin: ElasticsearchPlugin;
@ -190,6 +193,7 @@ export class Plugin {
xpackMainPlugin: plugins.xpackMain,
savedObjects: core.savedObjects,
spacesPlugin: plugins.spaces,
cloud: plugins.cloud,
};
const usageInitializationDeps: UsageInitialization = {
elasticsearchPlugin: plugins.elasticsearch,

View file

@ -21,10 +21,10 @@ import { isSecurityDisabled } from '../lib/security_utils';
export function systemRoutes({
commonRouteConfig,
elasticsearchPlugin,
config,
route,
xpackMainPlugin,
spacesPlugin
spacesPlugin,
cloud,
}) {
const callWithInternalUser = callWithInternalUserFactory(elasticsearchPlugin);
@ -174,8 +174,7 @@ export function systemRoutes({
try {
const info = await callWithRequest('ml.info');
const cloudIdKey = 'xpack.cloud.id';
const cloudId = config.has(cloudIdKey) && config.get(cloudIdKey);
const cloudId = cloud && cloud.cloudId;
return { ...info, cloudId };
} catch (error) {
return wrapError(error);

View file

@ -43,7 +43,7 @@ function NoDataMessage(props) {
export function NoData(props) {
const [isLoading, setIsLoading] = useState(false);
const [useInternalCollection, setUseInternalCollection] = useState(props.isOnCloud);
const [useInternalCollection, setUseInternalCollection] = useState(props.isCloudEnabled);
async function startSetup() {
setIsLoading(true);
@ -64,7 +64,7 @@ export function NoData(props) {
<EuiSpacer size="m" />
<NoDataMessage {...props} />
<CheckerErrors errors={props.errors} />
{ !props.isOnCloud ? (
{ !props.isCloudEnabled ? (
<Fragment>
<EuiHorizontalRule size="half" />
<EuiButtonEmpty isDisabled={props.isCollectionEnabledUpdated} onClick={() => setUseInternalCollection(false)}>

View file

@ -12,6 +12,7 @@ import chrome from 'ui/chrome';
import { toastNotifications } from 'ui/notify';
import { i18n } from '@kbn/i18n';
import { SetupModeEnterButton } from '../components/setup_mode/enter_button';
import { npSetup } from 'ui/new_platform';
function isOnPage(hash) {
return contains(window.location.hash, hash);
@ -82,10 +83,10 @@ export const updateSetupModeData = async (uuid, fetchWithoutClusterUuid = false)
const oldData = setupModeState.data;
const data = await fetchCollectionData(uuid, fetchWithoutClusterUuid);
setupModeState.data = data;
const isCloud = chrome.getInjected('isOnCloud');
const { cloud } = npSetup.plugins;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
const hasPermissions = get(data, '_meta.hasPermissions', false);
if (isCloud || !hasPermissions) {
if (isCloudEnabled || !hasPermissions) {
let text = null;
if (!hasPermissions) {
text = i18n.translate('xpack.monitoring.setupMode.notAvailablePermissions', {
@ -163,7 +164,9 @@ export const setSetupModeMenuItem = () => {
}
const globalState = angularState.injector.get('globalState');
const enabled = !globalState.inSetupMode && !chrome.getInjected('isOnCloud');
const { cloud } = npSetup.plugins;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
const enabled = !globalState.inSetupMode && !isCloudEnabled;
render(
<SetupModeEnterButton enabled={enabled} toggleSetupMode={toggleSetupMode} />,

View file

@ -69,12 +69,15 @@ function setModules() {
describe('setup_mode', () => {
beforeEach(async () => {
jest.doMock('ui/chrome', () => ({
getInjected: key => {
if (key === 'isOnCloud') {
return false;
jest.doMock('ui/new_platform', () => ({
npSetup: {
plugins: {
cloud: {
cloudId: undefined,
isCloudEnabled: false,
}
}
},
}
}));
setModules();
});
@ -122,12 +125,15 @@ describe('setup_mode', () => {
it('should not fetch data if on cloud', async done => {
const addDanger = jest.fn();
jest.doMock('ui/chrome', () => ({
getInjected: key => {
if (key === 'isOnCloud') {
return true;
jest.doMock('ui/new_platform', () => ({
npSetup: {
plugins: {
cloud: {
cloudId: 'test',
isCloudEnabled: true,
}
}
},
}
}));
data = {
_meta: {

View file

@ -5,7 +5,6 @@
*/
import React from 'react';
import chrome from 'ui/chrome';
import {
ClusterSettingsChecker,
NodeSettingsChecker,
@ -18,6 +17,7 @@ import { I18nContext } from 'ui/i18n';
import { CODE_PATH_LICENSE } from '../../../common/constants';
import { MonitoringViewBaseController } from '../base_controller';
import { i18n } from '@kbn/i18n';
import { npSetup } from 'ui/new_platform';
export class NoDataController extends MonitoringViewBaseController {
@ -97,6 +97,8 @@ export class NoDataController extends MonitoringViewBaseController {
render(enabler) {
const props = this;
const { cloud } = npSetup.plugins;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
this.renderReact(
<I18nContext>
@ -104,7 +106,7 @@ export class NoDataController extends MonitoringViewBaseController {
{...props}
enabler={enabler}
changePath={this.changePath}
isOnCloud={chrome.getInjected('isOnCloud')}
isCloudEnabled={isCloudEnabled}
/>
</I18nContext>
);

View file

@ -21,6 +21,15 @@ describe('Elasticsearch Cluster Settings', () => {
const getReq = response => {
return {
server: {
newPlatform: {
setup: {
plugins: {
cloud: {
isCloudEnabled: false,
}
}
}
},
plugins: {
elasticsearch: {
getCluster() {
@ -49,7 +58,7 @@ describe('Elasticsearch Cluster Settings', () => {
reason: {
context: `cluster ${source}`,
data: '-1',
isCloud: false,
isCloudEnabled: false,
property: 'xpack.monitoring.collection.interval'
}
});
@ -79,7 +88,7 @@ describe('Elasticsearch Cluster Settings', () => {
reason: {
context: `cluster ${source}`,
data: 'Remote exporters indicate a possible misconfiguration: myCoolExporter',
isCloud: false,
isCloudEnabled: false,
property: 'xpack.monitoring.exporters'
}
});
@ -109,7 +118,7 @@ describe('Elasticsearch Cluster Settings', () => {
reason: {
context: `cluster ${source}`,
data: 'false',
isCloud: false,
isCloudEnabled: false,
property: 'xpack.monitoring.enabled'
}
});

View file

@ -7,14 +7,14 @@
import { get } from 'lodash';
import { findReason } from './find_reason';
export function handleResponse(response, isCloud) {
export function handleResponse(response, isCloudEnabled) {
const sources = ['persistent', 'transient', 'defaults'];
for (const source of sources) {
const monitoringSettings = get(response[source], 'xpack.monitoring');
if (monitoringSettings !== undefined) {
const check = findReason(monitoringSettings, {
context: `cluster ${source}`,
isCloud: isCloud
isCloudEnabled,
});
if (check.found) {
@ -28,7 +28,8 @@ export function handleResponse(response, isCloud) {
export async function checkClusterSettings(req) {
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('admin');
const isCloud = get(req.server.plugins, 'cloud.config.isCloudEnabled', false);
const { cloud } = req.server.newPlatform.setup.plugins;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
const response = await callWithRequest(req, 'transport.request', {
method: 'GET',
path: '/_cluster/settings?include_defaults',
@ -39,5 +40,5 @@ export async function checkClusterSettings(req) {
]
});
return handleResponse(response, isCloud);
return handleResponse(response, isCloudEnabled);
}

View file

@ -14,7 +14,7 @@ const isEnabledOrDefault = property => {
return property === undefined || (Boolean(property) && property !== 'false');
};
export function findReason(settingsSource, context, isCloud) {
export function findReason(settingsSource, context, isCloudEnabled) {
const iterateReasons = () => {
// PluginEnabled: check for `monitoring.enabled: false`
const monitoringEnabled = get(settingsSource, 'enabled');
@ -91,7 +91,7 @@ export function findReason(settingsSource, context, isCloud) {
});
if (allEnabledRemote.length > 0 && allEnabledLocal.length === 0) {
let ret = {};
if (isCloud) {
if (isCloudEnabled) {
ret = {
found: true,
reason: {

View file

@ -5,7 +5,6 @@
*/
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
import { resolve } from 'path';
/**
@ -30,7 +29,6 @@ export const getUiExports = () => ({
const config = server.config();
return {
monitoringUiEnabled: config.get('xpack.monitoring.ui.enabled'),
isOnCloud: get(server.plugins, 'cloud.config.isCloudEnabled', false)
};
},
hacks: [ 'plugins/monitoring/hacks/toggle_app_link_in_nav' ],

View file

@ -39,7 +39,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => {
patch: () => {},
},
{
cloud: { config: { isCloudEnabled: false } },
cloud: { isCloudEnabled: false },
elasticsearch: { getCluster: () => ({ callWithInternalUser: mockCallWithInternalUser }) },
}
);

View file

@ -28,7 +28,7 @@ let isCloudEnabled: boolean = false;
let callWithInternalUser: any;
export function registerRepositoriesRoutes(router: Router, plugins: Plugins) {
isCloudEnabled = plugins.cloud.config.isCloudEnabled;
isCloudEnabled = plugins.cloud && plugins.cloud.isCloudEnabled;
callWithInternalUser = plugins.elasticsearch.getCluster('data').callWithInternalUser;
router.get('repository_types', getTypesHandler);
router.get('repositories', getAllHandler);

View file

@ -4,13 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { Legacy } from 'kibana';
import { createRouter, Router } from '../../server/lib/create_router';
import { registerLicenseChecker } from '../../server/lib/register_license_checker';
import { elasticsearchJsPlugin } from './server/client/elasticsearch_slm';
import { CloudSetup } from '../../../plugins/cloud/server';
export interface Core {
http: {
createRouter(basePath: string): Router;
@ -24,11 +23,7 @@ export interface Plugins {
license: {
registerLicenseChecker: typeof registerLicenseChecker;
};
cloud: {
config: {
isCloudEnabled: boolean;
};
};
cloud: CloudSetup;
settings: {
config: {
isSlmEnabled: boolean;
@ -42,6 +37,7 @@ export function createShim(
server: Legacy.Server,
pluginId: string
): { core: Core; plugins: Plugins } {
const { cloud } = server.newPlatform.setup.plugins;
return {
core: {
http: {
@ -56,11 +52,7 @@ export function createShim(
license: {
registerLicenseChecker,
},
cloud: {
config: {
isCloudEnabled: get(server.plugins, 'cloud.config.isCloudEnabled', false),
},
},
cloud: cloud as CloudSetup,
settings: {
config: {
isSlmEnabled: server.config()

View file

@ -4,12 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { get } from 'lodash';
import { Legacy } from 'kibana';
import { createRouter, Router } from '../../../server/lib/create_router';
import { registerLicenseChecker } from '../../../server/lib/register_license_checker';
import { elasticsearchJsPlugin } from './client/elasticsearch_transform';
export interface Core {
http: {
createRouter(basePath: string): Router;
@ -20,11 +18,6 @@ export interface Plugins {
license: {
registerLicenseChecker: typeof registerLicenseChecker;
};
cloud: {
config: {
isCloudEnabled: boolean;
};
};
xpack_main: any;
elasticsearch: any;
}
@ -46,11 +39,6 @@ export function createServerShim(
license: {
registerLicenseChecker,
},
cloud: {
config: {
isCloudEnabled: get(server.plugins, 'cloud.config.isCloudEnabled', false),
},
},
xpack_main: server.plugins.xpack_main,
elasticsearch: server.plugins.elasticsearch,
},

View file

@ -9,6 +9,7 @@ import { Legacy } from 'kibana';
import { resolve } from 'path';
import mappings from './mappings.json';
import { plugin } from './server/np_ready';
import { CloudSetup } from '../../../plugins/cloud/server';
export function upgradeAssistant(kibana: any) {
const publicSrc = resolve(__dirname, 'public');
@ -43,7 +44,11 @@ export function upgradeAssistant(kibana: any) {
init(server: Legacy.Server) {
// Add server routes and initialize the plugin here
const instance = plugin({} as any);
const { usageCollection, cloud } = server.newPlatform.setup.plugins;
instance.setup(server.newPlatform.setup.core, {
usageCollection,
cloud: cloud as CloudSetup,
__LEGACY: {
// Legacy objects
events: server.events,
@ -58,12 +63,6 @@ export function upgradeAssistant(kibana: any) {
apm_oss: server.plugins.apm_oss,
elasticsearch: server.plugins.elasticsearch,
xpack_main: server.plugins.xpack_main,
cloud: {
config: {
isCloudEnabled: _.get(server.plugins, 'cloud.config.isCloudEnabled', false),
},
},
usage: server.newPlatform.setup.plugins.usageCollection,
},
} as any,
});

View file

@ -19,6 +19,7 @@ import chrome from 'ui/chrome';
import { NEXT_MAJOR_VERSION } from '../common/version';
import { plugin } from './np_ready';
import { CloudSetup } from '../../../../plugins/cloud/public';
const BASE_PATH = `/management/elasticsearch/upgrade_assistant`;
@ -42,10 +43,10 @@ export interface LegacyManagementPlugin {
// Based on /rfcs/text/0006_management_section_service.md
export interface LegacyPlugins {
cloud?: CloudSetup;
management: LegacyManagementPlugin;
__LEGACY: {
XSRF: string;
isCloudEnabled: boolean;
};
}
@ -54,11 +55,11 @@ function startApp() {
template:
'<kbn-management-app section="elasticsearch/upgrade_assistant"><upgrade-assistant /></kbn-management-app>',
});
const { cloud } = npSetup.plugins as any;
const legacyPluginsShim: LegacyPlugins = {
cloud: cloud as CloudSetup,
__LEGACY: {
XSRF: chrome.getXsrfToken(),
isCloudEnabled: chrome.getInjected('isCloudEnabled', false),
},
management: {
sections: {

View file

@ -9,11 +9,10 @@ import { RootComponent } from './application/app';
import { LegacyPlugins } from '../legacy';
export class UpgradeAssistantUIPlugin implements Plugin {
async setup(
{ http }: CoreSetup,
{ management, __LEGACY: { XSRF, isCloudEnabled } }: LegacyPlugins
) {
async setup({ http }: CoreSetup, { cloud, management, __LEGACY: { XSRF } }: LegacyPlugins) {
const appRegistrar = management.sections.get('kibana');
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
return appRegistrar.registerApp({
mount(__, { __LEGACY: { renderToElement } }) {
return renderToElement(() => RootComponent({ http, XSRF, isCloudEnabled }));

View file

@ -4,21 +4,28 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Plugin, CoreSetup, CoreStart } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { ServerShim, ServerShimWithRouter } from './types';
import { credentialStoreFactory } from './lib/reindexing/credential_store';
import { registerUpgradeAssistantUsageCollector } from './lib/telemetry';
import { registerClusterCheckupRoutes } from './routes/cluster_checkup';
import { registerDeprecationLoggingRoutes } from './routes/deprecation_logging';
import { registerReindexIndicesRoutes, registerReindexWorker } from './routes/reindex_indices';
import { CloudSetup } from '../../../../../plugins/cloud/server';
import { registerTelemetryRoutes } from './routes/telemetry';
import { registerQueryDefaultFieldRoutes } from './routes/query_default_field';
import { registerTelemetryRoutes } from './routes/telemetry';
interface PluginsSetup {
__LEGACY: ServerShim;
usageCollection: UsageCollectionSetup;
cloud?: CloudSetup;
}
export class UpgradeAssistantServerPlugin implements Plugin<void, void, object, object> {
setup({ http }: CoreSetup, { __LEGACY }: { __LEGACY: ServerShim }) {
setup({ http }: CoreSetup, { __LEGACY, usageCollection, cloud }: PluginsSetup) {
const router = http.createRouter();
const shimWithRouter: ServerShimWithRouter = { ...__LEGACY, router };
registerClusterCheckupRoutes(shimWithRouter);
registerClusterCheckupRoutes(shimWithRouter, { cloud });
registerDeprecationLoggingRoutes(shimWithRouter);
registerQueryDefaultFieldRoutes(shimWithRouter);
@ -35,7 +42,7 @@ export class UpgradeAssistantServerPlugin implements Plugin<void, void, object,
// Bootstrap the needed routes and the collector for the telemetry
registerTelemetryRoutes(shimWithRouter);
registerUpgradeAssistantUsageCollector(__LEGACY.plugins.usage, __LEGACY);
registerUpgradeAssistantUsageCollector(usageCollection, __LEGACY);
}
start(core: CoreStart, plugins: any) {}

View file

@ -29,9 +29,15 @@ describe('cluster checkup API', () => {
let mockRouter: MockRouter;
let serverShim: any;
let ctxMock: any;
let mockPluginsSetup: any;
beforeEach(() => {
mockRouter = createMockRouter();
mockPluginsSetup = {
cloud: {
isCloudEnabled: true,
},
};
ctxMock = {
core: {},
};
@ -41,17 +47,12 @@ describe('cluster checkup API', () => {
apm_oss: {
indexPatterns: ['apm-*'],
},
cloud: {
config: {
isCloudEnabled: true,
},
},
elasticsearch: {
getCluster: () => ({ callWithRequest: jest.fn() } as any),
} as any,
},
};
registerClusterCheckupRoutes(serverShim);
registerClusterCheckupRoutes(serverShim, mockPluginsSetup);
});
describe('with cloud enabled', () => {

View file

@ -8,12 +8,20 @@ import _ from 'lodash';
import { ServerShimWithRouter } from '../types';
import { getUpgradeAssistantStatus } from '../lib/es_migration_apis';
import { versionCheckHandlerWrapper } from '../lib/es_version_precheck';
import { CloudSetup } from '../../../../../../plugins/cloud/server';
import { createRequestShim } from './create_request_shim';
export function registerClusterCheckupRoutes(server: ServerShimWithRouter) {
interface PluginsSetup {
cloud?: CloudSetup;
}
export function registerClusterCheckupRoutes(
server: ServerShimWithRouter,
pluginsSetup: PluginsSetup
) {
const { cloud } = pluginsSetup;
const isCloudEnabled = !!(cloud && cloud.isCloudEnabled);
const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin');
const isCloudEnabled = _.get(server.plugins, 'cloud.config.isCloudEnabled', false);
const apmIndexPatterns = _.get(server, 'plugins.apm_oss.indexPatterns', []);
server.router.get(

View file

@ -31,11 +31,6 @@ describe('deprecation logging API', () => {
serverShim = {
router: mockRouter,
plugins: {
cloud: {
config: {
isCloudEnabled: true,
},
},
elasticsearch: {
getCluster: () => ({ callWithRequest } as any),
} as any,

View file

@ -5,7 +5,6 @@
*/
import { Legacy } from 'kibana';
import { IRouter } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch';
import { XPackMainPlugin } from '../../../xpack_main/xpack_main';
@ -13,12 +12,6 @@ export interface ServerShim {
plugins: {
elasticsearch: ElasticsearchPlugin;
xpack_main: XPackMainPlugin;
cloud: {
config: {
isCloudEnabled: boolean;
};
};
usage: UsageCollectionSetup;
};
log: any;
events: any;

View file

@ -5,3 +5,4 @@
*/
export const KIBANA_CLOUD_STATS_TYPE = 'cloud';
export const ELASTIC_SUPPORT_LINK = 'https://support.elastic.co/';

View file

@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { getIsCloudEnabled } from './is_cloud_enabled';
const MOCK_CLOUD_ID_STAGING =
'staging:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==';
const MOCK_CLOUD_ID_PROD =
'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==';
describe('getIsCloudEnabled', () => {
it('returns `false` if `id` is not undefined', async () => {
const cloudId = undefined;
const isCloudEnabled = getIsCloudEnabled(cloudId);
expect(isCloudEnabled).toBe(false);
});
it('returns `false` if `id` is not a string', async () => {
const cloudId = 123 as any;
const isCloudEnabled = getIsCloudEnabled(cloudId);
expect(isCloudEnabled).toBe(false);
});
it('returns `true` if `id` is a string', async () => {
const isCloudEnabledStaging = getIsCloudEnabled(MOCK_CLOUD_ID_STAGING);
const isCloudEnabledProd = getIsCloudEnabled(MOCK_CLOUD_ID_PROD);
expect(isCloudEnabledStaging).toBe(true);
expect(isCloudEnabledProd).toBe(true);
});
});

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export function getIsCloudEnabled(cloudId?: string) {
return typeof cloudId === 'string';
}

View file

@ -0,0 +1,9 @@
{
"id": "cloud",
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "cloud"],
"optionalPlugins": ["usageCollection"],
"server": true,
"ui": true
}

View 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;
* you may not use this file except in compliance with the Elastic License.
*/
import { PluginInitializerContext } from '../../../../src/core/public';
import { CloudPlugin } from './plugin';
export { CloudSetup } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new CloudPlugin(initializerContext);
}

View file

@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/public';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
import { ELASTIC_SUPPORT_LINK } from '../common/constants';
interface CloudConfigType {
id?: string;
}
export interface CloudSetup {
cloudId?: string;
isCloudEnabled: boolean;
}
export class CloudPlugin implements Plugin<CloudSetup> {
constructor(private readonly initializerContext: PluginInitializerContext) {}
public async setup(core: CoreSetup) {
const { id } = this.initializerContext.config.get<CloudConfigType>();
const isCloudEnabled = getIsCloudEnabled(id);
return {
cloudId: id,
isCloudEnabled,
};
}
public start(coreStart: CoreStart) {
coreStart.chrome.setHelpSupportUrl(ELASTIC_SUPPORT_LINK);
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { createCloudUsageCollector } from './cloud_usage_collector';
const mockUsageCollection = () => ({
makeUsageCollector: jest.fn().mockImplementation((args: any) => ({ ...args })),
});
const getMockConfigs = (isCloudEnabled: boolean) => ({ isCloudEnabled });
describe('createCloudUsageCollector', () => {
it('calls `makeUsageCollector`', () => {
const mockConfigs = getMockConfigs(false);
const usageCollection = mockUsageCollection();
createCloudUsageCollector(usageCollection as any, mockConfigs);
expect(usageCollection.makeUsageCollector).toBeCalledTimes(1);
});
describe('Fetched Usage data', () => {
it('return isCloudEnabled boolean', () => {
const mockConfigs = getMockConfigs(true);
const usageCollection = mockUsageCollection() as any;
const collector = createCloudUsageCollector(usageCollection, mockConfigs);
expect(collector.fetch().isCloudEnabled).toBe(true);
});
});
});

View file

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { KIBANA_CLOUD_STATS_TYPE } from '../../common/constants';
interface Config {
isCloudEnabled: boolean;
}
export function createCloudUsageCollector(usageCollection: UsageCollectionSetup, config: Config) {
const { isCloudEnabled } = config;
return usageCollection.makeUsageCollector({
type: KIBANA_CLOUD_STATS_TYPE,
isReady: () => true,
fetch: () => {
return {
isCloudEnabled,
};
},
});
}
export function registerCloudUsageCollector(
usageCollection: UsageCollectionSetup | undefined,
config: Config
) {
if (!usageCollection) {
return;
}
const collector = createCloudUsageCollector(usageCollection, config);
usageCollection.registerCollector(collector);
}

View file

@ -4,8 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export interface CloudPlugin {
config: {
isCloudEnabled: boolean;
};
}
export { registerCloudUsageCollector } from './cloud_usage_collector';

View file

@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from 'kibana/server';
const apmConfigSchema = schema.object({
url: schema.maybe(schema.string()),
secret_token: schema.maybe(schema.string()),
ui: schema.maybe(
schema.object({
url: schema.maybe(schema.string()),
})
),
});
const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
id: schema.maybe(schema.string()),
apm: schema.maybe(apmConfigSchema),
});
export type CloudConfigType = TypeOf<typeof configSchema>;
export const config: PluginConfigDescriptor<CloudConfigType> = {
exposeToBrowser: {
id: true,
},
schema: configSchema,
};

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { PluginInitializerContext } from 'src/core/server';
import { CloudPlugin } from './plugin';
export { CloudSetup } from './plugin';
export { config } from './config';
export const plugin = (initializerContext: PluginInitializerContext) => {
return new CloudPlugin(initializerContext);
};

View file

@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { first } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/server';
import { CloudConfigType } from './config';
import { registerCloudUsageCollector } from './collectors';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
interface PluginsSetup {
usageCollection?: UsageCollectionSetup;
}
export interface CloudSetup {
cloudId?: string;
isCloudEnabled: boolean;
apm: {
url?: string;
secretToken?: string;
};
}
export class CloudPlugin implements Plugin<CloudSetup> {
private readonly logger: Logger;
private readonly config$: Observable<CloudConfigType>;
constructor(private readonly context: PluginInitializerContext) {
this.logger = this.context.logger.get();
this.config$ = this.context.config.create<CloudConfigType>();
}
public async setup(core: CoreSetup, { usageCollection }: PluginsSetup) {
this.logger.debug('Setting up Cloud plugin');
const config = await this.config$.pipe(first()).toPromise();
const isCloudEnabled = getIsCloudEnabled(config.id);
registerCloudUsageCollector(usageCollection, { isCloudEnabled });
return {
cloudId: config.id,
isCloudEnabled,
apm: {
url: config.apm?.url,
secretToken: config.apm?.secret_token,
},
};
}
public start() {}
}

View file

@ -6,7 +6,6 @@
import 'hapi';
import { CloudPlugin } from '../../legacy/plugins/cloud';
import { XPackMainPlugin } from '../../legacy/plugins/xpack_main/xpack_main';
import { SecurityPlugin } from '../../legacy/plugins/security';
import { ActionsPlugin, ActionsClient } from '../../legacy/plugins/actions';
@ -19,7 +18,6 @@ declare module 'hapi' {
getAlertsClient?: () => AlertsClient;
}
interface PluginProperties {
cloud?: CloudPlugin;
xpack_main: XPackMainPlugin;
security?: SecurityPlugin;
actions?: ActionsPlugin;

View file

@ -6,7 +6,6 @@
import 'hapi';
import { CloudPlugin } from '../legacy/plugins/cloud';
import { XPackMainPlugin } from '../legacy/plugins/xpack_main/xpack_main';
import { SecurityPlugin } from '../legacy/plugins/security';
import { ActionsPlugin, ActionsClient } from '../legacy/plugins/actions';
@ -19,7 +18,6 @@ declare module 'hapi' {
getAlertsClient?: () => AlertsClient;
}
interface PluginProperties {
cloud?: CloudPlugin;
xpack_main: XPackMainPlugin;
security?: SecurityPlugin;
actions?: ActionsPlugin;