Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const REPORTING_DATA_STREAM_WILDCARD = '.kibana-reporting*';
export const REPORTING_LEGACY_INDICES = '.reporting-*';
// Used to search for all reports and check for managing privileges
export const REPORTING_DATA_STREAM_WILDCARD_WITH_LEGACY = '.reporting-*,.kibana-reporting*';
// Name of index template
export const REPORTING_DATA_STREAM_INDEX_TEMPLATE = '.kibana-reporting';
// Name of component template which Kibana overrides for lifecycle settings
export const REPORTING_DATA_STREAM_COMPONENT_TEMPLATE = 'kibana-reporting@custom';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import { Report, ReportingStore, SavedReport } from '.';
import { ReportingCore } from '../..';
import { createMockReportingCore } from '../../test_helpers';

type MockEsClient = ReturnType<typeof elasticsearchServiceMock.createElasticsearchClient>;

describe('ReportingStore', () => {
const mockLogger = loggingSystemMock.createLogger();
let mockCore: ReportingCore;
let mockEsClient: ReturnType<typeof elasticsearchServiceMock.createElasticsearchClient>;
let mockEsClient: MockEsClient;

beforeEach(async () => {
const reportingConfig = {
Expand Down Expand Up @@ -455,6 +457,7 @@ describe('ReportingStore', () => {
it('creates an ILM policy for managing reporting indices if there is not already one', async () => {
mockEsClient.ilm.getLifecycle.mockRejectedValue({ statusCode: 404 });
mockEsClient.ilm.putLifecycle.mockResponse({} as any);
mockCallsForApplyingMapping(mockEsClient);

const store = new TestReportingStore(mockCore, mockLogger);
const createIlmPolicySpy = jest.spyOn(store, 'createIlmPolicy');
Expand All @@ -478,6 +481,7 @@ describe('ReportingStore', () => {

it('does not create an ILM policy for managing reporting indices if one already exists', async () => {
mockEsClient.ilm.getLifecycle.mockResponse({});
mockCallsForApplyingMapping(mockEsClient);

const store = new TestReportingStore(mockCore, mockLogger);
const createIlmPolicySpy = jest.spyOn(store, 'createIlmPolicy');
Expand All @@ -493,6 +497,9 @@ describe('ReportingStore', () => {
statefulSettings: { enabled: false },
};
mockCore = await createMockReportingCore(createMockConfigSchema(reportingConfig));
mockEsClient = (await mockCore.getEsClient()).asInternalUser as typeof mockEsClient;

mockCallsForApplyingMapping(mockEsClient);

const store = new TestReportingStore(mockCore, mockLogger);
const createIlmPolicySpy = jest.spyOn(store, 'createIlmPolicy');
Expand All @@ -502,3 +509,26 @@ describe('ReportingStore', () => {
});
});
});

function mockCallsForApplyingMapping(mockEsClient: MockEsClient) {
mockEsClient.indices.exists.mockResponse(true);
mockEsClient.indices.getIndexTemplate.mockResponse({
index_templates: [
{
name: '.kibana-reporting',
index_template: {
template: {
mappings: {
properties: {
foo: {
type: 'keyword',
},
},
},
},
},
},
],
} as any);
mockEsClient.indices.putMapping.mockResponse(undefined as any);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
import {
REPORTING_DATA_STREAM_ALIAS,
REPORTING_DATA_STREAM_COMPONENT_TEMPLATE,
REPORTING_DATA_STREAM_INDEX_TEMPLATE,
} from '@kbn/reporting-server';
import moment from 'moment';
import type { Report } from '.';
Expand Down Expand Up @@ -170,12 +171,66 @@ export class ReportingStore {
await this.createIlmPolicy();
}
} catch (e) {
this.logger.error('Error in start phase');
this.logger.error(e);
this.logger.error(`Error creating ILM policy: ${e.message}`, {
error: { stack_trace: e.stack },
});
throw e;
}

try {
await this.reapplyMappings();
} catch (e) {
this.logger.error(`Error applying mappings: ${e.message}`, {
error: { stack_trace: e.stack },
});
throw e;
}
}

private async reapplyMappings(): Promise<void> {
const client = await this.getClient();

const exists = await client.indices.exists({
index: REPORTING_DATA_STREAM_ALIAS,
});

if (!exists) {
this.logger.info(
`Mappings not applied to ${REPORTING_DATA_STREAM_ALIAS} since it does not exist.`
);
return;
}

const gotTemplate = await client.indices.getIndexTemplate({
name: REPORTING_DATA_STREAM_INDEX_TEMPLATE,
});
if (gotTemplate.index_templates.length === 0) {
throw new Error(`No index template found for ${REPORTING_DATA_STREAM_INDEX_TEMPLATE}`);
}

const template = gotTemplate.index_templates.find(
(t) => t.name === REPORTING_DATA_STREAM_INDEX_TEMPLATE
);
if (!template) {
throw new Error(
`No matching index template found for ${REPORTING_DATA_STREAM_INDEX_TEMPLATE}`
);
}

const mappings = template.index_template.template?.mappings?.properties;
if (!mappings) {
throw new Error(`No mappings found for ${REPORTING_DATA_STREAM_INDEX_TEMPLATE}`);
}

await client.indices.putMapping({
index: REPORTING_DATA_STREAM_ALIAS,
properties: mappings,
write_index_only: true,
});

this.logger.info(`Mappings applied to ${REPORTING_DATA_STREAM_ALIAS}`);
}

public async addReport(report: Report): Promise<SavedReport> {
try {
report.updateWithEsDoc(await this.indexReport(report));
Expand Down