Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dot-kibana-split' into dot-kib…
Browse files Browse the repository at this point in the history
…ana-split-security-solution
  • Loading branch information
pgayvallet committed Apr 19, 2023
2 parents 501937d + bc094dc commit 8aa4f96
Show file tree
Hide file tree
Showing 87 changed files with 3,778 additions and 242 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
setSecurityExtension: deps.savedObjects.setSecurityExtension,
setSpacesExtension: deps.savedObjects.setSpacesExtension,
registerType: deps.savedObjects.registerType,
getKibanaIndex: deps.savedObjects.getKibanaIndex,
getDefaultIndex: deps.savedObjects.getDefaultIndex,
getAllIndices: deps.savedObjects.getAllIndices,
},
status: {
core$: deps.status.core$,
Expand Down Expand Up @@ -313,6 +314,10 @@ export function createPluginStartContext<TPlugin, TPluginDependencies>(
createExporter: deps.savedObjects.createExporter,
createImporter: deps.savedObjects.createImporter,
getTypeRegistry: deps.savedObjects.getTypeRegistry,
getDefaultIndex: deps.savedObjects.getDefaultIndex,
getIndexForType: deps.savedObjects.getIndexForType,
getIndicesForTypes: deps.savedObjects.getIndicesForTypes,
getAllIndices: deps.savedObjects.getAllIndices,
},
metrics: {
collectionInterval: deps.metrics.collectionInterval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { type RawPackageInfo, Env } from '@kbn/config';
import { ByteSizeValue } from '@kbn/config-schema';
import { REPO_ROOT } from '@kbn/repo-info';
import { getEnvOptions } from '@kbn/config-mocks';
import { SavedObjectsType, MAIN_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
import { mockCoreContext } from '@kbn/core-base-server-mocks';
Expand Down Expand Up @@ -55,6 +56,14 @@ import { getSavedObjectsDeprecationsProvider } from './deprecations';
jest.mock('./object_types');
jest.mock('./deprecations');

const createType = (parts: Partial<SavedObjectsType>): SavedObjectsType => ({
name: 'test-type',
hidden: false,
namespaceType: 'single',
mappings: { properties: {} },
...parts,
});

describe('SavedObjectsService', () => {
let deprecationsSetup: ReturnType<typeof createDeprecationRegistryProviderMock>;

Expand Down Expand Up @@ -630,5 +639,85 @@ describe('SavedObjectsService', () => {
expect(includedHiddenTypes).toEqual(['someHiddenType']);
});
});

describe('index retrieval APIs', () => {
let soService: SavedObjectsService;

beforeEach(async () => {
const coreContext = createCoreContext({ skipMigration: false });
soService = new SavedObjectsService(coreContext);

typeRegistryInstanceMock.getType.mockImplementation((type: string) => {
if (type === 'dashboard') {
return createType({
name: 'dashboard',
});
} else if (type === 'foo') {
return createType({
name: 'foo',
indexPattern: '.kibana_foo',
});
} else if (type === 'bar') {
return createType({
name: 'bar',
indexPattern: '.kibana_bar',
});
} else if (type === 'bar_too') {
return createType({
name: 'bar_too',
indexPattern: '.kibana_bar',
});
} else {
return undefined;
}
});

await soService.setup(createSetupDeps());
});

describe('#getDefaultIndex', () => {
it('return the default index', async () => {
const { getDefaultIndex } = await soService.start(createStartDeps());
expect(getDefaultIndex()).toEqual(MAIN_SAVED_OBJECT_INDEX);
});
});

describe('#getIndexForType', () => {
it('return the correct index for type specifying its indexPattern', async () => {
const { getIndexForType } = await soService.start(createStartDeps());
expect(getIndexForType('bar')).toEqual('.kibana_bar');
});
it('return the correct index for type not specifying its indexPattern', async () => {
const { getIndexForType } = await soService.start(createStartDeps());
expect(getIndexForType('dashboard')).toEqual(MAIN_SAVED_OBJECT_INDEX);
});
it('return the default index for unknown type', async () => {
const { getIndexForType } = await soService.start(createStartDeps());
expect(getIndexForType('unknown_type')).toEqual(MAIN_SAVED_OBJECT_INDEX);
});
});

describe('#getIndicesForTypes', () => {
it('return the correct indices for specified types', async () => {
const { getIndicesForTypes } = await soService.start(createStartDeps());
expect(getIndicesForTypes(['dashboard', 'foo', 'bar'])).toEqual([
MAIN_SAVED_OBJECT_INDEX,
'.kibana_foo',
'.kibana_bar',
]);
});
it('ignore duplicate indices', async () => {
const { getIndicesForTypes } = await soService.start(createStartDeps());
expect(getIndicesForTypes(['bar', 'bar_too'])).toEqual(['.kibana_bar']);
});
it('return the default index for unknown type', async () => {
const { getIndicesForTypes } = await soService.start(createStartDeps());
expect(getIndicesForTypes(['unknown', 'foo'])).toEqual([
MAIN_SAVED_OBJECT_INDEX,
'.kibana_foo',
]);
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import {
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
import type { DeprecationRegistryProvider } from '@kbn/core-deprecations-server';
import type { NodeInfo } from '@kbn/core-node-server';
import { MAIN_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
import { MAIN_SAVED_OBJECT_INDEX, SavedObjectsIndexPatterns } from '@kbn/core-saved-objects-server';
import { registerRoutes } from './routes';
import { calculateStatus$ } from './status';
import { registerCoreObjectTypes } from './object_types';
Expand Down Expand Up @@ -197,7 +197,8 @@ export class SavedObjectsService
this.typeRegistry.registerType(type);
},
getTypeRegistry: () => this.typeRegistry,
getKibanaIndex: () => MAIN_SAVED_OBJECT_INDEX,
getDefaultIndex: () => MAIN_SAVED_OBJECT_INDEX,
getAllIndices: () => [...SavedObjectsIndexPatterns],
};
}

Expand Down Expand Up @@ -340,6 +341,21 @@ export class SavedObjectsService
importSizeLimit: options?.importSizeLimit ?? this.config!.maxImportExportSize,
}),
getTypeRegistry: () => this.typeRegistry,
getDefaultIndex: () => MAIN_SAVED_OBJECT_INDEX,
getIndexForType: (type: string) => {
const definition = this.typeRegistry.getType(type);
return definition?.indexPattern ?? MAIN_SAVED_OBJECT_INDEX;
},
getIndicesForTypes: (types: string[]) => {
const indices = new Set<string>();
types.forEach((type) => {
const definition = this.typeRegistry.getType(type);
const index = definition?.indexPattern ?? MAIN_SAVED_OBJECT_INDEX;
indices.add(index);
});
return [...indices];
},
getAllIndices: () => [...SavedObjectsIndexPatterns],
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const createStartContractMock = (typeRegistry?: jest.Mocked<ISavedObjectTypeRegi
createExporter: jest.fn(),
createImporter: jest.fn(),
getTypeRegistry: jest.fn(),
getDefaultIndex: jest.fn(),
getIndexForType: jest.fn(),
getIndicesForTypes: jest.fn(),
getAllIndices: jest.fn(),
};

startContrat.getScopedClient.mockReturnValue(savedObjectsClientMock.create());
Expand All @@ -50,6 +54,10 @@ const createStartContractMock = (typeRegistry?: jest.Mocked<ISavedObjectTypeRegi
startContrat.getTypeRegistry.mockReturnValue(typeRegistry ?? typeRegistryMock.create());
startContrat.createExporter.mockReturnValue(savedObjectsExporterMock.create());
startContrat.createImporter.mockReturnValue(savedObjectsImporterMock.create());
startContrat.getDefaultIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
startContrat.getIndexForType.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
startContrat.getIndicesForTypes.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);
startContrat.getAllIndices.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);

return startContrat;
};
Expand All @@ -68,10 +76,12 @@ const createSetupContractMock = () => {
setSecurityExtension: jest.fn(),
setSpacesExtension: jest.fn(),
registerType: jest.fn(),
getKibanaIndex: jest.fn(),
getDefaultIndex: jest.fn(),
getAllIndices: jest.fn(),
};

setupContract.getKibanaIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
setupContract.getDefaultIndex.mockReturnValue(MAIN_SAVED_OBJECT_INDEX);
setupContract.getAllIndices.mockReturnValue([MAIN_SAVED_OBJECT_INDEX]);

return setupContract;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export type { SavedObjectStatusMeta } from './src/saved_objects_status';
export {
MAIN_SAVED_OBJECT_INDEX,
TASK_MANAGER_SAVED_OBJECT_INDEX,
INGEST_SAVED_OBJECT_INDEX,
ALERTING_CASES_SAVED_OBJECT_INDEX,
SECURITY_SOLUTION_SAVED_OBJECT_INDEX,
SavedObjectsIndexPatterns,
} from './src/saved_objects_index_pattern';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,14 @@ export interface SavedObjectsServiceSetup {
/**
* Returns the default index used for saved objects.
*/
getKibanaIndex: () => string;
getDefaultIndex: () => string;

/**
* Returns all (aliases to) kibana system indices used for saved object storage.
*
* @deprecated use the `start` contract counterpart.
*/
getAllIndices: () => string[];
}

/**
Expand Down Expand Up @@ -209,4 +216,25 @@ export interface SavedObjectsServiceStart {
* {@link SavedObjectsType | saved object types}
*/
getTypeRegistry: () => ISavedObjectTypeRegistry;
/**
* Returns the (alias to the) index that the specified saved object type is stored in.
*
* @param type The SO type to retrieve the index/alias for.
*/
getIndexForType: (type: string) => string;
/**
* Returns the (alias to the) index that the specified saved object type is stored in.
*
* @remark if multiple types are living in the same index, duplicates will be removed.
* @param types The SO types to retrieve the index/alias for.
*/
getIndicesForTypes: (types: string[]) => string[];
/**
* Returns the default index used for saved objects.
*/
getDefaultIndex: () => string;
/**
* Returns all (aliases to) kibana system indices used for saved object storage.
*/
getAllIndices: () => string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
*/
export const MAIN_SAVED_OBJECT_INDEX = '.kibana';
export const TASK_MANAGER_SAVED_OBJECT_INDEX = `${MAIN_SAVED_OBJECT_INDEX}_task_manager`;
export const INGEST_SAVED_OBJECT_INDEX = `${MAIN_SAVED_OBJECT_INDEX}_ingest`;
export const ALERTING_CASES_SAVED_OBJECT_INDEX = `${MAIN_SAVED_OBJECT_INDEX}_alerting_cases`;
export const SECURITY_SOLUTION_SAVED_OBJECT_INDEX = `${MAIN_SAVED_OBJECT_INDEX}_security_solution`;
export const SavedObjectsIndexPatterns = [
MAIN_SAVED_OBJECT_INDEX,
TASK_MANAGER_SAVED_OBJECT_INDEX,
ALERTING_CASES_SAVED_OBJECT_INDEX,
INGEST_SAVED_OBJECT_INDEX,
SECURITY_SOLUTION_SAVED_OBJECT_INDEX,
];
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,14 @@ export function dashboardTaskRunner(logger: Logger, core: CoreSetup, embeddable:
return dashboardData;
};

const kibanaIndex = core.savedObjects.getKibanaIndex();
const dashboardIndex = await core
.getStartServices()
.then(([coreStart]) => coreStart.savedObjects.getIndexForType('dashboard'));
const pageSize = 50;

const searchParams = {
size: pageSize,
index: kibanaIndex,
index: dashboardIndex,
ignore_unavailable: true,
filter_path: ['hits.hits', '_scroll_id'],
body: { query: { bool: { filter: { term: { type: 'dashboard' } } } } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export class KqlTelemetryService implements Plugin<void> {

if (usageCollection) {
try {
makeKQLUsageCollector(usageCollection, savedObjects.getKibanaIndex());
const getIndexForType = (type: string) =>
getStartServices().then(([coreStart]) => coreStart.savedObjects.getIndexForType(type));
makeKQLUsageCollector(usageCollection, getIndexForType);
} catch (e) {
this.initializerContext.logger
.get('kql-telemetry')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function setupMockCallCluster(
describe('makeKQLUsageCollector', () => {
describe('fetch method', () => {
beforeEach(() => {
fetch = fetchProvider('.kibana');
fetch = fetchProvider(() => Promise.resolve('.kibana'));
});

it('should return opt in data from the .kibana/kql-telemetry doc', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ export interface Usage {
defaultQueryLanguage: string;
}

export function fetchProvider(index: string) {
export function fetchProvider(getIndexForType: (type: string) => Promise<string>) {
return async ({ esClient }: CollectorFetchContext): Promise<Usage> => {
const [response, config] = await Promise.all([
esClient.get(
{
index,
index: await getIndexForType('kql-telemetry'),
id: 'kql-telemetry:kql-telemetry',
},
{ ignore: [404] }
),
esClient.search(
{
index,
index: await getIndexForType('config'),
body: { query: { term: { type: 'config' } } },
},
{ ignore: [404] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
describe('makeKQLUsageCollector', () => {
let usageCollectionMock: jest.Mocked<UsageCollectionSetup>;

const getIndexForType = () => Promise.resolve('.kibana');

beforeEach(() => {
usageCollectionMock = {
makeUsageCollector: jest.fn(),
Expand All @@ -20,12 +22,12 @@ describe('makeKQLUsageCollector', () => {
});

it('should call registerCollector', () => {
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, '.kibana');
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, getIndexForType);
expect(usageCollectionMock.registerCollector).toHaveBeenCalledTimes(1);
});

it('should call makeUsageCollector with type = kql', () => {
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, '.kibana');
makeKQLUsageCollector(usageCollectionMock as UsageCollectionSetup, getIndexForType);
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('kql');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { fetchProvider, Usage } from './fetch';

export function makeKQLUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) {
export function makeKQLUsageCollector(
usageCollection: UsageCollectionSetup,
getIndexForType: (type: string) => Promise<string>
) {
const kqlUsageCollector = usageCollection.makeUsageCollector<Usage>({
type: 'kql',
fetch: fetchProvider(kibanaIndex),
fetch: fetchProvider(getIndexForType),
isReady: () => true,
schema: {
optInCount: { type: 'long' },
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/data/server/search/collectors/search/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ interface SearchTelemetry {
'search-telemetry': CollectedUsage;
}

export function fetchProvider(kibanaIndex: string) {
export function fetchProvider(getIndexForType: (type: string) => Promise<string>) {
return async ({ esClient }: CollectorFetchContext): Promise<ReportedUsage> => {
const searchIndex = await getIndexForType('search-telemetry');
const esResponse = await esClient.search<SearchTelemetry>(
{
index: kibanaIndex,
index: searchIndex,
body: {
query: { term: { type: { value: 'search-telemetry' } } },
},
Expand Down
Loading

0 comments on commit 8aa4f96

Please sign in to comment.