[Telemetry] Make telemetry plugin non-disableable (#133205)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alejandro Fernández Haro 2022-06-27 16:21:37 +02:00 committed by GitHub
parent fbff48fd30
commit 2410b879a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 54 additions and 115 deletions

View file

@ -17,13 +17,6 @@ See our https://www.elastic.co/legal/privacy-statement[Privacy Statement] to lea
[[telemetry-general-settings]]
==== General telemetry settings
[[telemetry-enabled]] `telemetry.enabled`::
Set to `true` 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
browser connected to the {kib} instance. Defaults to `true`.
`telemetry.sendUsageFrom`::
Set to `'server'` to report the cluster statistics from the {kib} server.
If the server fails to connect to our endpoint at https://telemetry.elastic.co/, it assumes
@ -31,13 +24,13 @@ See our https://www.elastic.co/legal/privacy-statement[Privacy Statement] to lea
when they are navigating through {kib}. Defaults to `'server'`.
[[telemetry-optIn]] `telemetry.optIn`::
Set to `true` to automatically opt into reporting cluster statistics. You can also opt out through
*Advanced Settings* in {kib}. Defaults to `true`.
Set to `true` 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 stop sending any telemetry data to Elastic. +
+
This setting can be changed at any time in <<advanced-options, Advanced Settings>>.
To prevent users from changing it,
set <<telemetry-allowChangingOptInStatus, `telemetry.allowChangingOptInStatus`>> to `false`. Defaults to `true`.
`telemetry.allowChangingOptInStatus`::
Set to `true` to allow overwriting the <<telemetry-optIn, `telemetry.optIn`>> setting via the {kib} UI. Defaults to `true`. +
+
[NOTE]
============
When `false`, <<telemetry-optIn, `telemetry.optIn`>> must be `true`. To disable telemetry and not allow users to change that parameter, use <<telemetry-enabled, `telemetry.enabled`>>.
============
Set to `true` to allow overwriting the <<telemetry-optIn, `telemetry.optIn`>> setting via the <<advanced-options, Advanced Settings>> in {kib}. Defaults to `true`.

View file

@ -533,23 +533,19 @@ server status API and status page. *Default: `false`*
[[telemetry-allowChangingOptInStatus]] `telemetry.allowChangingOptInStatus`::
When `true`, users are able to change the telemetry setting at a later time in
<<advanced-options, Advanced Settings>>. When `false`,
{kib} looks at the value of <<settings-telemetry-optIn, `telemetry.optIn`>> to determine whether to send
telemetry data or not. <<telemetry-allowChangingOptInStatus, `telemetry.allowChangingOptInStatus`>> and <<settings-telemetry-optIn, `telemetry.optIn`>>
cannot be `false` at the same time. *Default: `true`*.
<<advanced-options, Advanced Settings>>. When `false`, users cannot change the opt-in status through *Advanced Settings*, and
{kib} only looks at the value of <<settings-telemetry-optIn, `telemetry.optIn`>> to determine whether to send telemetry data or not. *Default: `true`*.
[[settings-telemetry-optIn]] `telemetry.optIn`::
When `true`, telemetry data is sent to Elastic.
When `false`, collection of telemetry data is disabled.
To enable telemetry and prevent users from disabling it,
set <<telemetry-allowChangingOptInStatus, `telemetry.allowChangingOptInStatus`>> to `false` and <<settings-telemetry-optIn, `telemetry.optIn`>> to `true`.
*Default: `true`*
`telemetry.enabled`::
Reporting your cluster statistics helps
us improve your user experience. Your data is never shared with anyone. Set to
`false` to disable telemetry capabilities entirely. You can alternatively opt
out through *Advanced Settings*. *Default: `true`*
us improve your user experience. Your data is never shared with anyone.
Set to `true` to allow telemetry data to be sent to Elastic.
When `false`, the telemetry data is never sent to Elastic. +
+
This setting can be changed at any time in <<advanced-options, Advanced Settings>>.
To prevent users from changing it,
set <<telemetry-allowChangingOptInStatus, `telemetry.allowChangingOptInStatus`>> to `false`.
*Default: `true`*
`vis_type_vega.enableExternalUrls` {ess-icon}::
Set this value to true to allow Vega to use any URL to access external data

View file

@ -10,7 +10,5 @@
"requiredPlugins": [
"usageCollection"
],
"optionalPlugins": [
"telemetry"
]
"optionalPlugins": []
}

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const registerEbtCountersMock = jest.fn();
jest.doMock('./ebt_counters', () => ({
registerEbtCounters: registerEbtCountersMock,
}));

View file

@ -8,32 +8,19 @@
import { coreMock } from '@kbn/core/public/mocks';
import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/public/mocks';
import { telemetryPluginMock } from '@kbn/telemetry-plugin/public/mocks';
import { registerEbtCountersMock } from './plugin.test.mocks';
import { plugin } from '.';
describe('kibana_usage_collection/public', () => {
const pluginInstance = plugin();
describe('optIn fallback from telemetry', () => {
test('should call optIn(false) when telemetry is disabled', () => {
describe('EBT stats -> UI Counters', () => {
test('should report UI counters when EBT emits', () => {
const coreSetup = coreMock.createSetup();
const usageCollectionMock = usageCollectionPluginMock.createSetupContract();
expect(pluginInstance.setup(coreSetup, { usageCollection: usageCollectionMock })).toBe(
undefined
);
expect(coreSetup.analytics.optIn).toHaveBeenCalledWith({ global: { enabled: false } });
});
test('should NOT call optIn(false) when telemetry is enabled', () => {
const coreSetup = coreMock.createSetup();
const usageCollectionMock = usageCollectionPluginMock.createSetupContract();
const telemetry = telemetryPluginMock.createSetupContract();
expect(
pluginInstance.setup(coreSetup, { usageCollection: usageCollectionMock, telemetry })
).toBe(undefined);
expect(coreSetup.analytics.optIn).not.toHaveBeenCalled();
pluginInstance.setup(coreSetup, { usageCollection: usageCollectionMock });
expect(registerEbtCountersMock).toHaveBeenCalledTimes(1);
});
});
});

View file

@ -8,23 +8,14 @@
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import type { CoreSetup, Plugin } from '@kbn/core/public';
import type { TelemetryPluginSetup } from '@kbn/telemetry-plugin/public';
import { registerEbtCounters } from './ebt_counters';
interface KibanaUsageCollectionPluginsDepsSetup {
usageCollection: UsageCollectionSetup;
telemetry?: TelemetryPluginSetup;
}
export class KibanaUsageCollectionPlugin implements Plugin {
public setup(
coreSetup: CoreSetup,
{ usageCollection, telemetry }: KibanaUsageCollectionPluginsDepsSetup
) {
if (!telemetry) {
// If the telemetry plugin is disabled, let's set optIn false to flush the queues.
coreSetup.analytics.optIn({ global: { enabled: false } });
}
public setup(coreSetup: CoreSetup, { usageCollection }: KibanaUsageCollectionPluginsDepsSetup) {
registerEbtCounters(coreSetup.analytics, usageCollection);
}

View file

@ -15,13 +15,11 @@ import {
CollectorOptions,
createUsageCollectionSetupMock,
} from '@kbn/usage-collection-plugin/server/mocks';
import { telemetryPluginMock } from '@kbn/telemetry-plugin/server/mocks';
import { cloudDetailsMock, registerEbtCountersMock } from './plugin.test.mocks';
import { plugin } from '.';
describe('kibana_usage_collection', () => {
const pluginInstance = plugin(coreMock.createPluginInitializerContext({}));
const telemetry = telemetryPluginMock.createSetupContract();
const usageCollectors: CollectorOptions[] = [];
@ -143,26 +141,4 @@ describe('kibana_usage_collection', () => {
test('Runs the stop method without issues', () => {
expect(pluginInstance.stop()).toBe(undefined);
});
describe('optIn fallback from telemetry', () => {
test('should call optIn(false) when telemetry is disabled', () => {
const coreSetup = coreMock.createSetup();
const usageCollectionMock = createUsageCollectionSetupMock();
expect(pluginInstance.setup(coreSetup, { usageCollection: usageCollectionMock })).toBe(
undefined
);
expect(coreSetup.analytics.optIn).toHaveBeenCalledWith({ global: { enabled: false } });
});
test('should NOT call optIn(false) when telemetry is enabled', () => {
const coreSetup = coreMock.createSetup();
const usageCollectionMock = createUsageCollectionSetupMock();
expect(
pluginInstance.setup(coreSetup, { usageCollection: usageCollectionMock, telemetry })
).toBe(undefined);
expect(coreSetup.analytics.optIn).not.toHaveBeenCalled();
});
});
});

View file

@ -7,7 +7,6 @@
*/
import type { UsageCollectionSetup, UsageCounter } from '@kbn/usage-collection-plugin/server';
import type { TelemetryPluginSetup } from '@kbn/telemetry-plugin/server';
import { ReplaySubject, Subject, type Subscription } from 'rxjs';
import type {
PluginInitializerContext,
@ -48,7 +47,6 @@ import {
interface KibanaUsageCollectionPluginsDepsSetup {
usageCollection: UsageCollectionSetup;
telemetry?: TelemetryPluginSetup;
}
type SavedObjectsRegisterType = SavedObjectsServiceSetup['registerType'];
@ -72,14 +70,7 @@ export class KibanaUsageCollectionPlugin implements Plugin {
this.subscriptions = [];
}
public setup(
coreSetup: CoreSetup,
{ usageCollection, telemetry }: KibanaUsageCollectionPluginsDepsSetup
) {
if (!telemetry) {
// If the telemetry plugin is disabled, let's set optIn false to flush the queues.
coreSetup.analytics.optIn({ global: { enabled: false } });
}
public setup(coreSetup: CoreSetup, { usageCollection }: KibanaUsageCollectionPluginsDepsSetup) {
registerEbtCounters(coreSetup.analytics, usageCollection);
usageCollection.createUsageCounter('uiCounters');
this.eventLoopUsageCounter = usageCollection.createUsageCounter('eventLoop');

View file

@ -33,7 +33,6 @@ export function mockTelemetryService({
config: configOverride = {},
}: TelemetryServiceMockOptions = {}) {
const config = {
enabled: true,
sendUsageTo: 'staging' as const,
sendUsageFrom: 'browser' as const,
optIn: true,

View file

@ -88,8 +88,6 @@ interface TelemetryPluginSetupDependencies {
* Public-exposed configuration
*/
export interface TelemetryPluginConfig {
/** Is the plugin enabled? **/
enabled: boolean;
/** The banner is expected to be shown when needed **/
banner: boolean;
/** Does the cluster allow changing the opt-in/out status via the UI? **/

View file

@ -19,13 +19,7 @@ const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
allowChangingOptInStatus: schema.boolean({ defaultValue: true }),
hidePrivacyStatement: schema.boolean({ defaultValue: false }),
optIn: schema.conditional(
schema.siblingRef('allowChangingOptInStatus'),
schema.literal(false),
schema.maybe(schema.literal(true)),
schema.boolean({ defaultValue: true }),
{ defaultValue: true }
),
optIn: schema.boolean({ defaultValue: true }),
// `config` is used internally and not intended to be set
config: schema.string({ defaultValue: getConfigPath() }),
banner: schema.boolean({ defaultValue: true }),
@ -45,7 +39,6 @@ export type TelemetryConfigType = TypeOf<typeof configSchema>;
export const config: PluginConfigDescriptor<TelemetryConfigType> = {
schema: configSchema,
exposeToBrowser: {
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: true,
@ -53,4 +46,17 @@ export const config: PluginConfigDescriptor<TelemetryConfigType> = {
sendUsageTo: true,
hidePrivacyStatement: true,
},
deprecations: () => [
(cfg) => {
if (cfg.telemetry?.enabled === false) {
return {
set: [
{ path: 'telemetry.optIn', value: false },
{ path: 'telemetry.allowChangingOptInStatus', value: false },
],
unset: [{ path: 'telemetry.enabled' }],
};
}
},
],
};

View file

@ -264,7 +264,6 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO
"defaultConfig": Object {
"allowChangingOptInStatus": false,
"banner": true,
"enabled": true,
"optIn": true,
"sendUsageFrom": "browser",
"sendUsageTo": "staging",

View file

@ -26,7 +26,6 @@ describe('TelemetryManagementSectionComponent', () => {
const telemetryService = new TelemetryService({
config: {
sendUsageTo: 'staging',
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: true,
@ -57,7 +56,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: false,
@ -109,7 +107,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: false,
@ -155,7 +152,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: false,
optIn: true,
@ -192,7 +188,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: false,
@ -233,7 +228,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: true,
optIn: false,
@ -281,7 +275,6 @@ describe('TelemetryManagementSectionComponent', () => {
const onQueryMatchChange = jest.fn();
const telemetryService = new TelemetryService({
config: {
enabled: true,
banner: true,
allowChangingOptInStatus: false,
optIn: false,

View file

@ -143,9 +143,8 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'newsfeed.service.urlRoot (string)',
'telemetry.allowChangingOptInStatus (boolean)',
'telemetry.banner (boolean)',
'telemetry.enabled (boolean)',
'telemetry.hidePrivacyStatement (boolean)',
'telemetry.optIn (any)',
'telemetry.optIn (boolean)',
'telemetry.sendUsageFrom (alternatives)',
'telemetry.sendUsageTo (any)',
'usageCollection.uiCounters.debug (boolean)',