[8.0] remove kibana.index config property (#112773)

* remove kibana config

* remove kibanaConfig usages

* prettier fix

* fix some globalConfig.kibana.index access

* fix xpack_legacy globalConfig usage

* fix home globalConfig usage

* fix canvas globalConfig usage

* fix action globalConfig usage

* fix (all?) remaining usages

* fix more plugins

* fix more plugins bis

* yet more usages

* fix ml usages

* fix security_solution

* fix lens

* fix monitoring

* remove from settings docs

* move doc update

* fix unit tests

* update generated doc

* improve test

* adapt new usage in security_solution

* fix security_solution config

* fix createConfig, again

* fix mock config
This commit is contained in:
Pierre Gayvallet 2021-10-25 23:25:24 +02:00 committed by GitHub
parent 74bc51ea7c
commit 106183551a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 188 additions and 477 deletions

View file

@ -31,10 +31,6 @@
# The URLs of the Elasticsearch instances to use for all your queries.
#elasticsearch.hosts: ["http://localhost:9200"]
# Kibana uses an index in Elasticsearch to store saved searches, visualizations and
# dashboards. Kibana creates a new index if the index doesn't already exist.
#kibana.index: ".kibana"
# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) &gt; [getKibanaIndex](./kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md)
## SavedObjectsServiceSetup.getKibanaIndex property
Returns the default index used for saved objects.
<b>Signature:</b>
```typescript
getKibanaIndex: () => string;
```

View file

@ -52,6 +52,7 @@ export class Plugin() {
| Property | Type | Description |
| --- | --- | --- |
| [addClientWrapper](./kibana-plugin-core-server.savedobjectsservicesetup.addclientwrapper.md) | <code>(priority: number, id: string, factory: SavedObjectsClientWrapperFactory) =&gt; void</code> | Add a [client wrapper factory](./kibana-plugin-core-server.savedobjectsclientwrapperfactory.md) with the given priority. |
| [getKibanaIndex](./kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md) | <code>() =&gt; string</code> | Returns the default index used for saved objects. |
| [registerType](./kibana-plugin-core-server.savedobjectsservicesetup.registertype.md) | <code>&lt;Attributes = any&gt;(type: SavedObjectsType&lt;Attributes&gt;) =&gt; void</code> | Register a [savedObjects type](./kibana-plugin-core-server.savedobjectstype.md) definition.<!-- -->See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-core-server.savedobjectmigrationmap.md) for more details about these. |
| [setClientFactoryProvider](./kibana-plugin-core-server.savedobjectsservicesetup.setclientfactoryprovider.md) | <code>(clientFactoryProvider: SavedObjectsClientFactoryProvider) =&gt; void</code> | Set the default [factory provider](./kibana-plugin-core-server.savedobjectsclientfactoryprovider.md) for creating Saved Objects clients. Only one provider can be set, subsequent calls to this method will fail. |

View file

@ -9,7 +9,6 @@
```typescript
export declare type SharedGlobalConfig = RecursiveReadonly<{
kibana: Pick<KibanaConfigType, typeof SharedGlobalConfigKeys.kibana[number]>;
elasticsearch: Pick<ElasticsearchConfigType, typeof SharedGlobalConfigKeys.elasticsearch[number]>;
path: Pick<PathConfigType, typeof SharedGlobalConfigKeys.path[number]>;
savedObjects: Pick<SavedObjectsConfigType, typeof SharedGlobalConfigKeys.savedObjects[number]>;

View file

@ -285,18 +285,6 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`.
| `interpreter.enableInVisualize`
| Enables use of interpreter in Visualize. *Default: `true`*
|[[kibana-index]] `kibana.index:`
| deprecated:[7.11.0,This setting will be removed in 8.0.] Multitenancy by
changing `kibana.index` will not be supported starting in 8.0. See
https://ela.st/kbn-remove-legacy-multitenancy[8.0 Breaking Changes] for more
details.
+
{kib} uses an index in {es} to store saved searches, visualizations, and
dashboards. {kib} creates a new index if the index doesnt already exist. If
you configure a custom index, the name must be lowercase, and conform to the
{es} {ref}/indices-create-index.html[index name limitations].
*Default: `".kibana"`*
| `data.autocomplete.valueSuggestions.timeout:` {ess-icon}
| Time in milliseconds to wait for autocomplete suggestions from {es}.
This value must be a whole number greater than zero. *Default: `"1000"`*

View file

@ -16,8 +16,8 @@ WARNING: The following instructions assumes {kib} is using the default index nam
Saved objects are stored in two indices:
* `.kibana_{kibana_version}_001`, or if the `kibana.index` configuration setting is set `.{kibana.index}_{kibana_version}_001`. E.g. for Kibana v7.12.0 `.kibana_7.12.0_001`.
* `.kibana_task_manager_{kibana_version}_001`, or if the `xpack.tasks.index` configuration setting is set `.{xpack.tasks.index}_{kibana_version}_001` E.g. for Kibana v7.12.0 `.kibana_task_manager_7.12.0_001`.
* `.kibana_{kibana_version}_001`, e.g. for Kibana v7.12.0 `.kibana_7.12.0_001`.
* `.kibana_task_manager_{kibana_version}_001`, e.g. for Kibana v7.12.0 `.kibana_task_manager_7.12.0_001`.
The index aliases `.kibana` and `.kibana_task_manager` will always point to
the most up-to-date saved object indices.

View file

@ -7,7 +7,6 @@
import { Action } from 'history';
import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
import Boom from '@hapi/boom';
import { ConfigDeprecationProvider } from '@kbn/config';
import { ConfigPath } from '@kbn/config';
import { DetailedPeerCertificate } from 'tls';
import { EnvironmentMode } from '@kbn/config';

View file

@ -17,7 +17,6 @@ import { mockCoreContext } from '../core_context.mock';
import { config as RawElasticsearchConfig } from '../elasticsearch/elasticsearch_config';
import { config as RawHttpConfig } from '../http/http_config';
import { config as RawLoggingConfig } from '../logging/logging_config';
import { config as RawKibanaConfig } from '../kibana_config';
import { savedObjectsConfig as RawSavedObjectsConfig } from '../saved_objects/saved_objects_config';
import { httpServiceMock } from '../http/http_service.mock';
import { metricsServiceMock } from '../metrics/metrics_service.mock';
@ -40,8 +39,6 @@ describe('CoreUsageDataService', () => {
return new BehaviorSubject(RawLoggingConfig.schema.validate({}));
} else if (path === 'savedObjects') {
return new BehaviorSubject(RawSavedObjectsConfig.schema.validate({}));
} else if (path === 'kibana') {
return new BehaviorSubject(RawKibanaConfig.schema.validate({}));
}
return new BehaviorSubject({});
};

View file

@ -33,7 +33,6 @@ import type {
} from './types';
import { isConfigured } from './is_configured';
import { ElasticsearchServiceStart } from '../elasticsearch';
import { KibanaConfigType } from '../kibana_config';
import { coreUsageStatsType } from './core_usage_stats';
import { LEGACY_URL_ALIAS_TYPE } from '../saved_objects/object_types';
import { CORE_USAGE_STATS_TYPE } from './constants';
@ -56,6 +55,8 @@ export interface StartDeps {
exposedConfigsToUsage: ExposedConfigsToUsage;
}
const kibanaIndex = '.kibana';
/**
* Because users can configure their Saved Object to any arbitrary index name,
* we need to map customized index names back to a "standard" index name.
@ -74,19 +75,6 @@ const kibanaOrTaskManagerIndex = (index: string, kibanaConfigIndex: string) => {
return index === kibanaConfigIndex ? '.kibana' : '.kibana_task_manager';
};
/**
* This is incredibly hacky... The config service doesn't allow you to determine
* whether or not a config value has been changed from the default value, and the
* default value is defined in legacy code.
*
* This will be going away in 8.0, so please look away for a few months
*
* @param index The `kibana.index` setting from the `kibana.yml`
*/
const isCustomIndex = (index: string) => {
return index !== '.kibana';
};
export class CoreUsageDataService
implements CoreService<InternalCoreUsageDataSetup, CoreUsageDataStart>
{
@ -98,7 +86,6 @@ export class CoreUsageDataService
private soConfig?: SavedObjectsConfigType;
private stop$: Subject<void>;
private opsMetrics?: OpsMetrics;
private kibanaConfig?: KibanaConfigType;
private coreUsageStatsClient?: CoreUsageStatsClient;
private deprecatedConfigPaths: ChangedDeprecatedPaths = { set: [], unset: [] };
private incrementUsageCounter: CoreIncrementUsageCounter = () => {}; // Initially set to noop
@ -133,8 +120,8 @@ export class CoreUsageDataService
.getTypeRegistry()
.getAllTypes()
.reduce((acc, type) => {
const index = type.indexPattern ?? this.kibanaConfig!.index;
return index != null ? acc.add(index) : acc;
const index = type.indexPattern ?? kibanaIndex;
return acc.add(index);
}, new Set<string>())
.values()
).map((index) => {
@ -150,7 +137,7 @@ export class CoreUsageDataService
.then(({ body }) => {
const stats = body[0];
return {
alias: kibanaOrTaskManagerIndex(index, this.kibanaConfig!.index),
alias: kibanaOrTaskManagerIndex(index, kibanaIndex),
docsCount: stats['docs.count'] ? parseInt(stats['docs.count'], 10) : 0,
docsDeleted: stats['docs.deleted'] ? parseInt(stats['docs.deleted'], 10) : 0,
storeSizeBytes: stats['store.size'] ? parseInt(stats['store.size'], 10) : 0,
@ -167,7 +154,7 @@ export class CoreUsageDataService
// Note: this agg can be changed to use `savedObjectsRepository.find` in the future after `filters` is supported.
// See src/core/server/saved_objects/service/lib/aggregations/aggs_types/bucket_aggs.ts for supported aggregations.
const { body: resp } = await elasticsearch.client.asInternalUser.search({
index: this.kibanaConfig!.index,
index: kibanaIndex,
body: {
track_total_hits: true,
query: { match: { type: LEGACY_URL_ALIAS_TYPE } },
@ -313,7 +300,7 @@ export class CoreUsageDataService
},
savedObjects: {
customIndex: isCustomIndex(this.kibanaConfig!.index),
customIndex: false,
maxImportPayloadBytes: this.soConfig.maxImportPayloadBytes.getValueInBytes(),
maxImportExportSize: this.soConfig.maxImportExportSize,
},
@ -472,13 +459,6 @@ export class CoreUsageDataService
this.soConfig = config;
});
this.configService
.atPath<KibanaConfigType>('kibana')
.pipe(takeUntil(this.stop$))
.subscribe((config) => {
this.kibanaConfig = config;
});
changedDeprecatedConfigPath$
.pipe(takeUntil(this.stop$))
.subscribe((deprecatedConfigPaths) => (this.deprecatedConfigPaths = deprecatedConfigPaths));

View file

@ -1,42 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { config } from './kibana_config';
import { getDeprecationsFor } from './config/test_utils';
const CONFIG_PATH = 'kibana';
const applyKibanaDeprecations = (settings: Record<string, any> = {}) =>
getDeprecationsFor({
provider: config.deprecations!,
settings,
path: CONFIG_PATH,
});
it('set correct defaults ', () => {
const configValue = config.schema.validate({});
expect(configValue).toMatchInlineSnapshot(`
Object {
"enabled": true,
"index": ".kibana",
}
`);
});
describe('deprecations', () => {
['.foo', '.kibana'].forEach((index) => {
it('logs a warning if index is set', () => {
const { messages } = applyKibanaDeprecations({ index });
expect(messages).toMatchInlineSnapshot(`
Array [
"\\"kibana.index\\" is deprecated. Multitenancy by changing \\"kibana.index\\" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details",
]
`);
});
});
});

View file

@ -1,51 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
import { schema, TypeOf } from '@kbn/config-schema';
import { ConfigDeprecationProvider } from '@kbn/config';
export type KibanaConfigType = TypeOf<typeof config.schema>;
const deprecations: ConfigDeprecationProvider = () => [
(settings, fromPath, addDeprecation) => {
const kibana = settings[fromPath];
if (kibana?.index) {
addDeprecation({
configPath: 'kibana.index',
title: i18n.translate('core.kibana.index.deprecationTitle', {
defaultMessage: `Setting "kibana.index" is deprecated`,
}),
message: i18n.translate('core.kibana.index.deprecationMessage', {
defaultMessage: `"kibana.index" is deprecated. Multitenancy by changing "kibana.index" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details`,
}),
documentationUrl: 'https://ela.st/kbn-remove-legacy-multitenancy',
correctiveActions: {
manualSteps: [
i18n.translate('core.kibana.index.deprecationManualStep1', {
defaultMessage: `If you rely on this setting to achieve multitenancy you should use Spaces, cross-cluster replication, or cross-cluster search instead.`,
}),
i18n.translate('core.kibana.index.deprecationManualStep2', {
defaultMessage: `To migrate to Spaces, we encourage using saved object management to export your saved objects from a tenant into the default tenant in a space.`,
}),
],
},
});
}
return settings;
},
];
export const config = {
path: 'kibana',
schema: schema.object({
enabled: schema.boolean({ defaultValue: true }),
index: schema.string({ defaultValue: '.kibana' }),
}),
deprecations,
};

View file

@ -65,9 +65,6 @@ type MockedPluginInitializerConfig<T> = jest.Mocked<PluginInitializerContext<T>[
export function pluginInitializerContextConfigMock<T>(config: T) {
const globalConfig: SharedGlobalConfig = {
kibana: {
index: '.kibana-tests',
},
elasticsearch: {
shardTimeout: duration('30s'),
requestTimeout: duration('30s'),

View file

@ -41,9 +41,6 @@ describe('Legacy config', () => {
const legacyConfig = getGlobalConfig(configService);
expect(legacyConfig).toStrictEqual({
kibana: {
index: '.kibana',
},
elasticsearch: {
shardTimeout: duration(30, 's'),
requestTimeout: duration(30, 's'),
@ -62,9 +59,6 @@ describe('Legacy config', () => {
const legacyConfig = await getGlobalConfig$(configService).pipe(take(1)).toPromise();
expect(legacyConfig).toStrictEqual({
kibana: {
index: '.kibana',
},
elasticsearch: {
shardTimeout: duration(30, 's'),
requestTimeout: duration(30, 's'),

View file

@ -13,7 +13,6 @@ import { pick, deepFreeze } from '@kbn/std';
import { IConfigService } from '@kbn/config';
import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types';
import { KibanaConfigType, config as kibanaConfig } from '../kibana_config';
import {
ElasticsearchConfigType,
config as elasticsearchConfig,
@ -21,18 +20,15 @@ import {
import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config';
const createGlobalConfig = ({
kibana,
elasticsearch,
path,
savedObjects,
}: {
kibana: KibanaConfigType;
elasticsearch: ElasticsearchConfigType;
path: PathConfigType;
savedObjects: SavedObjectsConfigType;
}): SharedGlobalConfig => {
return deepFreeze({
kibana: pick(kibana, SharedGlobalConfigKeys.kibana),
elasticsearch: pick(elasticsearch, SharedGlobalConfigKeys.elasticsearch),
path: pick(path, SharedGlobalConfigKeys.path),
savedObjects: pick(savedObjects, SharedGlobalConfigKeys.savedObjects),
@ -41,7 +37,6 @@ const createGlobalConfig = ({
export const getGlobalConfig = (configService: IConfigService): SharedGlobalConfig => {
return createGlobalConfig({
kibana: configService.atPathSync<KibanaConfigType>(kibanaConfig.path),
elasticsearch: configService.atPathSync<ElasticsearchConfigType>(elasticsearchConfig.path),
path: configService.atPathSync<PathConfigType>(pathConfig.path),
savedObjects: configService.atPathSync<SavedObjectsConfigType>(savedObjectsConfig.path),
@ -50,15 +45,13 @@ export const getGlobalConfig = (configService: IConfigService): SharedGlobalConf
export const getGlobalConfig$ = (configService: IConfigService): Observable<SharedGlobalConfig> => {
return combineLatest([
configService.atPath<KibanaConfigType>(kibanaConfig.path),
configService.atPath<ElasticsearchConfigType>(elasticsearchConfig.path),
configService.atPath<PathConfigType>(pathConfig.path),
configService.atPath<SavedObjectsConfigType>(savedObjectsConfig.path),
]).pipe(
map(
([kibana, elasticsearch, path, savedObjects]) =>
([elasticsearch, path, savedObjects]) =>
createGlobalConfig({
kibana,
elasticsearch,
path,
savedObjects,

View file

@ -124,9 +124,6 @@ describe('createPluginInitializerContext', () => {
.pipe(first())
.toPromise();
expect(configObject).toStrictEqual({
kibana: {
index: '.kibana',
},
elasticsearch: {
shardTimeout: duration(30, 's'),
requestTimeout: duration(30, 's'),

View file

@ -197,6 +197,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
setClientFactoryProvider: deps.savedObjects.setClientFactoryProvider,
addClientWrapper: deps.savedObjects.addClientWrapper,
registerType: deps.savedObjects.registerType,
getKibanaIndex: deps.savedObjects.getKibanaIndex,
},
status: {
core$: deps.status.core$,

View file

@ -13,7 +13,6 @@ import { PathConfigType } from '@kbn/utils';
import { ConfigPath, EnvironmentMode, PackageInfo, ConfigDeprecationProvider } from '../config';
import { LoggerFactory } from '../logging';
import { KibanaConfigType } from '../kibana_config';
import { ElasticsearchConfigType } from '../elasticsearch/elasticsearch_config';
import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config';
import { CorePreboot, CoreSetup, CoreStart } from '..';
@ -364,7 +363,6 @@ export interface AsyncPlugin<
export const SharedGlobalConfigKeys = {
// We can add more if really needed
kibana: ['index'] as const,
elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout'] as const,
path: ['data'] as const,
savedObjects: ['maxImportPayloadBytes'] as const,
@ -374,7 +372,6 @@ export const SharedGlobalConfigKeys = {
* @public
*/
export type SharedGlobalConfig = RecursiveReadonly<{
kibana: Pick<KibanaConfigType, typeof SharedGlobalConfigKeys.kibana[number]>;
elasticsearch: Pick<ElasticsearchConfigType, typeof SharedGlobalConfigKeys.elasticsearch[number]>;
path: Pick<PathConfigType, typeof SharedGlobalConfigKeys.path[number]>;
savedObjects: Pick<SavedObjectsConfigType, typeof SharedGlobalConfigKeys.savedObjects[number]>;

View file

@ -9,13 +9,12 @@
import type { RegisterDeprecationsConfig } from '../../deprecations';
import type { ISavedObjectTypeRegistry } from '../saved_objects_type_registry';
import type { SavedObjectConfig } from '../saved_objects_config';
import type { KibanaConfigType } from '../../kibana_config';
import { getUnknownTypesDeprecations } from './unknown_object_types';
interface GetDeprecationProviderOptions {
typeRegistry: ISavedObjectTypeRegistry;
savedObjectsConfig: SavedObjectConfig;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
}

View file

@ -12,7 +12,6 @@ import { estypes } from '@elastic/elasticsearch';
import { deleteUnknownTypeObjects, getUnknownTypesDeprecations } from './unknown_object_types';
import { typeRegistryMock } from '../saved_objects_type_registry.mock';
import { elasticsearchClientMock } from '../../elasticsearch/client/mocks';
import type { KibanaConfigType } from '../../kibana_config';
import { SavedObjectsType } from 'kibana/server';
const createSearchResponse = (count: number): estypes.SearchResponse => {
@ -30,7 +29,7 @@ describe('unknown saved object types deprecation', () => {
let typeRegistry: ReturnType<typeof typeRegistryMock.create>;
let esClient: ReturnType<typeof elasticsearchClientMock.createScopedClusterClient>;
let kibanaConfig: KibanaConfigType;
const kibanaIndex = '.kibana';
beforeEach(() => {
typeRegistry = typeRegistryMock.create();
@ -41,11 +40,6 @@ describe('unknown saved object types deprecation', () => {
{ name: 'bar' },
] as SavedObjectsType[]);
getIndexForTypeMock.mockImplementation(({ type }: { type: string }) => `${type}-index`);
kibanaConfig = {
index: '.kibana',
enabled: true,
};
});
afterEach(() => {
@ -63,7 +57,7 @@ describe('unknown saved object types deprecation', () => {
await getUnknownTypesDeprecations({
esClient,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
@ -89,7 +83,7 @@ describe('unknown saved object types deprecation', () => {
const deprecations = await getUnknownTypesDeprecations({
esClient,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
@ -104,7 +98,7 @@ describe('unknown saved object types deprecation', () => {
const deprecations = await getUnknownTypesDeprecations({
esClient,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
@ -132,7 +126,7 @@ describe('unknown saved object types deprecation', () => {
await deleteUnknownTypeObjects({
esClient,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});

View file

@ -12,13 +12,12 @@ import type { DeprecationsDetails } from '../../deprecations';
import { IScopedClusterClient } from '../../elasticsearch';
import { ISavedObjectTypeRegistry } from '../saved_objects_type_registry';
import { SavedObjectsRawDocSource } from '../serialization';
import type { KibanaConfigType } from '../../kibana_config';
import { getIndexForType } from '../service/lib';
interface UnknownTypesDeprecationOptions {
typeRegistry: ISavedObjectTypeRegistry;
esClient: IScopedClusterClient;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
}
@ -29,11 +28,11 @@ const getTargetIndices = ({
types,
typeRegistry,
kibanaVersion,
kibanaConfig,
kibanaIndex,
}: {
types: string[];
typeRegistry: ISavedObjectTypeRegistry;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
}) => {
return [
@ -43,7 +42,7 @@ const getTargetIndices = ({
type,
typeRegistry,
kibanaVersion,
defaultIndex: kibanaConfig.index,
defaultIndex: kibanaIndex,
})
)
),
@ -63,14 +62,14 @@ const getUnknownTypesQuery = (knownTypes: string[]): estypes.QueryDslQueryContai
const getUnknownSavedObjects = async ({
typeRegistry,
esClient,
kibanaConfig,
kibanaIndex,
kibanaVersion,
}: UnknownTypesDeprecationOptions) => {
const knownTypes = getKnownTypes(typeRegistry);
const targetIndices = getTargetIndices({
types: knownTypes,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
const query = getUnknownTypesQuery(knownTypes);
@ -133,21 +132,21 @@ export const getUnknownTypesDeprecations = async (
interface DeleteUnknownTypesOptions {
typeRegistry: ISavedObjectTypeRegistry;
esClient: IScopedClusterClient;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
}
export const deleteUnknownTypeObjects = async ({
esClient,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
}: DeleteUnknownTypesOptions) => {
const knownTypes = getKnownTypes(typeRegistry);
const targetIndices = getTargetIndices({
types: knownTypes,
typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
const query = getUnknownTypesQuery(knownTypes);

View file

@ -16,6 +16,7 @@ import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
import { SavedObjectsType } from '../../types';
import { DocumentMigrator } from '../core/document_migrator';
import { ByteSizeValue } from '@kbn/config-schema';
jest.mock('../core/document_migrator', () => {
return {
// Create a mock for spying on the constructor
@ -304,10 +305,7 @@ const mockOptions = () => {
migrations: {},
},
]),
kibanaConfig: {
enabled: true,
index: '.my-index',
} as KibanaMigratorOptions['kibanaConfig'],
kibanaIndex: '.my-index',
soMigrationsConfig: {
batchSize: 20,
maxBatchSizeBytes: ByteSizeValue.parse('20mb'),

View file

@ -13,7 +13,6 @@
import { BehaviorSubject } from 'rxjs';
import Semver from 'semver';
import { KibanaConfigType } from '../../../kibana_config';
import { ElasticsearchClient } from '../../../elasticsearch';
import { Logger } from '../../../logging';
import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings';
@ -35,7 +34,7 @@ export interface KibanaMigratorOptions {
client: ElasticsearchClient;
typeRegistry: ISavedObjectTypeRegistry;
soMigrationsConfig: SavedObjectsMigrationConfigType;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
logger: Logger;
migrationsRetryDelay?: number;
@ -55,7 +54,7 @@ export interface KibanaMigratorStatus {
export class KibanaMigrator {
private readonly client: ElasticsearchClient;
private readonly documentMigrator: VersionedTransformer;
private readonly kibanaConfig: KibanaConfigType;
private readonly kibanaIndex: string;
private readonly log: Logger;
private readonly mappingProperties: SavedObjectsTypeMappingDefinitions;
private readonly typeRegistry: ISavedObjectTypeRegistry;
@ -76,14 +75,14 @@ export class KibanaMigrator {
constructor({
client,
typeRegistry,
kibanaConfig,
kibanaIndex,
soMigrationsConfig,
kibanaVersion,
logger,
migrationsRetryDelay,
}: KibanaMigratorOptions) {
this.client = client;
this.kibanaConfig = kibanaConfig;
this.kibanaIndex = kibanaIndex;
this.soMigrationsConfig = soMigrationsConfig;
this.typeRegistry = typeRegistry;
this.serializer = new SavedObjectsSerializer(this.typeRegistry);
@ -148,9 +147,8 @@ export class KibanaMigrator {
}
private runMigrationsInternal() {
const kibanaIndexName = this.kibanaConfig.index;
const indexMap = createIndexMap({
kibanaIndexName,
kibanaIndexName: this.kibanaIndex,
indexMap: this.mappingProperties,
registry: this.typeRegistry,
});

View file

@ -9,16 +9,15 @@
import { IRouter } from '../../../http';
import { catchAndReturnBoomErrors } from '../utils';
import { deleteUnknownTypeObjects } from '../../deprecations';
import { KibanaConfigType } from '../../../kibana_config';
interface RouteDependencies {
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
kibanaVersion: string;
}
export const registerDeleteUnknownTypesRoute = (
router: IRouter,
{ kibanaConfig, kibanaVersion }: RouteDependencies
{ kibanaIndex, kibanaVersion }: RouteDependencies
) => {
router.post(
{
@ -29,7 +28,7 @@ export const registerDeleteUnknownTypesRoute = (
await deleteUnknownTypeObjects({
esClient: context.core.elasticsearch.client,
typeRegistry: context.core.savedObjects.typeRegistry,
kibanaConfig,
kibanaIndex,
kibanaVersion,
});
return res.ok({

View file

@ -28,7 +28,6 @@ import { registerLegacyImportRoute } from './legacy_import_export/import';
import { registerLegacyExportRoute } from './legacy_import_export/export';
import { registerBulkResolveRoute } from './bulk_resolve';
import { registerDeleteUnknownTypesRoute } from './deprecations';
import { KibanaConfigType } from '../../kibana_config';
export function registerRoutes({
http,
@ -37,7 +36,7 @@ export function registerRoutes({
config,
migratorPromise,
kibanaVersion,
kibanaConfig,
kibanaIndex,
}: {
http: InternalHttpServiceSetup;
coreUsageData: InternalCoreUsageDataSetup;
@ -45,7 +44,7 @@ export function registerRoutes({
config: SavedObjectConfig;
migratorPromise: Promise<IKibanaMigrator>;
kibanaVersion: string;
kibanaConfig: KibanaConfigType;
kibanaIndex: string;
}) {
const router = http.createRouter('/api/saved_objects/');
@ -74,5 +73,5 @@ export function registerRoutes({
const internalRouter = http.createRouter('/internal/saved_objects/');
registerMigrateRoute(internalRouter, migratorPromise);
registerDeleteUnknownTypesRoute(internalRouter, { kibanaConfig, kibanaVersion });
registerDeleteUnknownTypesRoute(internalRouter, { kibanaIndex, kibanaVersion });
}

View file

@ -12,17 +12,13 @@ import { registerDeleteUnknownTypesRoute } from '../deprecations';
import { elasticsearchServiceMock } from '../../../../../core/server/elasticsearch/elasticsearch_service.mock';
import { typeRegistryMock } from '../../saved_objects_type_registry.mock';
import { setupServer } from '../test_utils';
import { KibanaConfigType } from '../../../kibana_config';
import { SavedObjectsType } from 'kibana/server';
type SetupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
describe('POST /internal/saved_objects/deprecations/_delete_unknown_types', () => {
const kibanaVersion = '8.0.0';
const kibanaConfig: KibanaConfigType = {
enabled: true,
index: '.kibana',
};
const kibanaIndex = '.kibana';
let server: SetupServerReturn['server'];
let httpSetup: SetupServerReturn['httpSetup'];
@ -45,7 +41,7 @@ describe('POST /internal/saved_objects/deprecations/_delete_unknown_types', () =
const router = httpSetup.createRouter('/internal/saved_objects/');
registerDeleteUnknownTypesRoute(router, {
kibanaVersion,
kibanaConfig,
kibanaIndex,
});
await server.start();

View file

@ -60,8 +60,11 @@ const createSetupContractMock = () => {
setClientFactoryProvider: jest.fn(),
addClientWrapper: jest.fn(),
registerType: jest.fn(),
getKibanaIndex: jest.fn(),
};
setupContract.getKibanaIndex.mockReturnValue('.kibana');
return setupContract;
};

View file

@ -23,7 +23,6 @@ import {
InternalElasticsearchServiceStart,
} from '../elasticsearch';
import { InternalDeprecationsServiceSetup } from '../deprecations';
import { KibanaConfigType } from '../kibana_config';
import {
SavedObjectsConfigType,
SavedObjectsMigrationConfigType,
@ -47,6 +46,8 @@ import { calculateStatus$ } from './status';
import { registerCoreObjectTypes } from './object_types';
import { getSavedObjectsDeprecationsProvider } from './deprecations';
const kibanaIndex = '.kibana';
/**
* Saved Objects is Kibana's data persistence mechanism allowing plugins to
* use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods
@ -144,6 +145,11 @@ export interface SavedObjectsServiceSetup {
* ```
*/
registerType: <Attributes = any>(type: SavedObjectsType<Attributes>) => void;
/**
* Returns the default index used for saved objects.
*/
getKibanaIndex: () => string;
}
/**
@ -302,14 +308,9 @@ export class SavedObjectsService
.toPromise();
this.config = new SavedObjectConfig(savedObjectsConfig, savedObjectsMigrationConfig);
const kibanaConfig = await this.coreContext.configService
.atPath<KibanaConfigType>('kibana')
.pipe(first())
.toPromise();
deprecations.getRegistry('savedObjects').registerDeprecations(
getSavedObjectsDeprecationsProvider({
kibanaConfig,
kibanaIndex,
savedObjectsConfig: this.config,
kibanaVersion: this.coreContext.env.packageInfo.version,
typeRegistry: this.typeRegistry,
@ -324,7 +325,7 @@ export class SavedObjectsService
logger: this.logger,
config: this.config,
migratorPromise: this.migrator$.pipe(first()).toPromise(),
kibanaConfig,
kibanaIndex,
kibanaVersion: this.coreContext.env.packageInfo.version,
});
@ -361,6 +362,7 @@ export class SavedObjectsService
this.typeRegistry.registerType(type);
},
getTypeRegistry: () => this.typeRegistry,
getKibanaIndex: () => kibanaIndex,
};
}
@ -374,14 +376,9 @@ export class SavedObjectsService
this.logger.debug('Starting SavedObjects service');
const kibanaConfig = await this.coreContext.configService
.atPath<KibanaConfigType>('kibana')
.pipe(first())
.toPromise();
const client = elasticsearch.client;
const migrator = this.createMigrator(
kibanaConfig,
this.config.migration,
elasticsearch.client.asInternalUser,
migrationsRetryDelay
@ -442,7 +439,7 @@ export class SavedObjectsService
return SavedObjectsRepository.createRepository(
migrator,
this.typeRegistry,
kibanaConfig.index,
kibanaIndex,
esClient,
this.logger.get('repository'),
includedHiddenTypes
@ -498,7 +495,6 @@ export class SavedObjectsService
public async stop() {}
private createMigrator(
kibanaConfig: KibanaConfigType,
soMigrationsConfig: SavedObjectsMigrationConfigType,
client: ElasticsearchClient,
migrationsRetryDelay?: number
@ -508,7 +504,7 @@ export class SavedObjectsService
logger: this.logger,
kibanaVersion: this.coreContext.env.packageInfo.version,
soMigrationsConfig,
kibanaConfig,
kibanaIndex,
client,
migrationsRetryDelay,
});

View file

@ -2704,6 +2704,7 @@ export class SavedObjectsSerializer {
// @public
export interface SavedObjectsServiceSetup {
addClientWrapper: (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void;
getKibanaIndex: () => string;
registerType: <Attributes = any>(type: SavedObjectsType<Attributes>) => void;
setClientFactoryProvider: (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void;
}
@ -2977,7 +2978,6 @@ export interface ShardsResponse {
// @public (undocumented)
export type SharedGlobalConfig = RecursiveReadonly<{
kibana: Pick<KibanaConfigType, typeof SharedGlobalConfigKeys.kibana[number]>;
elasticsearch: Pick<ElasticsearchConfigType, typeof SharedGlobalConfigKeys.elasticsearch[number]>;
path: Pick<PathConfigType, typeof SharedGlobalConfigKeys.path[number]>;
savedObjects: Pick<SavedObjectsConfigType, typeof SharedGlobalConfigKeys.savedObjects[number]>;
@ -3052,9 +3052,8 @@ export const validBodyOutput: readonly ["data", "stream"];
//
// src/core/server/elasticsearch/client/types.ts:94:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts
// src/core/server/http/router/response.ts:302:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:380:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:486:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
// src/core/server/plugins/types.ts:375:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
// src/core/server/plugins/types.ts:483:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
```

View file

@ -36,7 +36,6 @@ import { config as cspConfig } from './csp';
import { config as elasticsearchConfig } from './elasticsearch';
import { config as httpConfig } from './http';
import { config as loggingConfig } from './logging';
import { config as kibanaConfig } from './kibana_config';
import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects';
import { config as uiSettingsConfig } from './ui_settings';
import { config as statusConfig } from './status';
@ -373,7 +372,6 @@ export class Server {
loggingConfig,
httpConfig,
pluginsConfig,
kibanaConfig,
savedObjectsConfig,
savedObjectsMigrationConfig,
uiSettingsConfig,

View file

@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
import { first } from 'rxjs/operators';
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server';
import { registerKqlTelemetryRoute } from './route';
import { UsageCollectionSetup } from '../../../usage_collection/server';
@ -28,15 +27,13 @@ export class KqlTelemetryService implements Plugin<void> {
);
if (usageCollection) {
this.initializerContext.config.legacy.globalConfig$
.pipe(first())
.toPromise()
.then((config) => makeKQLUsageCollector(usageCollection, config.kibana.index))
.catch((e) => {
this.initializerContext.logger
.get('kql-telemetry')
.warn(`Registering KQL telemetry collector failed: ${e}`);
});
try {
makeKQLUsageCollector(usageCollection, savedObjects.getKibanaIndex());
} catch (e) {
this.initializerContext.logger
.get('kql-telemetry')
.warn(`Registering KQL telemetry collector failed: ${e}`);
}
}
}

View file

@ -9,10 +9,7 @@
import { fetchProvider, Usage } from './fetch';
import { UsageCollectionSetup } from '../../../../usage_collection/server';
export async function makeKQLUsageCollector(
usageCollection: UsageCollectionSetup,
kibanaIndex: string
) {
export function makeKQLUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) {
const kqlUsageCollector = usageCollection.makeUsageCollector<Usage>({
type: 'kql',
fetch: fetchProvider(kibanaIndex),

View file

@ -6,21 +6,18 @@
* Side Public License, v 1.
*/
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SharedGlobalConfig } from 'kibana/server';
import { CollectorFetchContext } from 'src/plugins/usage_collection/server';
import { CollectedUsage, ReportedUsage } from './register';
interface SearchTelemetry {
'search-telemetry': CollectedUsage;
}
export function fetchProvider(config$: Observable<SharedGlobalConfig>) {
export function fetchProvider(kibanaIndex: string) {
return async ({ esClient }: CollectorFetchContext): Promise<ReportedUsage> => {
const config = await config$.pipe(first()).toPromise();
const { body: esResponse } = await esClient.search<SearchTelemetry>(
{
index: config.kibana.index,
index: kibanaIndex,
body: {
query: { term: { type: { value: 'search-telemetry' } } },
},

View file

@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
import { PluginInitializerContext } from 'kibana/server';
import { UsageCollectionSetup } from '../../../../usage_collection/server';
import { fetchProvider } from './fetch';
@ -22,15 +21,12 @@ export interface ReportedUsage {
averageDuration: number | null;
}
export async function registerUsageCollector(
usageCollection: UsageCollectionSetup,
context: PluginInitializerContext
) {
export function registerUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) {
try {
const collector = usageCollection.makeUsageCollector<ReportedUsage>({
type: 'search',
isReady: () => true,
fetch: fetchProvider(context.config.legacy.globalConfig$),
fetch: fetchProvider(kibanaIndex),
schema: {
successCount: { type: 'long' },
errorCount: { type: 'long' },

View file

@ -184,7 +184,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
core.savedObjects.registerType(searchTelemetry);
if (usageCollection) {
registerUsageCollector(usageCollection, this.initializerContext);
registerUsageCollector(usageCollection, core.savedObjects.getKibanaIndex());
}
expressions.registerFunction(getEsaggs({ getStartServices: core.getStartServices }));

View file

@ -61,7 +61,8 @@ export class SampleDataRegistry {
customIntegrations?: CustomIntegrationsPluginSetup
) {
if (usageCollections) {
makeSampleDataUsageCollector(usageCollections, this.initContext);
const kibanaIndex = core.savedObjects.getKibanaIndex();
makeSampleDataUsageCollector(usageCollections, kibanaIndex);
}
const usageTracker = usage(
core.getStartServices().then(([coreStart]) => coreStart.savedObjects),

View file

@ -6,20 +6,16 @@
* Side Public License, v 1.
*/
import type { PluginInitializerContext } from 'kibana/server';
import type { UsageCollectionSetup } from '../../../../../usage_collection/server';
import { fetchProvider, TelemetryResponse } from './collector_fetch';
export function makeSampleDataUsageCollector(
usageCollection: UsageCollectionSetup,
context: PluginInitializerContext
kibanaIndex: string
) {
const config = context.config.legacy.get();
const index = config.kibana.index;
const collector = usageCollection.makeUsageCollector<TelemetryResponse>({
type: 'sample-data',
fetch: fetchProvider(index),
fetch: fetchProvider(kibanaIndex),
isReady: () => true,
schema: {
installed: { type: 'array', items: { type: 'keyword' } },

View file

@ -6,11 +6,7 @@
* Side Public License, v 1.
*/
import {
loggingSystemMock,
pluginInitializerContextConfigMock,
elasticsearchServiceMock,
} from '../../../../../core/server/mocks';
import { loggingSystemMock, elasticsearchServiceMock } from '../../../../../core/server/mocks';
import {
Collector,
createCollectorFetchContextMock,
@ -29,7 +25,7 @@ describe('kibana_usage', () => {
return createUsageCollectionSetupMock().makeUsageCollector(config);
});
const legacyConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$;
const kibanaIndex = '.kibana-tests';
const getMockFetchClients = (hits?: unknown[]) => {
const fetchParamsMock = createCollectorFetchContextMock();
@ -40,7 +36,7 @@ describe('kibana_usage', () => {
return fetchParamsMock;
};
beforeAll(() => registerKibanaUsageCollector(usageCollectionMock, legacyConfig$));
beforeAll(() => registerKibanaUsageCollector(usageCollectionMock, kibanaIndex));
afterAll(() => jest.clearAllTimers());
test('registered collector is set', () => {

View file

@ -6,10 +6,8 @@
* Side Public License, v 1.
*/
import type { Observable } from 'rxjs';
import type { ElasticsearchClient, SharedGlobalConfig } from 'src/core/server';
import type { ElasticsearchClient } from 'src/core/server';
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { take } from 'rxjs/operators';
import { snakeCase } from 'lodash';
import { getSavedObjectsCounts } from './get_saved_object_counts';
@ -46,7 +44,7 @@ export async function getKibanaSavedObjectCounts(
export function registerKibanaUsageCollector(
usageCollection: UsageCollectionSetup,
legacyConfig$: Observable<SharedGlobalConfig>
kibanaIndex: string
) {
usageCollection.registerCollector(
usageCollection.makeUsageCollector<KibanaUsage>({
@ -83,12 +81,9 @@ export function registerKibanaUsageCollector(
},
},
async fetch({ esClient }) {
const {
kibana: { index },
} = await legacyConfig$.pipe(take(1)).toPromise();
return {
index,
...(await getKibanaSavedObjectCounts(esClient, index)),
index: kibanaIndex,
...(await getKibanaSavedObjectCounts(esClient, kibanaIndex)),
};
},
})

View file

@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
import { pluginInitializerContextConfigMock } from '../../../../../core/server/mocks';
import {
createCollectorFetchContextMock,
createUsageCollectionSetupMock,
@ -16,9 +15,9 @@ import { registerSavedObjectsCountUsageCollector } from './saved_objects_count_c
describe('saved_objects_count_collector', () => {
const usageCollectionMock = createUsageCollectionSetupMock();
const legacyConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$;
const kibanaIndex = '.kibana-tests';
beforeAll(() => registerSavedObjectsCountUsageCollector(usageCollectionMock, legacyConfig$));
beforeAll(() => registerSavedObjectsCountUsageCollector(usageCollectionMock, kibanaIndex));
afterAll(() => jest.clearAllTimers());
test('registered collector is set', () => {

View file

@ -6,9 +6,6 @@
* Side Public License, v 1.
*/
import type { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import type { SharedGlobalConfig } from 'src/core/server';
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { getSavedObjectsCounts } from './get_saved_object_counts';
@ -23,7 +20,7 @@ interface SavedObjectsCountUsage {
export function registerSavedObjectsCountUsageCollector(
usageCollection: UsageCollectionSetup,
legacyConfig$: Observable<SharedGlobalConfig>
kibanaIndex: string
) {
usageCollection.registerCollector(
usageCollection.makeUsageCollector<SavedObjectsCountUsage>({
@ -45,10 +42,7 @@ export function registerSavedObjectsCountUsageCollector(
},
},
async fetch({ esClient }) {
const {
kibana: { index },
} = await legacyConfig$.pipe(take(1)).toPromise();
const buckets = await getSavedObjectsCounts(esClient, index);
const buckets = await getSavedObjectsCounts(esClient, kibanaIndex);
return {
by_type: buckets.map(({ key: type, doc_count: count }) => {
return { type, count };

View file

@ -7,14 +7,13 @@
*/
import type { UsageCollectionSetup, UsageCounter } from 'src/plugins/usage_collection/server';
import { Subject, Observable } from 'rxjs';
import { Subject } from 'rxjs';
import type {
PluginInitializerContext,
CoreSetup,
Plugin,
ISavedObjectsRepository,
IUiSettingsClient,
SharedGlobalConfig,
CoreStart,
SavedObjectsServiceSetup,
OpsMetrics,
@ -55,7 +54,6 @@ type SavedObjectsRegisterType = SavedObjectsServiceSetup['registerType'];
export class KibanaUsageCollectionPlugin implements Plugin {
private readonly logger: Logger;
private readonly legacyConfig$: Observable<SharedGlobalConfig>;
private readonly instanceUuid: string;
private savedObjectsClient?: ISavedObjectsRepository;
private uiSettingsClient?: IUiSettingsClient;
@ -66,7 +64,6 @@ export class KibanaUsageCollectionPlugin implements Plugin {
constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
this.legacyConfig$ = initializerContext.config.legacy.globalConfig$;
this.metric$ = new Subject<OpsMetrics>();
this.pluginStop$ = new Subject();
this.instanceUuid = initializerContext.env.instanceUuid;
@ -121,6 +118,7 @@ export class KibanaUsageCollectionPlugin implements Plugin {
pluginStop$: Subject<void>,
registerType: SavedObjectsRegisterType
) {
const kibanaIndex = coreSetup.savedObjects.getKibanaIndex();
const getSavedObjectsClient = () => this.savedObjectsClient;
const getUiSettingsClient = () => this.uiSettingsClient;
const getCoreUsageDataService = () => this.coreUsageData!;
@ -133,8 +131,8 @@ export class KibanaUsageCollectionPlugin implements Plugin {
registerUsageCountersUsageCollector(usageCollection);
registerOpsStatsCollector(usageCollection, metric$);
registerKibanaUsageCollector(usageCollection, this.legacyConfig$);
registerSavedObjectsCountUsageCollector(usageCollection, this.legacyConfig$);
registerKibanaUsageCollector(usageCollection, kibanaIndex);
registerSavedObjectsCountUsageCollector(usageCollection, kibanaIndex);
registerManagementUsageCollector(usageCollection, getUiSettingsClient);
registerUiMetricUsageCollector(usageCollection, registerType, getSavedObjectsClient);
registerApplicationUsageCollector(

View file

@ -113,6 +113,7 @@ export class UsageCollectionPlugin implements Plugin<UsageCollectionSetup> {
public setup(core: CoreSetup): UsageCollectionSetup {
const config = this.initializerContext.config.get<ConfigType>();
const kibanaIndex = core.savedObjects.getKibanaIndex();
const collectorSet = new CollectorSet({
logger: this.logger.get('usage-collection', 'collector-set'),
@ -128,7 +129,6 @@ export class UsageCollectionPlugin implements Plugin<UsageCollectionSetup> {
const { createUsageCounter, getUsageCounterByType } = this.usageCountersService.setup(core);
const uiCountersUsageCounter = createUsageCounter('uiCounter');
const globalConfig = this.initializerContext.config.legacy.get();
const router = core.http.createRouter();
setupRoutes({
router,
@ -137,7 +137,7 @@ export class UsageCollectionPlugin implements Plugin<UsageCollectionSetup> {
collectorSet,
config: {
allowAnonymous: core.status.isStatusPageAnonymous(),
kibanaIndex: globalConfig.kibana.index,
kibanaIndex,
kibanaVersion: this.initializerContext.env.packageInfo.version,
server: core.http.getServerInfo(),
uuid: this.initializerContext.env.instanceUuid,

View file

@ -96,19 +96,25 @@ export interface PluginSetupContract {
>(
actionType: ActionType<Config, Secrets, Params, ExecutorResultData>
): void;
isPreconfiguredConnector(connectorId: string): boolean;
}
export interface PluginStartContract {
isActionTypeEnabled(id: string, options?: { notifyUsage: boolean }): boolean;
isActionExecutable(
actionId: string,
actionTypeId: string,
options?: { notifyUsage: boolean }
): boolean;
getActionsClientWithRequest(request: KibanaRequest): Promise<PublicMethodsOf<ActionsClient>>;
getActionsAuthorizationWithRequest(request: KibanaRequest): PublicMethodsOf<ActionsAuthorization>;
preconfiguredActions: PreConfiguredAction[];
renderActionParameterTemplates<Params extends ActionTypeParams = ActionTypeParams>(
actionTypeId: string,
actionId: string,
@ -127,6 +133,7 @@ export interface ActionsPluginsSetup {
features: FeaturesPluginSetup;
spaces?: SpacesPluginSetup;
}
export interface ActionsPluginsStart {
encryptedSavedObjects: EncryptedSavedObjectsPluginStart;
taskManager: TaskManagerStartContract;
@ -154,7 +161,7 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
private usageCounter?: UsageCounter;
private readonly telemetryLogger: Logger;
private readonly preconfiguredActions: PreConfiguredAction[];
private readonly kibanaIndexConfig: { kibana: { index: string } };
private kibanaIndex?: string;
constructor(initContext: PluginInitializerContext) {
this.logger = initContext.logger.get();
@ -164,13 +171,14 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
);
this.telemetryLogger = initContext.logger.get('usage');
this.preconfiguredActions = [];
this.kibanaIndexConfig = initContext.config.legacy.get();
}
public setup(
core: CoreSetup<ActionsPluginsStart>,
plugins: ActionsPluginsSetup
): PluginSetupContract {
this.kibanaIndex = core.savedObjects.getKibanaIndex();
this.licenseState = new LicenseState(plugins.licensing.license$);
this.isESOCanEncrypt = plugins.encryptedSavedObjects.canEncrypt;
@ -253,14 +261,14 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
core.http.registerRouteHandlerContext<ActionsRequestHandlerContext, 'actions'>(
'actions',
this.createRouteHandlerContext(core, this.kibanaIndexConfig.kibana.index)
this.createRouteHandlerContext(core, this.kibanaIndex)
);
if (usageCollection) {
initializeActionsTelemetry(
this.telemetryLogger,
plugins.taskManager,
core,
this.kibanaIndexConfig.kibana.index,
this.kibanaIndex,
this.preconfiguredActions
);
}
@ -282,7 +290,7 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
logger: this.logger,
coreStartServices: core.getStartServices(),
config: this.actionsConfig.cleanupFailedExecutionsTask,
kibanaIndex: this.kibanaIndexConfig.kibana.index,
kibanaIndex: this.kibanaIndex,
taskManagerIndex: plugins.taskManager.index,
});
}
@ -314,7 +322,7 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
actionExecutor,
actionTypeRegistry,
taskRunnerFactory,
kibanaIndexConfig,
kibanaIndex,
isESOCanEncrypt,
preconfiguredActions,
instantiateAuthorization,
@ -342,12 +350,10 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
request
);
const kibanaIndex = kibanaIndexConfig.kibana.index;
return new ActionsClient({
unsecuredSavedObjectsClient,
actionTypeRegistry: actionTypeRegistry!,
defaultKibanaIndex: kibanaIndex,
defaultKibanaIndex: kibanaIndex!,
scopedClusterClient: core.elasticsearch.client.asScoped(request),
preconfiguredActions,
request,

View file

@ -7,7 +7,7 @@
import type { PublicMethodsOf } from '@kbn/utility-types';
import { first, map, share } from 'rxjs/operators';
import { BehaviorSubject, Observable } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { combineLatest } from 'rxjs';
import { SecurityPluginSetup, SecurityPluginStart } from '../../security/server';
@ -108,10 +108,13 @@ export interface PluginSetupContract {
export interface PluginStartContract {
listTypes: RuleTypeRegistry['list'];
getRulesClientWithRequest(request: KibanaRequest): PublicMethodsOf<RulesClient>;
getAlertingAuthorizationWithRequest(
request: KibanaRequest
): PublicMethodsOf<AlertingAuthorization>;
getFrameworkHealth: () => Promise<AlertsHealth>;
}
@ -125,6 +128,7 @@ export interface AlertingPluginsSetup {
eventLog: IEventLogService;
statusService: StatusServiceSetup;
}
export interface AlertingPluginsStart {
actions: ActionsPluginStartContract;
taskManager: TaskManagerStartContract;
@ -150,7 +154,6 @@ export class AlertingPlugin {
private readonly kibanaVersion: PluginInitializerContext['env']['packageInfo']['version'];
private eventLogService?: IEventLogService;
private eventLogger?: IEventLogger;
private readonly kibanaIndexConfig: Observable<{ kibana: { index: string } }>;
private kibanaBaseUrl: string | undefined;
constructor(initializerContext: PluginInitializerContext) {
@ -160,7 +163,6 @@ export class AlertingPlugin {
this.rulesClientFactory = new RulesClientFactory();
this.alertingAuthorizationClientFactory = new AlertingAuthorizationClientFactory();
this.telemetryLogger = initializerContext.logger.get('usage');
this.kibanaIndexConfig = initializerContext.config.legacy.globalConfig$;
this.kibanaVersion = initializerContext.env.packageInfo.version;
}
@ -168,6 +170,7 @@ export class AlertingPlugin {
core: CoreSetup<AlertingPluginsStart, unknown>,
plugins: AlertingPluginsSetup
): PluginSetupContract {
const kibanaIndex = core.savedObjects.getKibanaIndex();
this.kibanaBaseUrl = core.http.basePath.publicBaseUrl;
this.licenseState = new LicenseState(plugins.licensing.license$);
this.security = plugins.security;
@ -211,14 +214,7 @@ export class AlertingPlugin {
usageCollection,
core.getStartServices().then(([_, { taskManager }]) => taskManager)
);
this.kibanaIndexConfig.subscribe((config) => {
initializeAlertingTelemetry(
this.telemetryLogger,
core,
plugins.taskManager,
config.kibana.index
);
});
initializeAlertingTelemetry(this.telemetryLogger, core, plugins.taskManager, kibanaIndex);
}
// Usage counter for telemetry

View file

@ -78,9 +78,9 @@ export class CanvasPlugin implements Plugin {
plugins.home.sampleData.addAppLinksToSampleDataset
);
// we need the kibana index provided by global config for the Canvas usage collector
const globalConfig = this.initializerContext.config.legacy.get();
registerCanvasUsageCollector(plugins.usageCollection, globalConfig.kibana.index);
// we need the kibana index for the Canvas usage collector
const kibanaIndex = coreSetup.savedObjects.getKibanaIndex();
registerCanvasUsageCollector(plugins.usageCollection, kibanaIndex);
setupInterpreter(expressionsFork);

View file

@ -6,12 +6,10 @@
*/
import {
SharedGlobalConfig,
ElasticsearchClient,
SavedObjectsErrorHelpers,
Logger,
} from '../../../../../src/core/server';
import { BehaviorSubject } from 'rxjs';
import { fetchProvider } from './fetch';
import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks';
@ -21,17 +19,13 @@ describe('fetchProvider', () => {
let mockLogger: Logger;
beforeEach(async () => {
const config$ = new BehaviorSubject<SharedGlobalConfig>({
kibana: {
index: '123',
},
} as any);
const kibanaIndex = '123';
mockLogger = {
warn: jest.fn(),
debug: jest.fn(),
} as any;
esClient = elasticsearchServiceMock.createElasticsearchClient();
fetchFn = fetchProvider(config$, mockLogger);
fetchFn = fetchProvider(kibanaIndex, mockLogger);
});
test('returns when ES returns no results', async () => {

View file

@ -5,9 +5,7 @@
* 2.0.
*/
import type { estypes } from '@elastic/elasticsearch';
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SharedGlobalConfig, Logger } from 'kibana/server';
import { Logger } from 'kibana/server';
import { CollectorFetchContext } from '../../../../../src/plugins/usage_collection/server';
import { SEARCH_SESSION_TYPE } from '../../../../../src/plugins/data/common';
import { ReportedUsage } from './register';
@ -17,12 +15,11 @@ interface SessionPersistedTermsBucket {
doc_count: number;
}
export function fetchProvider(config$: Observable<SharedGlobalConfig>, logger: Logger) {
export function fetchProvider(kibanaIndex: string, logger: Logger) {
return async ({ esClient }: CollectorFetchContext): Promise<ReportedUsage> => {
try {
const config = await config$.pipe(first()).toPromise();
const { body: esResponse } = await esClient.search<unknown>({
index: config.kibana.index,
index: kibanaIndex,
body: {
size: 0,
aggs: {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { PluginInitializerContext, Logger } from 'kibana/server';
import { Logger } from 'kibana/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { fetchProvider } from './fetch';
@ -15,16 +15,16 @@ export interface ReportedUsage {
totalCount: number;
}
export async function registerUsageCollector(
export function registerUsageCollector(
usageCollection: UsageCollectionSetup,
context: PluginInitializerContext,
kibanaIndex: string,
logger: Logger
) {
try {
const collector = usageCollection.makeUsageCollector<ReportedUsage>({
type: 'search-session',
isReady: () => true,
fetch: fetchProvider(context.config.legacy.globalConfig$, logger),
fetch: fetchProvider(kibanaIndex, logger),
schema: {
transientCount: { type: 'long' },
persistedCount: { type: 'long' },

View file

@ -53,7 +53,7 @@ export class EnhancedDataServerPlugin
});
if (deps.usageCollection) {
registerUsageCollector(deps.usageCollection, this.initializerContext, this.logger);
registerUsageCollector(deps.usageCollection, core.savedObjects.getKibanaIndex(), this.logger);
}
}

View file

@ -12,7 +12,6 @@ import {
Plugin as CorePlugin,
PluginInitializerContext,
IClusterClient,
SharedGlobalConfig,
IContextProvider,
} from 'src/core/server';
import { SpacesPluginStart } from '../../spaces/server';
@ -50,7 +49,6 @@ export class Plugin implements CorePlugin<IEventLogService, IEventLogClientServi
private eventLogService?: EventLogService;
private esContext?: EsContext;
private eventLogger?: IEventLogger;
private globalConfig: SharedGlobalConfig;
private eventLogClientService?: EventLogClientService;
private savedObjectProviderRegistry: SavedObjectProviderRegistry;
private kibanaVersion: PluginInitializerContext['env']['packageInfo']['version'];
@ -58,13 +56,12 @@ export class Plugin implements CorePlugin<IEventLogService, IEventLogClientServi
constructor(private readonly context: PluginInitializerContext) {
this.systemLogger = this.context.logger.get();
this.config = this.context.config.get<IEventLogConfig>();
this.globalConfig = this.context.config.legacy.get();
this.savedObjectProviderRegistry = new SavedObjectProviderRegistry();
this.kibanaVersion = this.context.env.packageInfo.version;
}
setup(core: CoreSetup): IEventLogService {
const kibanaIndex = this.globalConfig.kibana.index;
const kibanaIndex = core.savedObjects.getKibanaIndex();
this.systemLogger.debug('setting up plugin');

View file

@ -7,7 +7,6 @@
import { Plugin, CoreSetup, CoreStart, PluginInitializerContext, Logger } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { Observable } from 'rxjs';
import { PluginStart as DataPluginStart } from 'src/plugins/data/server';
import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
import { FieldFormatsStart } from 'src/plugins/field_formats/server';
@ -41,13 +40,12 @@ export interface LensServerPluginSetup {
}
export class LensServerPlugin implements Plugin<LensServerPluginSetup, {}, {}, {}> {
private readonly kibanaIndexConfig: Observable<{ kibana: { index: string } }>;
private readonly telemetryLogger: Logger;
constructor(private initializerContext: PluginInitializerContext) {
this.kibanaIndexConfig = initializerContext.config.legacy.globalConfig$;
this.telemetryLogger = initializerContext.logger.get('usage');
}
setup(core: CoreSetup<PluginStartContract>, plugins: PluginSetupContract) {
setupSavedObjects(core);
setupRoutes(core, this.initializerContext.logger.get());
@ -60,12 +58,7 @@ export class LensServerPlugin implements Plugin<LensServerPluginSetup, {}, {}, {
.getStartServices()
.then(([_, { taskManager }]) => taskManager as TaskManagerStartContract)
);
initializeLensTelemetry(
this.telemetryLogger,
core,
this.kibanaIndexConfig,
plugins.taskManager
);
initializeLensTelemetry(this.telemetryLogger, core, plugins.taskManager);
}
plugins.embeddable.registerEmbeddableFactory(lensEmbeddableFactory());

View file

@ -6,8 +6,6 @@
*/
import { CoreSetup, Logger, ElasticsearchClient } from 'kibana/server';
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import moment from 'moment';
import {
RunContext,
@ -28,10 +26,9 @@ export const TASK_ID = `Lens-${TELEMETRY_TASK_TYPE}`;
export function initializeLensTelemetry(
logger: Logger,
core: CoreSetup,
config: Observable<{ kibana: { index: string } }>,
taskManager: TaskManagerSetupContract
) {
registerLensTelemetryTask(logger, core, config, taskManager);
registerLensTelemetryTask(logger, core, taskManager);
}
export function scheduleLensTelemetry(logger: Logger, taskManager?: TaskManagerStartContract) {
@ -43,14 +40,13 @@ export function scheduleLensTelemetry(logger: Logger, taskManager?: TaskManagerS
function registerLensTelemetryTask(
logger: Logger,
core: CoreSetup,
config: Observable<{ kibana: { index: string } }>,
taskManager: TaskManagerSetupContract
) {
taskManager.registerTaskDefinitions({
[TELEMETRY_TASK_TYPE]: {
title: 'Lens usage fetch task',
timeout: '1m',
createTaskRunner: telemetryTaskRunner(logger, core, config),
createTaskRunner: telemetryTaskRunner(logger, core),
},
});
}
@ -177,11 +173,7 @@ export async function getDailyEvents(
};
}
export function telemetryTaskRunner(
logger: Logger,
core: CoreSetup,
config: Observable<{ kibana: { index: string } }>
) {
export function telemetryTaskRunner(logger: Logger, core: CoreSetup) {
return ({ taskInstance }: RunContext) => {
const { state } = taskInstance;
const getEsClient = async () => {
@ -191,7 +183,7 @@ export function telemetryTaskRunner(
return {
async run() {
const kibanaIndex = (await config.pipe(first()).toPromise()).kibana.index;
const kibanaIndex = core.savedObjects.getKibanaIndex();
return Promise.all([
getDailyEvents(kibanaIndex, getEsClient),

View file

@ -16,7 +16,6 @@ import type {
CapabilitiesStart,
IClusterClient,
SavedObjectsServiceStart,
SharedGlobalConfig,
UiSettingsServiceStart,
} from 'kibana/server';
import type { SecurityPluginSetup } from '../../security/server';
@ -82,14 +81,11 @@ export class MlServerPlugin
private dataViews: DataViewsPluginStart | null = null;
private isMlReady: Promise<void>;
private setMlReady: () => void = () => {};
private readonly kibanaIndexConfig: SharedGlobalConfig;
constructor(ctx: PluginInitializerContext) {
this.log = ctx.logger.get();
this.mlLicense = new MlLicense();
this.isMlReady = new Promise((resolve) => (this.setMlReady = resolve));
this.kibanaIndexConfig = ctx.config.legacy.get();
}
public setup(coreSetup: CoreSetup<PluginsStart>, plugins: PluginsSetup): MlPluginSetup {
@ -235,7 +231,7 @@ export class MlServerPlugin
}
if (plugins.usageCollection) {
registerCollector(plugins.usageCollection, this.kibanaIndexConfig.kibana.index);
registerCollector(plugins.usageCollection, coreSetup.savedObjects.getKibanaIndex());
}
return sharedServicesProviders;

View file

@ -104,7 +104,7 @@ export class MonitoringPlugin
kibanaStats: {
uuid: this.initializerContext.env.instanceUuid,
name: serverInfo.name,
index: this.legacyConfig.kibana.index,
index: coreSetup.savedObjects.getKibanaIndex(),
host: serverInfo.hostname,
locale: i18n.getLocale(),
port: serverInfo.port.toString(),

View file

@ -5,15 +5,7 @@
* 2.0.
*/
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import {
CoreSetup,
Plugin,
Logger,
PluginInitializerContext,
SharedGlobalConfig,
} from 'src/core/server';
import { CoreSetup, Plugin, Logger, PluginInitializerContext } from 'src/core/server';
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
@ -30,17 +22,15 @@ import { getCapabilitiesForRollupIndices } from '../../../../src/plugins/data/se
export class RollupPlugin implements Plugin<void, void, any, any> {
private readonly logger: Logger;
private readonly globalConfig$: Observable<SharedGlobalConfig>;
private readonly license: License;
constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
this.globalConfig$ = initializerContext.config.legacy.globalConfig$;
this.license = new License();
}
public setup(
{ http, uiSettings, getStartServices }: CoreSetup,
{ http, uiSettings, savedObjects, getStartServices }: CoreSetup,
{ features, licensing, indexManagement, visTypeTimeseries, usageCollection }: Dependencies
) {
this.license.setup(
@ -101,15 +91,11 @@ export class RollupPlugin implements Plugin<void, void, any, any> {
});
if (usageCollection) {
this.globalConfig$
.pipe(first())
.toPromise()
.then((globalConfig) => {
registerRollupUsageCollector(usageCollection, globalConfig.kibana.index);
})
.catch((e: any) => {
this.logger.warn(`Registering Rollup collector failed: ${e}`);
});
try {
registerRollupUsageCollector(usageCollection, savedObjects.getKibanaIndex());
} catch (e) {
this.logger.warn(`Registering Rollup collector failed: ${e}`);
}
}
if (indexManagement && indexManagement.indexDataEnricher) {

View file

@ -13,7 +13,6 @@ import {
KibanaRequest,
CoreStart,
IContextProvider,
SharedGlobalConfig,
} from 'src/core/server';
import { PluginStartContract as AlertingStart } from '../../alerting/server';
@ -53,7 +52,6 @@ export class RuleRegistryPlugin
>
{
private readonly config: RuleRegistryPluginConfig;
private readonly legacyConfig: SharedGlobalConfig;
private readonly logger: Logger;
private readonly kibanaVersion: string;
private readonly alertsClientFactory: AlertsClientFactory;
@ -62,8 +60,6 @@ export class RuleRegistryPlugin
constructor(initContext: PluginInitializerContext) {
this.config = initContext.config.get<RuleRegistryPluginConfig>();
// TODO: Can be removed in 8.0.0. Exists to work around multi-tenancy users.
this.legacyConfig = initContext.config.legacy.get();
this.logger = initContext.logger.get();
this.kibanaVersion = initContext.env.packageInfo.version;
this.ruleDataService = null;
@ -85,25 +81,10 @@ export class RuleRegistryPlugin
this.security = plugins.security;
const isWriteEnabled = (config: RuleRegistryPluginConfig, legacyConfig: SharedGlobalConfig) => {
const hasEnabledWrite = config.write.enabled;
const hasSetCustomKibanaIndex = legacyConfig.kibana.index !== '.kibana';
const hasSetUnsafeAccess = config.unsafe.legacyMultiTenancy.enabled;
if (!hasEnabledWrite) return false;
// Not using legacy multi-tenancy
if (!hasSetCustomKibanaIndex) {
return hasEnabledWrite;
} else {
return hasSetUnsafeAccess;
}
};
this.ruleDataService = new RuleDataService({
logger,
kibanaVersion,
isWriteEnabled: isWriteEnabled(this.config, this.legacyConfig),
isWriteEnabled: this.config.write.enabled,
getClusterClient: async () => {
const deps = await startDependencies;
return deps.core.elasticsearch.client.asInternalUser;

View file

@ -11,4 +11,4 @@ import { SavedObjectTaggingPlugin } from './plugin';
export { config } from './config';
export const plugin = (initializerContext: PluginInitializerContext) =>
new SavedObjectTaggingPlugin(initializerContext);
new SavedObjectTaggingPlugin();

View file

@ -19,7 +19,7 @@ describe('SavedObjectTaggingPlugin', () => {
let usageCollectionSetup: ReturnType<typeof usageCollectionPluginMock.createSetupContract>;
beforeEach(() => {
plugin = new SavedObjectTaggingPlugin(coreMock.createPluginInitializerContext());
plugin = new SavedObjectTaggingPlugin();
featuresPluginSetup = featuresPluginMock.createSetup();
usageCollectionSetup = usageCollectionPluginMock.createSetupContract();
// `usageCollection` 'mocked' implementation use the real `CollectorSet` implementation

View file

@ -5,14 +5,7 @@
* 2.0.
*/
import { Observable } from 'rxjs';
import {
CoreSetup,
CoreStart,
PluginInitializerContext,
Plugin,
SharedGlobalConfig,
} from 'src/core/server';
import { CoreSetup, CoreStart, Plugin } from 'src/core/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server';
import { SecurityPluginSetup } from '../../security/server';
@ -30,12 +23,6 @@ interface SetupDeps {
}
export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> {
private readonly legacyConfig$: Observable<SharedGlobalConfig>;
constructor(context: PluginInitializerContext) {
this.legacyConfig$ = context.config.legacy.globalConfig$;
}
public setup(
{ savedObjects, http }: CoreSetup,
{ features, usageCollection, security }: SetupDeps
@ -58,7 +45,7 @@ export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> {
usageCollection.registerCollector(
createTagUsageCollector({
usageCollection,
legacyConfig$: this.legacyConfig$,
kibanaIndex: savedObjects.getKibanaIndex(),
})
);
}

View file

@ -5,9 +5,6 @@
* 2.0.
*/
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import { SharedGlobalConfig } from 'src/core/server';
import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/server';
import { TaggingUsageData } from './types';
import { fetchTagUsageData } from './fetch_tag_usage_data';
@ -15,18 +12,17 @@ import { tagUsageCollectorSchema } from './schema';
export const createTagUsageCollector = ({
usageCollection,
legacyConfig$,
kibanaIndex,
}: {
usageCollection: UsageCollectionSetup;
legacyConfig$: Observable<SharedGlobalConfig>;
kibanaIndex: string;
}) => {
return usageCollection.makeUsageCollector<TaggingUsageData>({
type: 'saved_objects_tagging',
isReady: () => true,
schema: tagUsageCollectorSchema,
fetch: async ({ esClient }) => {
const { kibana } = await legacyConfig$.pipe(take(1)).toPromise();
return fetchTagUsageData({ esClient, kibanaIndex: kibana.index });
fetch: ({ esClient }) => {
return fetchTagUsageData({ esClient, kibanaIndex });
},
});
};

View file

@ -6,7 +6,6 @@
*/
import type { Subscription } from 'rxjs';
import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import type { TypeOf } from '@kbn/config-schema';
@ -203,6 +202,7 @@ export class SecurityPlugin
core: CoreSetup<PluginStartDependencies>,
{ features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies
) {
this.kibanaIndexName = core.savedObjects.getKibanaIndex();
const config$ = this.initializerContext.config.create<TypeOf<typeof ConfigSchema>>().pipe(
map((rawConfig) =>
createConfig(rawConfig, this.initializerContext.logger.get('config'), {
@ -210,12 +210,8 @@ export class SecurityPlugin
})
)
);
this.configSubscription = combineLatest([
config$,
this.initializerContext.config.legacy.globalConfig$,
]).subscribe(([config, { kibana }]) => {
this.configSubscription = config$.subscribe((config) => {
this.config = config;
this.kibanaIndexName = kibana.index;
});
const config = this.getConfig();

View file

@ -34,7 +34,6 @@ export const createMockConfig = (): ConfigType => {
underlyingClient: UnderlyingLogClient.savedObjects,
},
kibanaIndex: '.kibana',
experimentalFeatures: parseExperimentalConfigValue(enableExperimental),
};
};

View file

@ -139,20 +139,15 @@ export const configSchema = schema.object({
export type ConfigSchema = TypeOf<typeof configSchema>;
export type ConfigType = ConfigSchema & {
kibanaIndex: string;
experimentalFeatures: ExperimentalFeatures;
};
export const createConfig = (context: PluginInitializerContext): ConfigType => {
const globalConfig = context.config.legacy.get();
const pluginConfig = context.config.get<TypeOf<typeof configSchema>>();
const kibanaIndex = globalConfig.kibana.index;
const experimentalFeatures = parseExperimentalConfigValue(pluginConfig.enableExperimental);
return {
...pluginConfig,
kibanaIndex,
experimentalFeatures,
};
};

View file

@ -107,6 +107,7 @@ export class Plugin implements ISecuritySolutionPlugin {
private checkMetadataTransformsTask: CheckMetadataTransformsTask | undefined;
private artifactsCache: LRU<string, Buffer>;
private telemetryUsageCounter?: UsageCounter;
private kibanaIndex?: string;
constructor(context: PluginInitializerContext) {
this.pluginContext = context;
@ -130,6 +131,7 @@ export class Plugin implements ISecuritySolutionPlugin {
const { pluginContext, config, logger, appClientFactory } = this;
const experimentalFeatures = config.experimentalFeatures;
this.kibanaIndex = core.savedObjects.getKibanaIndex();
appClientFactory.setup({
getSpaceId: plugins.spaces?.spacesService?.getSpaceId,
@ -162,7 +164,7 @@ export class Plugin implements ISecuritySolutionPlugin {
initUsageCollectors({
core,
kibanaIndex: config.kibanaIndex,
kibanaIndex: core.savedObjects.getKibanaIndex(),
signalsIndex: config.signalsIndex,
ml: plugins.ml,
usageCollection: plugins.usageCollection,
@ -411,7 +413,8 @@ export class Plugin implements ISecuritySolutionPlugin {
this.telemetryReceiver.start(
core,
config.kibanaIndex,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.kibanaIndex!,
this.endpointAppContextService,
exceptionListClient
);

View file

@ -94,8 +94,6 @@ export class SpacesPlugin
{
private readonly config$: Observable<ConfigType>;
private readonly kibanaIndexConfig$: Observable<{ kibana: { index: string } }>;
private readonly log: Logger;
private readonly spacesLicenseService = new SpacesLicenseService();
@ -110,7 +108,6 @@ export class SpacesPlugin
constructor(initializerContext: PluginInitializerContext) {
this.config$ = initializerContext.config.create<ConfigType>();
this.kibanaIndexConfig$ = initializerContext.config.legacy.globalConfig$;
this.log = initializerContext.logger.get();
this.spacesService = new SpacesService();
this.spacesClientService = new SpacesClientService((message) => this.log.debug(message));
@ -180,7 +177,7 @@ export class SpacesPlugin
if (plugins.usageCollection) {
registerSpacesUsageCollector(plugins.usageCollection, {
kibanaIndexConfig$: this.kibanaIndexConfig$,
kibanaIndex: core.savedObjects.getKibanaIndex(),
features: plugins.features,
licensing: plugins.licensing,
usageStatsServicePromise,

View file

@ -7,10 +7,7 @@
import * as Rx from 'rxjs';
import {
elasticsearchServiceMock,
pluginInitializerContextConfigMock,
} from 'src/core/server/mocks';
import { elasticsearchServiceMock } from 'src/core/server/mocks';
import { createCollectorFetchContextMock } from '../../../../../src/plugins/usage_collection/server/mocks';
import type { KibanaFeature } from '../../../features/server';
@ -43,6 +40,8 @@ const MOCK_USAGE_STATS: UsageStats = {
'apiCalls.disableLegacyUrlAliases.total': 17,
};
const kibanaIndex = '.kibana-tests';
function setup({
license = { isAvailable: true },
features = [{ id: 'feature1' } as KibanaFeature, { id: 'feature2' } as KibanaFeature],
@ -53,6 +52,7 @@ function setup({
constructor({ fetch }: any) {
this.fetch = fetch;
}
// to make typescript happy
public fakeFetchUsage() {
return this.fetch;
@ -121,7 +121,7 @@ describe('error handling', () => {
license: { isAvailable: true, type: 'basic' },
});
const collector = getSpacesUsageCollector(usageCollection as any, {
kibanaIndexConfig$: Rx.of({ kibana: { index: '.kibana' } }),
kibanaIndex,
features,
licensing,
usageStatsServicePromise: Promise.resolve(usageStatsService),
@ -145,7 +145,7 @@ describe('with a basic license', () => {
beforeAll(async () => {
const collector = getSpacesUsageCollector(usageCollection as any, {
kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$,
kibanaIndex,
features,
licensing,
usageStatsServicePromise: Promise.resolve(usageStatsService),
@ -164,7 +164,7 @@ describe('with a basic license', () => {
size: 0,
track_total_hits: true,
},
index: '.kibana-tests',
index: kibanaIndex,
});
});
@ -204,7 +204,7 @@ describe('with no license', () => {
beforeAll(async () => {
const collector = getSpacesUsageCollector(usageCollection as any, {
kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$,
kibanaIndex,
features,
licensing,
usageStatsServicePromise: Promise.resolve(usageStatsService),
@ -245,7 +245,7 @@ describe('with platinum license', () => {
beforeAll(async () => {
const collector = getSpacesUsageCollector(usageCollection as any, {
kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$,
kibanaIndex,
features,
licensing,
usageStatsServicePromise: Promise.resolve(usageStatsService),

View file

@ -5,7 +5,6 @@
* 2.0.
*/
import type { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import type { ElasticsearchClient } from 'src/core/server';
@ -150,7 +149,7 @@ export interface UsageData extends UsageStats {
}
interface CollectorDeps {
kibanaIndexConfig$: Observable<{ kibana: { index: string } }>;
kibanaIndex: string;
features: PluginsSetup['features'];
licensing: PluginsSetup['licensing'];
usageStatsServicePromise: Promise<UsageStatsServiceSetup>;
@ -426,12 +425,10 @@ export function getSpacesUsageCollector(
},
},
fetch: async ({ esClient }: CollectorFetchContext) => {
const { licensing, kibanaIndexConfig$, features, usageStatsServicePromise } = deps;
const { licensing, kibanaIndex, features, usageStatsServicePromise } = deps;
const license = await licensing.license$.pipe(take(1)).toPromise();
const available = license.isAvailable; // some form of spaces is available for all valid licenses
const kibanaIndex = (await kibanaIndexConfig$.pipe(take(1)).toPromise()).kibana.index;
const usageData = await getSpacesUsage(esClient, kibanaIndex, features, available);
const usageStats = await getUsageStats(usageStatsServicePromise, available);