[7.x] [Telemetry] Move to OSS (#45769) (#48370)

This commit is contained in:
Ahmad Bamieh 2019-10-16 11:50:17 +03:00 committed by GitHub
parent ac4482aaca
commit e51369a72a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
155 changed files with 2128 additions and 1406 deletions

View file

@ -29,6 +29,7 @@
"kbnESQuery": "packages/kbn-es-query",
"inspector": "src/plugins/inspector",
"kibana-react": "src/plugins/kibana_react",
"telemetry": "src/legacy/core_plugins/telemetry",
"esUi": "src/plugins/es_ui_shared",
"uiActions": "src/plugins/ui_actions"
},

View file

@ -54,7 +54,7 @@ Specifies the password that {kib} uses for authentication when it retrieves data
from the monitoring cluster. If not set, {kib} uses the value of the
`elasticsearch.password` setting.
`xpack.telemetry.enabled`::
`telemetry.enabled`::
Set to `true` (default) to send cluster statistics to Elastic. Reporting your
cluster statistics helps us improve your user experience. Your data is never
shared with anyone. Set to `false` to disable statistics reporting from any

View file

@ -184,7 +184,7 @@ kibana_vars=(
xpack.security.public.protocol
xpack.security.public.hostname
xpack.security.public.port
xpack.telemetry.enabled
telemetry.enabled
)
longopts=''

View file

@ -38,6 +38,7 @@ import * as systemApi from './server/lib/system_api';
import mappings from './mappings.json';
import { getUiSettingDefaults } from './ui_setting_defaults';
import { makeKQLUsageCollector } from './server/lib/kql_usage_collector';
import { registerCspCollector } from './server/lib/csp_usage_collector';
import { injectVars } from './inject_vars';
import { i18n } from '@kbn/i18n';
@ -344,6 +345,7 @@ export default function (kibana) {
registerFieldFormats(server);
registerTutorials(server);
makeKQLUsageCollector(server);
registerCspCollector(server);
server.expose('systemApi', systemApi);
server.injectUiAppVars('kibana', () => injectVars(server));
},

View file

@ -24,7 +24,7 @@ import {
EuiCard,
EuiButton,
} from '@elastic/eui';
import { OptInMessage } from './opt_in_message';
import { OptInMessage } from '../../../../../telemetry/public/components/opt_in_message';
export interface Props {
urlBasePath: string;

View file

@ -20,7 +20,7 @@
import { uiModules } from 'ui/modules';
import { npStart } from 'ui/new_platform';
import { createUiStatsReporter, METRIC_TYPE } from '../../../ui_metric/public';
import { TelemetryOptInProvider } from './telemetry_opt_in';
import { TelemetryOptInProvider } from '../../../telemetry/public/services';
export let indexPatternService;
export let shouldShowTelemetryOptIn;

View file

@ -1,18 +1,35 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import sinon from 'sinon';
import { DEFAULT_CSP_RULES } from '../../../../../../../../src/legacy/server/csp';
import {
getMockCallWithInternal,
getMockKbnServer,
getMockTaskFetch,
} from '../../../../test_utils';
import { Server } from 'hapi';
import { DEFAULT_CSP_RULES } from '../../../../../server/csp';
import { createCspCollector } from './csp_collector';
interface MockConfig {
get: (x: string) => any;
}
const getMockKbnServer = (mockConfig: MockConfig) => ({
config: () => mockConfig,
});
test('fetches whether strict mode is enabled', async () => {
const { collector, mockConfig } = setupCollector();
@ -72,7 +89,7 @@ function setupCollector() {
mockConfig.get.withArgs('csp.strict').returns(true);
mockConfig.get.withArgs('csp.warnLegacyBrowsers').returns(true);
const mockKbnServer = getMockKbnServer(getMockCallWithInternal(), getMockTaskFetch(), mockConfig);
const mockKbnServer = getMockKbnServer(mockConfig);
return { mockConfig, collector: createCspCollector(mockKbnServer) };
return { mockConfig, collector: createCspCollector(mockKbnServer as Server) };
}

View file

@ -0,0 +1,49 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Server } from 'hapi';
import { createCSPRuleString, DEFAULT_CSP_RULES } from '../../../../../server/csp';
export function createCspCollector(server: Server) {
return {
type: 'csp',
isReady: () => true,
async fetch() {
const config = server.config();
// It's important that we do not send the value of csp.rules here as it
// can be customized with values that can be identifiable to given
// installs, such as URLs
const defaultRulesString = createCSPRuleString([...DEFAULT_CSP_RULES]);
const actualRulesString = createCSPRuleString(config.get('csp.rules'));
return {
strict: config.get('csp.strict'),
warnLegacyBrowsers: config.get('csp.warnLegacyBrowsers'),
rulesChangedFromDefault: defaultRulesString !== actualRulesString,
};
},
};
}
export function registerCspCollector(server: Server): void {
const { collectorSet } = server.usage;
const collector = collectorSet.makeUsageCollector(createCspCollector(server));
collectorSet.register(collector);
}

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { registerCspCollector } from './csp_collector';

View file

@ -0,0 +1,66 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { i18n } from '@kbn/i18n';
/*
* config options opt into telemetry
* @type {string}
*/
export const CONFIG_TELEMETRY = 'telemetry:optIn';
/*
* config description for opting into telemetry
* @type {string}
*/
export const getConfigTelemetryDesc = () => {
return i18n.translate('telemetry.telemetryConfigDescription', {
defaultMessage:
'Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.',
});
};
/**
* The amount of time, in milliseconds, to wait between reports when enabled.
*
* Currently 24 hours.
* @type {Number}
*/
export const REPORT_INTERVAL_MS = 86400000;
/*
* Key for the localStorage service
*/
export const LOCALSTORAGE_KEY = 'telemetry.data';
/**
* Link to the Elastic Telemetry privacy statement.
*/
export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/telemetry-privacy-statement`;
/**
* The type name used within the Monitoring index to publish localization stats.
* @type {string}
*/
export const KIBANA_LOCALIZATION_STATS_TYPE = 'localization';
/**
* UI metric usage type
* @type {string}
*/
export const UI_METRIC_USAGE_TYPE = 'ui_metric';

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { KibanaConfig } from 'src/legacy/server/kbn_server';
export function getXpackConfigWithDeprecated(config: KibanaConfig, configPath: string) {
try {
const deprecatedXpackmainConfig = config.get(`xpack.xpack_main.${configPath}`);
if (typeof deprecatedXpackmainConfig !== 'undefined') {
return deprecatedXpackmainConfig;
}
} catch (err) {
// swallow error
}
try {
const deprecatedXpackConfig = config.get(`xpack.${configPath}`);
if (typeof deprecatedXpackConfig !== 'undefined') {
return deprecatedXpackConfig;
}
} catch (err) {
// swallow error
}
return config.get(configPath);
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { resolve } from 'path';
@ -9,10 +22,11 @@ import JoiNamespace from 'joi';
import { Server } from 'hapi';
import { CoreSetup, PluginInitializerContext } from 'src/core/server';
import { i18n } from '@kbn/i18n';
// @ts-ignore
import mappings from './mappings.json';
import { CONFIG_TELEMETRY, getConfigTelemetryDesc, REPORT_INTERVAL_MS } from './common/constants';
import { CONFIG_TELEMETRY, getConfigTelemetryDesc } from './common/constants';
import { getXpackConfigWithDeprecated } from './common/get_xpack_config_with_deprecated';
import { telemetryPlugin } from './server';
import { telemetryPlugin, getTelemetryOptIn } from './server';
import {
createLocalizationUsageCollector,
@ -22,10 +36,10 @@ import {
const ENDPOINT_VERSION = 'v2';
export const telemetry = (kibana: any) => {
const telemetry = (kibana: any) => {
return new kibana.Plugin({
id: 'telemetry',
configPrefix: 'xpack.telemetry',
configPrefix: 'telemetry',
publicDir: resolve(__dirname, 'public'),
require: ['elasticsearch'],
config(Joi: typeof JoiNamespace) {
@ -49,7 +63,7 @@ export const telemetry = (kibana: any) => {
managementSections: ['plugins/telemetry/views/management'],
uiSettingDefaults: {
[CONFIG_TELEMETRY]: {
name: i18n.translate('xpack.telemetry.telemetryConfigTitle', {
name: i18n.translate('telemetry.telemetryConfigTitle', {
defaultMessage: 'Telemetry opt-in',
}),
description: getConfigTelemetryDesc(),
@ -62,11 +76,20 @@ export const telemetry = (kibana: any) => {
isNamespaceAgnostic: true,
},
},
async replaceInjectedVars(originalInjectedVars: any, request: any) {
const telemetryOptedIn = await getTelemetryOptIn(request);
return {
...originalInjectedVars,
telemetryOptedIn,
};
},
injectDefaultVars(server: Server) {
const config = server.config();
return {
telemetryEnabled: getXpackConfigWithDeprecated(config, 'telemetry.enabled'),
telemetryUrl: getXpackConfigWithDeprecated(config, 'telemetry.url'),
telemetryBanner: config.get('xpack.telemetry.banner'),
telemetryBanner: getXpackConfigWithDeprecated(config, 'telemetry.banner'),
telemetryOptedIn: null,
};
},
@ -75,8 +98,10 @@ export const telemetry = (kibana: any) => {
},
init(server: Server) {
const initializerContext = {} as PluginInitializerContext;
const coreSetup = ({
http: { server },
log: server.log,
} as any) as CoreSetup;
telemetryPlugin(initializerContext).setup(coreSetup);
@ -85,9 +110,9 @@ export const telemetry = (kibana: any) => {
server.usage.collectorSet.register(createLocalizationUsageCollector(server));
server.usage.collectorSet.register(createTelemetryUsageCollector(server));
server.usage.collectorSet.register(createUiMetricUsageCollector(server));
// expose
server.expose('telemetryCollectionInterval', REPORT_INTERVAL_MS);
},
});
};
// eslint-disable-next-line import/no-default-export
export default telemetry;

View file

@ -0,0 +1,4 @@
{
"name": "telemetry",
"version": "kibana"
}

View file

@ -15,7 +15,7 @@ exports[`OptInDetailsComponent renders as expected 1`] = `
<h2>
<FormattedMessage
defaultMessage="Cluster statistics"
id="xpack.telemetry.callout.clusterStatisticsTitle"
id="telemetry.callout.clusterStatisticsTitle"
values={Object {}}
/>
</h2>
@ -26,7 +26,7 @@ exports[`OptInDetailsComponent renders as expected 1`] = `
<EuiText>
<FormattedMessage
defaultMessage="This is an example of the basic cluster statistics that we'll collect. It includes the number of indices, shards, and nodes. It also includes high-level usage statistics, such as whether monitoring is turned on."
id="xpack.telemetry.callout.clusterStatisticsDescription"
id="telemetry.callout.clusterStatisticsDescription"
values={Object {}}
/>
</EuiText>

View file

@ -16,7 +16,7 @@ exports[`TelemetryForm renders as expected 1`] = `
<h2>
<FormattedMessage
defaultMessage="Usage Data"
id="xpack.telemetry.usageDataTitle"
id="telemetry.usageDataTitle"
values={Object {}}
/>
</h2>
@ -43,7 +43,7 @@ exports[`TelemetryForm renders as expected 1`] = `
>
<FormattedMessage
defaultMessage="See an example of what we collect"
id="xpack.telemetry.seeExampleOfWhatWeCollectLinkText"
id="telemetry.seeExampleOfWhatWeCollectLinkText"
values={Object {}}
/>
</ForwardRef>
@ -55,7 +55,7 @@ exports[`TelemetryForm renders as expected 1`] = `
>
<FormattedMessage
defaultMessage="Read our usage data privacy statement"
id="xpack.telemetry.readOurUsageDataPrivacyStatementLinkText"
id="telemetry.readOurUsageDataPrivacyStatementLinkText"
values={Object {}}
/>
</ForwardRef>

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-ignore
export { TelemetryForm } from './telemetry_form';
export { OptInExampleFlyout } from './opt_in_details_component';
export { OptInBanner } from './opt_in_banner_component';
export { OptInMessage } from './opt_in_message';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import * as React from 'react';
@ -21,7 +34,7 @@ export class OptInBanner extends React.PureComponent<Props> {
render() {
const title = (
<FormattedMessage
id="xpack.telemetry.welcomeBanner.title"
id="telemetry.welcomeBanner.title"
defaultMessage="Help us improve the Elastic Stack!"
/>
);
@ -32,18 +45,12 @@ export class OptInBanner extends React.PureComponent<Props> {
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiButton size="s" onClick={() => this.props.optInClick(true)}>
<FormattedMessage
id="xpack.telemetry.welcomeBanner.yesButtonLabel"
defaultMessage="Yes"
/>
<FormattedMessage id="telemetry.welcomeBanner.yesButtonLabel" defaultMessage="Yes" />
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton size="s" onClick={() => this.props.optInClick(false)}>
<FormattedMessage
id="xpack.telemetry.welcomeBanner.noButtonLabel"
defaultMessage="No"
/>
<FormattedMessage id="telemetry.welcomeBanner.noButtonLabel" defaultMessage="No" />
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>

View file

@ -0,0 +1,34 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { OptInExampleFlyout } from './opt_in_details_component';
describe('OptInDetailsComponent', () => {
it('renders as expected', () => {
expect(
shallowWithIntl(
<OptInExampleFlyout
fetchTelemetry={jest.fn(async () => ({ data: [] }))}
onClose={jest.fn()}
/>
)
).toMatchSnapshot();
});
});

View file

@ -91,7 +91,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
<EuiCallOut
title={
<FormattedMessage
id="kbn.home.telemetry.callout.errorUnprivilegedUserTitle"
id="telemetry.callout.errorUnprivilegedUserTitle"
defaultMessage="Error displaying cluster statistics"
/>
}
@ -99,7 +99,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
iconType="cross"
>
<FormattedMessage
id="kbn.home.telemetry.callout.errorUnprivilegedUserDescription"
id="telemetry.callout.errorUnprivilegedUserDescription"
defaultMessage="You do not have access to see unencrypted cluster statistics."
/>
</EuiCallOut>
@ -111,7 +111,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
<EuiCallOut
title={
<FormattedMessage
id="kbn.home.telemetry.callout.errorLoadingClusterStatisticsTitle"
id="telemetry.callout.errorLoadingClusterStatisticsTitle"
defaultMessage="Error loading cluster statistics"
/>
}
@ -119,7 +119,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
iconType="cross"
>
<FormattedMessage
id="kbn.home.telemetry.callout.errorLoadingClusterStatisticsDescription"
id="telemetry.callout.errorLoadingClusterStatisticsDescription"
defaultMessage="An unexpected error occured while attempting to fetch the cluster statistics.
This can occur because Elasticsearch failed, Kibana failed, or there is a network error.
Check Kibana, then reload the page and try again."
@ -139,7 +139,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
<EuiTitle>
<h2>
<FormattedMessage
id="kbn.home.telemetry.callout.clusterStatisticsTitle"
id="telemetry.callout.clusterStatisticsTitle"
defaultMessage="Cluster statistics"
/>
</h2>
@ -147,7 +147,7 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
<EuiTextColor color="subdued">
<EuiText>
<FormattedMessage
id="kbn.home.telemetry.callout.clusterStatisticsDescription"
id="telemetry.callout.clusterStatisticsDescription"
defaultMessage="This is an example of the basic cluster statistics that we'll collect.
It includes the number of indices, shards, and nodes.
It also includes high-level usage statistics, such as whether monitoring is turned on."

View file

@ -20,6 +20,8 @@
import * as React from 'react';
import { EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../common/constants';
import { OptInExampleFlyout } from './opt_in_details_component';
interface Props {
@ -44,29 +46,27 @@ export class OptInMessage extends React.PureComponent<Props, State> {
};
render() {
const { fetchTelemetry } = this.props;
const { showDetails, showExample } = this.state;
const getDetails = () => (
<FormattedMessage
id="kbn.home.telemetry.optInMessage.detailsDescription"
defaultMessage="No information about the data you process or store will be sent. This feature will periodically send basic feature usage statistics. See an {exampleLink} or read our {telemetryPrivacyStatementLink}. You can disable this feature at any time."
id="telemetry.welcomeBanner.telemetryConfigDetailsDescription"
defaultMessage="No information about the data you process or store will be sent. This feature
will periodically send basic feature usage statistics. See an {exampleLink} or read our {telemetryPrivacyStatementLink}.
You can disable this feature at any time."
values={{
exampleLink: (
<EuiLink onClick={this.toggleShowExample}>
<FormattedMessage
id="kbn.home.telemetry.optInMessage.detailsExampleLinkText"
id="telemetry.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText"
defaultMessage="example"
/>
</EuiLink>
),
telemetryPrivacyStatementLink: (
<EuiLink
href="https://www.elastic.co/legal/telemetry-privacy-statement"
target="_blank"
>
<EuiLink href={PRIVACY_STATEMENT_URL} target="_blank">
<FormattedMessage
id="kbn.home.telemetry.optInMessage.detailsTelemetryPrivacyStatementLinkText"
id="telemetry.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText"
defaultMessage="telemetry privacy statement"
/>
</EuiLink>
@ -78,14 +78,14 @@ export class OptInMessage extends React.PureComponent<Props, State> {
const getFlyoutDetails = () => (
<OptInExampleFlyout
onClose={() => this.setState({ showExample: false })}
fetchTelemetry={fetchTelemetry}
fetchTelemetry={this.props.fetchTelemetry}
/>
);
const getReadMore = () => (
<EuiLink onClick={() => this.setState({ showDetails: true })}>
<FormattedMessage
id="kbn.home.telemetry.optInMessage.readMoreLinkText"
id="telemetry.welcomeBanner.telemetryConfigDescription.readMoreLinkText"
defaultMessage="Read more"
/>
</EuiLink>
@ -93,13 +93,13 @@ export class OptInMessage extends React.PureComponent<Props, State> {
return (
<React.Fragment>
<FormattedMessage
id="kbn.home.telemetry.optInMessageDescription"
defaultMessage="Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic."
/>{' '}
{!showDetails && getReadMore()}
{showDetails && getDetails()}
{showDetails && showExample && getFlyoutDetails()}
{getConfigTelemetryDesc()} {!showDetails && getReadMore()}
{showDetails && (
<span style={{ display: 'block', paddingTop: '10px' }}>
{getDetails()}
{showExample && getFlyoutDetails()}
</span>
)}
</React.Fragment>
);
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { Component, Fragment } from 'react';
@ -28,8 +41,7 @@ export class TelemetryForm extends Component {
telemetryOptInProvider: PropTypes.object.isRequired,
query: PropTypes.object,
onQueryMatchChange: PropTypes.func.isRequired,
spacesEnabled: PropTypes.bool.isRequired,
activeSpace: PropTypes.object,
showAppliesSettingMessage: PropTypes.bool.isRequired,
enableSaving: PropTypes.bool.isRequired,
};
@ -85,7 +97,7 @@ export class TelemetryForm extends Component {
<EuiFlexItem grow={false}>
<h2>
<FormattedMessage
id="xpack.telemetry.usageDataTitle"
id="telemetry.usageDataTitle"
defaultMessage="Usage Data"
/>
</h2>
@ -93,7 +105,7 @@ export class TelemetryForm extends Component {
</EuiFlexGroup>
</EuiText>
{this.maybeGetSpacesWarning()}
{this.maybeGetAppliesSettingMessage()}
<EuiSpacer size="s" />
<Field
setting={{
@ -112,8 +124,8 @@ export class TelemetryForm extends Component {
);
}
maybeGetSpacesWarning = () => {
if (!this.props.spacesEnabled) {
maybeGetAppliesSettingMessage = () => {
if (!this.props.showAppliesSettingMessage) {
return null;
}
return (
@ -123,13 +135,13 @@ export class TelemetryForm extends Component {
title={
<p>
<FormattedMessage
id="xpack.telemetry.callout.appliesSettingTitle"
id="telemetry.callout.appliesSettingTitle"
defaultMessage="This setting applies to {allOfKibanaText}"
values={{
allOfKibanaText: (
<strong>
<FormattedMessage
id="xpack.telemetry.callout.appliesSettingTitle.allOfKibanaText"
id="telemetry.callout.appliesSettingTitle.allOfKibanaText"
defaultMessage="all of Kibana."
/>
</strong>
@ -148,7 +160,7 @@ export class TelemetryForm extends Component {
<p>
<EuiLink onClick={this.toggleExample}>
<FormattedMessage
id="xpack.telemetry.seeExampleOfWhatWeCollectLinkText"
id="telemetry.seeExampleOfWhatWeCollectLinkText"
defaultMessage="See an example of what we collect"
/>
</EuiLink>
@ -156,7 +168,7 @@ export class TelemetryForm extends Component {
<p>
<EuiLink href={PRIVACY_STATEMENT_URL} target="_blank">
<FormattedMessage
id="xpack.telemetry.readOurUsageDataPrivacyStatementLinkText"
id="telemetry.readOurUsageDataPrivacyStatementLinkText"
defaultMessage="Read our usage data privacy statement"
/>
</EuiLink>

View file

@ -1,14 +1,27 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import '../services/telemetry_opt_in.test.mocks';
import React from 'react';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { TelemetryForm } from './telemetry_form';
import { TelemetryOptInProvider } from '../services/telemetry_opt_in';
import { TelemetryOptInProvider } from '../services';
const buildTelemetryOptInProvider = () => {
const mockHttp = {

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from '@kbn/expect';

View file

@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { uiModules } from 'ui/modules';
// This overrides settings for other UI tests
uiModules.get('kibana')
// disable stat reporting while running tests,
// MockInjector used in these tests is not impacted
.constant('telemetryEnabled', false)
.constant('telemetryOptedIn', null)
.constant('telemetryUrl', 'not.a.valid.url.0');

View file

@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import uiChrome from 'ui/chrome';
import moment from 'moment';
/**
* Fetch Telemetry data by calling the Kibana API.
*
* @param {Object} $http The HTTP handler
* @param {String} basePath The base URI
* @param {Function} _moment moment.js, but injectable for tests
* @return {Promise} An array of cluster Telemetry objects.
*/
export function fetchTelemetry($http, { basePath = uiChrome.getBasePath(), _moment = moment, unencrypted = false } = { }) {
return $http.post(`${basePath}/api/telemetry/v2/clusters/_stats`, {
unencrypted,
timeRange: {
min: _moment().subtract(20, 'minutes').toISOString(),
max: _moment().toISOString()
}
});
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Telemetry } from './telemetry';

View file

@ -0,0 +1,45 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { npStart } from 'ui/new_platform';
// @ts-ignore
import { uiModules } from 'ui/modules';
import { isUnauthenticated } from '../services';
// @ts-ignore
import { Telemetry } from './telemetry';
// @ts-ignore
import { fetchTelemetry } from './fetch_telemetry';
function telemetryInit($injector: any) {
const $http = $injector.get('$http');
const telemetryEnabled = npStart.core.injectedMetadata.getInjectedVar('telemetryEnabled');
if (telemetryEnabled) {
// no telemetry for non-logged in users
if (isUnauthenticated()) {
return;
}
const sender = new Telemetry($injector, () => fetchTelemetry($http));
sender.start();
}
}
uiModules.get('telemetry/hacks').run(telemetryInit);

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { uiModules } from 'ui/modules';
import { injectBanner } from './welcome_banner';
uiModules.get('telemetry/hacks').run(injectBanner);

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
@ -41,7 +54,7 @@ export async function clickBanner(
_toastNotifications.addDanger({
title: (
<FormattedMessage
id="xpack.telemetry.telemetryErrorNotificationMessageTitle"
id="telemetry.telemetryErrorNotificationMessageTitle"
defaultMessage="Telemetry Error"
/>
),
@ -49,13 +62,13 @@ export async function clickBanner(
<EuiText>
<p>
<FormattedMessage
id="xpack.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText"
id="telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText"
defaultMessage="Unable to save telemetry preference."
/>
</p>
<EuiText size="xs">
<FormattedMessage
id="xpack.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText"
id="telemetry.telemetryErrorNotificationMessageDescription.tryAgainText"
defaultMessage="Check that Kibana and Elasticsearch are still running, then try again."
/>
</EuiText>

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mockInjectedMetadata } from '../../services/telemetry_opt_in.test.mocks';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { CONFIG_TELEMETRY } from '../../../common/constants';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mockInjectedMetadata } from '../../services/telemetry_opt_in.test.mocks';

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { injectBanner } from './inject_banner';

View file

@ -1,15 +1,28 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import chrome from 'ui/chrome';
import { Path } from 'plugins/xpack_main/services/path';
import { fetchTelemetry } from '../fetch_telemetry';
import { renderBanner } from './render_banner';
import { shouldShowBanner } from './should_show_banner';
import { TelemetryOptInProvider } from '../../services/telemetry_opt_in';
import { TelemetryOptInProvider, isUnauthenticated } from '../../services';
import { npStart } from 'ui/new_platform';
/**
@ -26,7 +39,7 @@ async function asyncInjectBanner($injector) {
const config = $injector.get('config');
// and no banner for non-logged in users
if (Path.isUnauthenticated()) {
if (isUnauthenticated()) {
return;
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';

View file

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import '../../services/telemetry_opt_in.test.mocks';
import { renderBanner } from './render_banner';
describe('render_banner', () => {
it('adds a banner to banners with priority of 10000', () => {
const bannerID = 'brucer-banner';
const telemetryOptInProvider = { setBannerId: jest.fn() };
const banners = { add: jest.fn().mockReturnValue(bannerID) };
const fetchTelemetry = jest.fn();
renderBanner(telemetryOptInProvider, fetchTelemetry, { _banners: banners });
expect(banners.add).toBeCalledTimes(1);
expect(fetchTelemetry).toBeCalledTimes(0);
expect(telemetryOptInProvider.setBannerId).toBeCalledWith(bannerID);
const bannerConfig = banners.add.mock.calls[0][0];
expect(bannerConfig.component).not.toBe(undefined);
expect(bannerConfig.priority).toBe(10000);
});
});

View file

@ -0,0 +1,33 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { handleOldSettings } from './handle_old_settings';
/**
* Determine if the banner should be displayed.
*
* This method can have side-effects related to deprecated config settings.
*
* @param {Object} config The advanced settings config object.
* @param {Object} _handleOldSettings handleOldSettings function, but overridable for tests.
* @return {Boolean} {@code true} if the banner should be displayed. {@code false} otherwise.
*/
export async function shouldShowBanner(telemetryOptInProvider, config, { _handleOldSettings = handleOldSettings } = {}) {
return telemetryOptInProvider.getOptIn() === null && await _handleOldSettings(config, telemetryOptInProvider);
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mockInjectedMetadata } from '../../services/telemetry_opt_in.test.mocks';
@ -10,7 +23,7 @@ import sinon from 'sinon';
import { CONFIG_TELEMETRY } from '../../../common/constants';
import { shouldShowBanner } from './should_show_banner';
import { TelemetryOptInProvider } from '../../services/telemetry_opt_in';
import { TelemetryOptInProvider } from '../../services';
const getMockInjector = () => {
const get = sinon.stub();

View file

@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { TelemetryOptInProvider } from './telemetry_opt_in';
export { isUnauthenticated } from './path';

View file

@ -0,0 +1,25 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import chrome from 'ui/chrome';
export function isUnauthenticated() {
const path = (chrome as any).removeBasePath(window.location.pathname);
return path === '/login' || path === '/logout' || path === '/logged_out' || path === '/status';
}

View file

@ -1,8 +1,22 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mockInjectedMetadata } from './telemetry_opt_in.test.mocks';
import { TelemetryOptInProvider } from './telemetry_opt_in';

View file

@ -0,0 +1,50 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {
injectedMetadataServiceMock,
notificationServiceMock,
overlayServiceMock,
} from '../../../../../core/public/mocks';
const injectedMetadataMock = injectedMetadataServiceMock.createStartContract();
export function mockInjectedMetadata({ telemetryOptedIn }) {
const mockGetInjectedVar = jest.fn().mockImplementation((key) => {
switch (key) {
case 'telemetryOptedIn': return telemetryOptedIn;
default: throw new Error(`unexpected injectedVar ${key}`);
}
});
injectedMetadataMock.getInjectedVar = mockGetInjectedVar;
}
jest.doMock('ui/new_platform', () => ({
npSetup: {
core: {
notifications: notificationServiceMock.createSetupContract(),
}
},
npStart: {
core: {
injectedMetadata: injectedMetadataMock,
overlays: overlayServiceMock.createStartContract(),
},
},
}));

View file

@ -23,16 +23,20 @@ import { toastNotifications } from 'ui/notify';
import { npStart } from 'ui/new_platform';
import { i18n } from '@kbn/i18n';
export function TelemetryOptInProvider($injector, chrome) {
let currentOptInStatus = npStart.core.injectedMetadata.getInjectedVar('telemetryOptedIn');
let bannerId = null;
let bannerId: string | null = null;
let currentOptInStatus = false;
export function TelemetryOptInProvider($injector: any, chrome: any) {
currentOptInStatus = npStart.core.injectedMetadata.getInjectedVar('telemetryOptedIn') as boolean;
setCanTrackUiMetrics(currentOptInStatus);
const provider = {
getBannerId: () => bannerId,
getOptIn: () => currentOptInStatus,
setBannerId(id) { bannerId = id; },
setOptIn: async (enabled) => {
setBannerId(id: string) {
bannerId = id;
},
setOptIn: async (enabled: boolean) => {
setCanTrackUiMetrics(enabled);
const $http = $injector.get('$http');
@ -41,10 +45,10 @@ export function TelemetryOptInProvider($injector, chrome) {
currentOptInStatus = enabled;
} catch (error) {
toastNotifications.addError(error, {
title: i18n.translate('kbn.home.telemetry.optInErrorToastTitle', {
title: i18n.translate('telemetry.optInErrorToastTitle', {
defaultMessage: 'Error',
}),
toastMessage: i18n.translate('kbn.home.telemetry.optInErrorToastText', {
toastMessage: i18n.translate('telemetry.optInErrorToastText', {
defaultMessage: 'An error occured while trying to set the usage statistics preference.',
}),
});
@ -58,11 +62,13 @@ export function TelemetryOptInProvider($injector, chrome) {
return $http.post(chrome.addBasePath(`/api/telemetry/v2/clusters/_stats`), {
unencrypted: true,
timeRange: {
min: moment().subtract(20, 'minutes').toISOString(),
max: moment().toISOString()
}
min: moment()
.subtract(20, 'minutes')
.toISOString(),
max: moment().toISOString(),
},
});
}
},
};
return provider;

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import './management';

View file

@ -0,0 +1,42 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import routes from 'ui/routes';
import { registerSettingsComponent, PAGE_FOOTER_COMPONENT } from 'ui/management';
import { TelemetryOptInProvider } from '../../services';
import { TelemetryForm } from '../../components';
routes.defaults(/\/management/, {
resolve: {
telemetryManagementSection: function (Private) {
const telemetryOptInProvider = Private(TelemetryOptInProvider);
const Component = (props) => (
<TelemetryForm
showAppliesSettingMessage={true}
telemetryOptInProvider={telemetryOptInProvider}
{...props}
/>
);
registerSettingsComponent(PAGE_FOOTER_COMPONENT, Component, true);
}
}
});

View file

@ -0,0 +1,49 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
class TelemetryCollectionManager {
private getterMethod?: any;
private collectionTitle?: string;
private getterMethodPriority = 0;
public setStatsGetter = (statsGetter: any, title: string, priority = 0) => {
if (priority >= this.getterMethodPriority) {
this.getterMethod = statsGetter;
this.collectionTitle = title;
this.getterMethodPriority = priority;
}
};
getCollectionTitle = () => {
return this.collectionTitle;
};
public getStatsGetter = () => {
if (!this.getterMethod) {
throw Error('Stats getter method not set.');
}
return {
getStats: this.getterMethod,
priority: this.getterMethodPriority,
title: this.collectionTitle,
};
};
}
export const telemetryCollectionManager = new TelemetryCollectionManager();

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { telemetryJWKS } from './telemetry_jwks';

View file

@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { createRequestEncryptor } from '@elastic/request-crypto';
import { telemetryJWKS } from './telemetry_jwks';
export function getKID(isProd = false): string {
return isProd ? 'kibana' : 'kibana_dev';
}
export async function encryptTelemetry(payload: any, isProd = false): Promise<string[]> {
const kid = getKID(isProd);
const encryptor = await createRequestEncryptor(telemetryJWKS);
const clusters = [].concat(payload);
return Promise.all(clusters.map((cluster: any) => encryptor.encrypt(kid, cluster)));
}

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { encryptTelemetry } from './encrypt';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { PublicJWKS } from '@elastic/request-crypto';

View file

@ -0,0 +1,23 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { encryptTelemetry } from './encryption';
export { createTelemetryUsageCollector } from './usage';
export { createUiMetricUsageCollector } from './ui_metric';
export { createLocalizationUsageCollector } from './localization';

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Readable } from 'stream';
jest.doMock('fs', () => ({
createReadStream(filepath: string): Readable {
if (filepath === 'ERROR') {
throw new Error('MOCK ERROR - Invalid Path');
}
const readableStream = new Readable();
const streamData = filepath.split('');
let cursor = 0;
readableStream._read = function(size) {
const current = streamData[cursor++];
if (typeof current === 'undefined') {
return this.push(null);
}
this.push(current);
};
return readableStream;
},
}));

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import './file_integrity.test.mocks';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { createHash } from 'crypto';

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { createLocalizationUsageCollector } from './telemetry_localization_collector';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
interface TranslationsMock {

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { i18nLoader } from '@kbn/i18n';

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { createUiMetricUsageCollector } from './telemetry_ui_metric_collector';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { UI_METRIC_USAGE_TYPE } from '../../../common/constants';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ensureDeepObject } from './ensure_deep_object';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//

View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { createTelemetryUsageCollector } from './telemetry_usage_collector';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { writeFileSync, unlinkSync } from 'fs';
@ -28,8 +41,8 @@ const serverWithConfig = (configPath: string): KibanaHapiServer & Server => {
...getMockServer(),
config: () => ({
get: (key: string) => {
if (key !== 'xpack.telemetry.config' && key !== 'xpack.xpack_main.telemetry.config') {
throw new Error('Expected `xpack.telemetry.config`');
if (key !== 'telemetry.config' && key !== 'xpack.xpack_main.telemetry.config') {
throw new Error('Expected `telemetry.config`');
}
return configPath;

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { accessSync, constants, readFileSync, statSync } from 'fs';

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export async function getTelemetryOptIn(request: any) {

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { PluginInitializerContext } from 'src/core/server';
import { TelemetryPlugin } from './plugin';
import * as constants from '../common/constants';
export { getTelemetryOptIn } from './get_telemetry_opt_in';
export { telemetryCollectionManager } from './collection_manager';
export const telemetryPlugin = (initializerContext: PluginInitializerContext) =>
new TelemetryPlugin();
export { constants };

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { CoreSetup } from 'src/core/server';
import { registerRoutes } from './routes';
import { telemetryCollectionManager } from './collection_manager';
import { getStats } from './telemetry_collection';
export class TelemetryPlugin {
public setup(core: CoreSetup) {
telemetryCollectionManager.setStatsGetter(getStats, 'local');
registerRoutes(core);
}
}

View file

@ -0,0 +1,27 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { CoreSetup } from 'src/core/server';
import { registerOptInRoutes } from './opt_in';
import { registerTelemetryDataRoutes } from './telemetry_stats';
export function registerRoutes(core: CoreSetup) {
registerOptInRoutes(core);
registerTelemetryDataRoutes(core);
}

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Joi from 'joi';

View file

@ -1,13 +1,27 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Joi from 'joi';
import { boomify } from 'boom';
import { CoreSetup } from 'src/core/server';
import { getStats, encryptTelemetry } from '../collectors';
import { encryptTelemetry } from '../collectors';
import { telemetryCollectionManager } from '../collection_manager';
export function registerTelemetryDataRoutes(core: CoreSetup) {
const { server } = core.http as any;
@ -34,13 +48,17 @@ export function registerTelemetryDataRoutes(core: CoreSetup) {
const isDev = config.get('env.dev');
try {
const { getStats, title } = telemetryCollectionManager.getStatsGetter();
server.log(['debug', 'telemetry'], `Using Stats Getter: ${title}`);
const usageData = await getStats(req, config, start, end, unencrypted);
if (unencrypted) return usageData;
return encryptTelemetry(usageData, isDev);
} catch (err) {
if (isDev) {
// don't ignore errors when running in dev mode
return boomify(err, { statusCode: err.status });
return boomify(err, { statusCode: err.status || 500 });
} else {
const statusCode = unencrypted && err.status === 403 ? 403 : 200;
// ignore errors and return empty set

View file

@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from '@kbn/expect';
import sinon from 'sinon';
import { getClusterInfo } from '../get_cluster_info';
export function mockGetClusterInfo(callCluster, clusterInfo, req) {
callCluster.withArgs(req, 'info').returns(clusterInfo);
callCluster.withArgs('info').returns(clusterInfo);
}
describe('get_cluster_info', () => {
it('uses callCluster to get info API', () => {
const callCluster = sinon.stub();
const response = Promise.resolve({});
mockGetClusterInfo(callCluster, response);
expect(getClusterInfo(callCluster)).to.be(response);
});
});

View file

@ -0,0 +1,49 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from '@kbn/expect';
import sinon from 'sinon';
import { TIMEOUT } from '../constants';
import { getClusterStats } from '../get_cluster_stats';
export function mockGetClusterStats(callCluster, clusterStats, req) {
callCluster.withArgs(req, 'cluster.stats', {
timeout: TIMEOUT
})
.returns(clusterStats);
callCluster.withArgs('cluster.stats', {
timeout: TIMEOUT
})
.returns(clusterStats);
}
describe('get_cluster_stats', () => {
it('uses callCluster to get cluster.stats API', () => {
const callCluster = sinon.stub();
const response = Promise.resolve({});
mockGetClusterStats(callCluster, response);
expect(getClusterStats(callCluster)).to.be(response);
});
});

View file

@ -1,7 +1,20 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import expect from '@kbn/expect';
@ -9,7 +22,6 @@ import sinon from 'sinon';
import { mockGetClusterInfo } from './get_cluster_info';
import { mockGetClusterStats } from './get_cluster_stats';
import { mockGetXPack } from './get_xpack';
import { omit } from 'lodash';
import {
@ -22,17 +34,25 @@ const getMockServer = (getCluster = sinon.stub(), kibanaUsage = {}) => ({
log(tags, message) {
console.log({ tags, message });
},
config() {
return {
get(item) {
switch(item) {
case 'pkg.version': return '8675309-snapshot';
default: throw Error(`unexpected config.get('${item}') received.`);
}
}
};
},
usage: { collectorSet: { bulkFetch: () => kibanaUsage, toObject: data => data } },
plugins: {
xpack_main: { status: { plugin: { kbnServer: { version: '8675309-snapshot' } } } },
elasticsearch: { getCluster },
},
});
function mockGetLocalStats(callCluster, clusterInfo, clusterStats, license, usage, req) {
function mockGetLocalStats(callCluster, clusterInfo, clusterStats, req) {
mockGetClusterInfo(callCluster, clusterInfo, req);
mockGetClusterStats(callCluster, clusterStats, req);
mockGetXPack(callCluster, license, usage, req);
}
describe('get_local_stats', () => {
@ -53,8 +73,6 @@ describe('get_local_stats', () => {
nodes: { yup: 'abc' },
random: 123
};
const license = { fancy: 'license' };
const xpack = { also: 'fancy' };
const kibana = {
kibana: {
great: 'googlymoogly',
@ -81,9 +99,6 @@ describe('get_local_stats', () => {
collection: 'local',
cluster_uuid: clusterUuid,
cluster_name: clusterName,
license: {
fancy: 'license'
},
version,
cluster_stats: omit(clusterStats, '_nodes', 'cluster_name'),
stack_stats: {
@ -108,7 +123,6 @@ describe('get_local_stats', () => {
snow: { chances: 0 },
}
},
xpack: { also: 'fancy' },
}
};
@ -121,11 +135,11 @@ describe('get_local_stats', () => {
expect(result.version).to.be('2.3.4');
expect(result.collection).to.be('local');
expect(result.license).to.be(undefined);
expect(result.stack_stats).to.eql({ kibana: undefined, xpack: undefined });
expect(result.stack_stats).to.eql({ kibana: undefined });
});
it('returns expected object with xpack', () => {
const result = handleLocalStats(getMockServer(), clusterInfo, clusterStats, license, xpack);
const result = handleLocalStats(getMockServer(), clusterInfo, clusterStats);
const { stack_stats: stack, ...cluster } = result;
expect(cluster.collection).to.be(combinedStatsResult.collection);
expect(cluster.cluster_uuid).to.be(combinedStatsResult.cluster_uuid);
@ -147,8 +161,6 @@ describe('get_local_stats', () => {
callClusterUsageFailed,
Promise.resolve(clusterInfo),
Promise.resolve(clusterStats),
Promise.resolve(license),
Promise.reject('usage failed')
);
const result = await getLocalStatsWithCaller(getMockServer(), callClusterUsageFailed);
@ -170,8 +182,6 @@ describe('get_local_stats', () => {
callCluster,
Promise.resolve(clusterInfo),
Promise.resolve(clusterStats),
Promise.resolve(license),
Promise.resolve(xpack)
);
const result = await getLocalStatsWithCaller(getMockServer(callCluster, kibana), callCluster);
@ -192,8 +202,6 @@ describe('get_local_stats', () => {
callWithInternalUser,
Promise.resolve(clusterInfo),
Promise.resolve(clusterStats),
Promise.resolve(license),
Promise.resolve(xpack)
);
const result = await getLocalStats(req, { useInternalUser: true });
@ -213,8 +221,6 @@ describe('get_local_stats', () => {
callWithRequest,
Promise.resolve(clusterInfo),
Promise.resolve(clusterStats),
Promise.resolve(license),
Promise.resolve(xpack),
req
);

View file

@ -0,0 +1,23 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* The timeout used by each request, whenever a timeout can be specified.
*/
export const TIMEOUT = '30s';

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Get the cluster info from the connected cluster.
*
* This is the equivalent to GET /
*
* @param {function} callCluster The callWithInternalUser handler (exposed for testing)
* @return {Promise} The response from Elasticsearch.
*/
export function getClusterInfo(callCluster) {
return callCluster('info');
}

View file

@ -0,0 +1,34 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TIMEOUT } from './constants';
/**
* Get the cluster stats from the connected cluster.
*
* This is the equivalent to GET /_cluster/stats?timeout=30s.
*
* @param {function} callCluster The callWithInternalUser handler (exposed for testing)
* @return {Promise} The response from Elasticsearch equivalent to GET /_cluster/stats.
*/
export function getClusterStats(callCluster) {
return callCluster('cluster.stats', {
timeout: TIMEOUT
});
}

View file

@ -0,0 +1,58 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { get, omit } from 'lodash';
export function handleKibanaStats(server, response) {
if (!response) {
server.log(['warning', 'telemetry', 'local-stats'], 'No Kibana stats returned from usage collectors');
return;
}
const { kibana, kibana_stats: kibanaStats, ...plugins } = response;
const platform = get(kibanaStats, 'os.platform', 'unknown');
const platformRelease = get(kibanaStats, 'os.platformRelease', 'unknown');
const version = server.config().get('pkg.version').replace(/-snapshot/i, '');
// combine core stats (os types, saved objects) with plugin usage stats
// organize the object into the same format as monitoring-enabled telemetry
return {
...omit(kibana, 'index'), // discard index
count: 1,
indices: 1,
os: {
platforms: [{ platform, count: 1 }],
platformReleases: [{ platformRelease, count: 1 }],
},
versions: [{ version, count: 1 }],
plugins,
};
}
/*
* Check user privileges for read access to monitoring
* Pass callWithInternalUser to bulkFetchUsage
*/
export async function getKibana(server, callWithInternalUser) {
const { collectorSet } = server.usage;
const usage = await collectorSet.bulkFetch(callWithInternalUser);
return collectorSet.toObject(usage);
}

View file

@ -1,13 +1,25 @@
/*
* 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.
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { get, omit } from 'lodash';
import { getClusterInfo } from './get_cluster_info';
import { getClusterStats } from './get_cluster_stats';
import { getXPack } from './get_xpack';
import { getKibana, handleKibanaStats } from './get_kibana';
/**
@ -16,10 +28,9 @@ import { getKibana, handleKibanaStats } from './get_kibana';
*
* @param {Object} clusterInfo Cluster info (GET /)
* @param {Object} clusterStats Cluster stats (GET /_cluster/stats)
* @param {Object} xpack License and X-Pack details
* @return {Object} A combined object containing the different responses.
*/
export function handleLocalStats(server, clusterInfo, clusterStats, license, xpack, kibana) {
export function handleLocalStats(server, clusterInfo, clusterStats, kibana) {
return {
timestamp: (new Date()).toISOString(),
cluster_uuid: get(clusterInfo, 'cluster_uuid'),
@ -27,10 +38,8 @@ export function handleLocalStats(server, clusterInfo, clusterStats, license, xpa
version: get(clusterInfo, 'version.number'),
cluster_stats: omit(clusterStats, '_nodes', 'cluster_name'),
collection: 'local',
license,
stack_stats: {
kibana: handleKibanaStats(server, kibana),
xpack,
}
};
}
@ -42,18 +51,17 @@ export function handleLocalStats(server, clusterInfo, clusterStats, license, xpa
* @param {function} callCluster The callWithInternalUser handler (exposed for testing)
* @return {Promise} The object containing the current Elasticsearch cluster's telemetry.
*/
export function getLocalStatsWithCaller(server, callCluster) {
return Promise.all([
export async function getLocalStatsWithCaller(server, callCluster) {
const [ clusterInfo, clusterStats, kibana ] = await Promise.all([
getClusterInfo(callCluster), // cluster info
getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_)
getXPack(callCluster), // { license, xpack }
getKibana(server, callCluster)
]).then(([clusterInfo, clusterStats, { license, xpack }, kibana]) => {
return handleLocalStats(server, clusterInfo, clusterStats, license, xpack, kibana);
}
);
getKibana(server, callCluster),
]);
return handleLocalStats(server, clusterInfo, clusterStats, kibana);
}
/**
* Get statistics for the connected Elasticsearch cluster.
*
@ -61,10 +69,10 @@ export function getLocalStatsWithCaller(server, callCluster) {
* @param {Boolean} useRequestUser callWithRequest, otherwise callWithInternalUser
* @return {Promise} The cluster object containing telemetry.
*/
export function getLocalStats(req, { useInternalUser = false } = {}) {
export async function getLocalStats(req, { useInternalUser = false } = {}) {
const { server } = req;
const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster('data');
const callCluster = useInternalUser ? callWithInternalUser : (...args) => callWithRequest(req, ...args);
return getLocalStatsWithCaller(server, callCluster);
return await getLocalStatsWithCaller(server, callCluster);
}

View file

@ -0,0 +1,45 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-ignore
import { getLocalStats } from './get_local_stats';
/**
* Get the telemetry data.
*
* @param {Object} req The incoming request.
* @param {Object} config Kibana config.
* @param {String} start The start time of the request (likely 20m ago).
* @param {String} end The end time of the request.
* @param {Boolean} unencrypted Is the request payload going to be unencrypted.
* @return {Promise} An array of telemetry objects.
*/
export async function getStats(
req: any,
config: any,
start: string,
end: string,
unencrypted: boolean
) {
return [
await getLocalStats(req, {
useInternalUser: !unencrypted,
}),
];
}

View file

@ -0,0 +1,24 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-ignore
export { getLocalStats } from './get_local_stats';
// @ts-ignore
export { getStats } from './get_stats';

View file

@ -55,6 +55,7 @@ export default function () {
`--elasticsearch.username=${servers.elasticsearch.username}`,
`--elasticsearch.password=${servers.elasticsearch.password}`,
`--kibana.disableWelcomeScreen=true`,
'--telemetry.banner=false',
`--server.maxPayloadBytes=1679958`,
],
},

20
typings/elastic__node_crypto.d.ts vendored Normal file
View file

@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
declare module '@elastic/node-crypto';

View file

@ -25,7 +25,6 @@
"xpack.ml": "legacy/plugins/ml",
"xpack.logstash": "legacy/plugins/logstash",
"xpack.main": "legacy/plugins/xpack_main",
"xpack.telemetry": "legacy/plugins/telemetry",
"xpack.monitoring": "legacy/plugins/monitoring",
"xpack.remoteClusters": "legacy/plugins/remote_clusters",
"xpack.reporting": "legacy/plugins/reporting",

View file

@ -38,7 +38,6 @@ import { upgradeAssistant } from './legacy/plugins/upgrade_assistant';
import { uptime } from './legacy/plugins/uptime';
import { ossTelemetry } from './legacy/plugins/oss_telemetry';
import { fileUpload } from './legacy/plugins/file_upload';
import { telemetry } from './legacy/plugins/telemetry';
import { encryptedSavedObjects } from './legacy/plugins/encrypted_saved_objects';
import { snapshotRestore } from './legacy/plugins/snapshot_restore';
import { transform } from './legacy/plugins/transform';
@ -49,7 +48,6 @@ import { lens } from './legacy/plugins/lens';
module.exports = function (kibana) {
return [
xpackMain(kibana),
telemetry(kibana),
graph(kibana),
monitoring(kibana),
reporting(kibana),

View file

@ -4,10 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { fetchTelemetry } from '../../../telemetry/public/hacks/fetch_telemetry';
export { PRIVACY_STATEMENT_URL } from '../../../telemetry/common/constants';
export { TelemetryOptInProvider } from '../../../telemetry/public/services/telemetry_opt_in';
export { OptInExampleFlyout } from '../../../telemetry/public/components';
import { fetchTelemetry } from '../../../../../../src/legacy/core_plugins/telemetry/public/hacks/fetch_telemetry';
export { PRIVACY_STATEMENT_URL } from '../../../../../../src/legacy/core_plugins/telemetry/common/constants';
export { TelemetryOptInProvider } from '../../../../../../src/legacy/core_plugins/telemetry/public/services';
export { OptInExampleFlyout } from '../../../../../../src/legacy/core_plugins/telemetry/public/components';
let telemetryEnabled;
let httpClient;

View file

@ -155,10 +155,7 @@ export const METRICBEAT_INDEX_NAME_UNIQUE_TOKEN = '-mb-';
// We use this for metricbeat migration to identify specific products that we do not have constants for
export const ELASTICSEARCH_SYSTEM_ID = 'elasticsearch';
export const KIBANA_SYSTEM_ID = 'kibana';
export const BEATS_SYSTEM_ID = 'beats';
export const APM_SYSTEM_ID = 'apm';
export const LOGSTASH_SYSTEM_ID = 'logstash';
/**
* The id of the infra source owned by the monitoring plugin.
*/
@ -181,3 +178,47 @@ export const CODE_PATH_LOGSTASH = 'logstash';
export const CODE_PATH_APM = 'apm';
export const CODE_PATH_LICENSE = 'license';
export const CODE_PATH_LOGS = 'logs';
/**
* The header sent by telemetry service when hitting Elasticsearch to identify query source
* @type {string}
*/
export const TELEMETRY_QUERY_SOURCE = 'TELEMETRY';
/**
* The name of the Kibana System ID used to publish and look up Kibana stats through the Monitoring system.
* @type {string}
*/
export const KIBANA_SYSTEM_ID = 'kibana';
/**
* The name of the Beats System ID used to publish and look up Beats stats through the Monitoring system.
* @type {string}
*/
export const BEATS_SYSTEM_ID = 'beats';
/**
* The name of the Apm System ID used to publish and look up Apm stats through the Monitoring system.
* @type {string}
*/
export const APM_SYSTEM_ID = 'apm';
/**
* The name of the Kibana System ID used to look up Logstash stats through the Monitoring system.
* @type {string}
*/
export const LOGSTASH_SYSTEM_ID = 'logstash';
/**
* The name of the Kibana System ID used to look up Reporting stats through the Monitoring system.
* @type {string}
*/
export const REPORTING_SYSTEM_ID = 'reporting';
/**
* The amount of time, in milliseconds, to wait between collecting kibana stats from es.
*
* Currently 24 hours kept in sync with reporting interval.
* @type {Number}
*/
export const TELEMETRY_COLLECTION_INTERVAL = 86400000;

View file

@ -49,9 +49,6 @@ describe('BulkUploader', () => {
server = {
log: sinon.spy(),
xpackMainPlugin: {
telemetryCollectionInterval: 3000,
},
elasticsearchPlugin: {
createCluster: () => cluster,
getCluster: () => cluster,

View file

@ -10,7 +10,9 @@ import { callClusterFactory } from '../../../xpack_main';
import {
LOGGING_TAG,
KIBANA_MONITORING_LOGGING_TAG,
TELEMETRY_COLLECTION_INTERVAL,
} from '../../common/constants';
import {
sendBulkPayload,
monitoringBulk,
@ -36,7 +38,7 @@ const LOGGING_TAGS = [LOGGING_TAG, KIBANA_MONITORING_LOGGING_TAG];
* @param {Object} xpackInfo server.plugins.xpack_main.info object
*/
export class BulkUploader {
constructor({ config, log, interval, xpackMainPlugin, elasticsearchPlugin, kbnServerStatus, kbnServerVersion }) {
constructor({ config, log, interval, elasticsearchPlugin, kbnServerStatus, kbnServerVersion }) {
if (typeof interval !== 'number') {
throw new Error('interval number of milliseconds is required');
}
@ -44,7 +46,7 @@ export class BulkUploader {
this._timer = null;
this._interval = interval;
this._lastFetchUsageTime = null;
this._usageInterval = xpackMainPlugin.telemetryCollectionInterval;
this._usageInterval = TELEMETRY_COLLECTION_INTERVAL;
this._log = {
debug: message => log(['debug', ...LOGGING_TAGS], message),

View file

@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { MONITORING_SYSTEM_API_VERSION } from '../../../common/constants';
import { KIBANA_SYSTEM_ID } from '../../../../telemetry/common/constants';
import { MONITORING_SYSTEM_API_VERSION, KIBANA_SYSTEM_ID } from '../../../common/constants';
/*
* Send the Kibana usage data to the ES Monitoring Bulk endpoint

View file

@ -10,6 +10,9 @@ import { requireUIRoutes } from './routes';
import { instantiateClient } from './es_client/instantiate_client';
import { initMonitoringXpackInfo } from './init_monitoring_xpack_info';
import { initBulkUploader } from './kibana_monitoring';
import { telemetryCollectionManager } from '../../../../../src/legacy/core_plugins/telemetry/server';
import { getStatsWithMonitoring } from './telemetry_collection';
import {
getKibanaUsageCollector,
getOpsStatsCollector,
@ -36,6 +39,8 @@ export class Plugin {
collectorSet.register(getKibanaUsageCollector({ collectorSet, config }));
collectorSet.register(getSettingsCollector({ collectorSet, config }));
telemetryCollectionManager.setStatsGetter(getStatsWithMonitoring, 'monitoring', 2);
/*
* Instantiate and start the internal background task that calls collector
* fetch methods and uploads to the ES monitoring bulk endpoint
@ -90,7 +95,6 @@ export class Plugin {
const bulkUploader = initBulkUploader({
elasticsearchPlugin: plugins.elasticsearch,
xpackMainPlugin: plugins.xpack_main,
config,
log: core.log,
kbnServerStatus: kbnServer.status,

View file

@ -6,7 +6,7 @@
import expect from '@kbn/expect';
import sinon from 'sinon';
import { addStackStats, getAllStats, getAllStatsForServer, handleAllStats } from '../get_all_stats';
import { addStackStats, getAllStats, handleAllStats } from '../get_all_stats';
describe('get_all_stats', () => {
const size = 123;
@ -106,7 +106,7 @@ describe('get_all_stats', () => {
}
];
describe('getAllStats / getAllStatsForServer return the same results', () => {
describe('getAllStats', () => {
it('returns clusters', async () => {
const clusterUuidsResponse = {
aggregations: { cluster_uuids: { buckets: [ { key: 'a' } ] } }
@ -201,7 +201,6 @@ describe('get_all_stats', () => {
.onCall(3).returns(Promise.resolve(logstashStatsResponse));
expect(await getAllStats(req, start, end)).to.eql(allClusters);
expect(await getAllStatsForServer(server, start, end)).to.eql(allClusters);
});
it('returns empty clusters', async () => {
@ -213,7 +212,6 @@ describe('get_all_stats', () => {
callWithInternalUser.withArgs('search').returns(Promise.resolve(clusterUuidsResponse));
expect(await getAllStats(req, start, end)).to.eql([]);
expect(await getAllStatsForServer(server, start, end)).to.eql([]);
});
});

Some files were not shown because too many files have changed in this diff Show more