Skip to content

Commit

Permalink
[Fleet] cleanup old file upload index and index template (#162329)
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet authored Jul 24, 2023
1 parent 6775f58 commit d2825d9
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 1 deletion.
1 change: 0 additions & 1 deletion x-pack/plugins/fleet/server/services/setup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jest.mock('./setup/upgrade_package_install_version');
jest.mock('./epm/elasticsearch/template/install', () => {
return {
...jest.requireActual('./epm/elasticsearch/template/install'),
ensureFileUploadWriteIndices: jest.fn(),
};
});

Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/fleet/server/services/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
ensurePreconfiguredFleetServerHosts,
getPreconfiguredFleetServerHostFromConfig,
} from './preconfiguration/fleet_server_host';
import { cleanUpOldFileIndices } from './setup/clean_old_fleet_indices';

export interface SetupStatus {
isInitialized: boolean;
Expand All @@ -75,6 +76,8 @@ async function createSetupSideEffects(
const logger = appContextService.getLogger();
logger.info('Beginning fleet setup');

await cleanUpOldFileIndices(esClient, logger);

await ensureFleetDirectories();

const { agentPolicies: policiesOrUndefined, packages: packagesOrUndefined } =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';

import { loggingSystemMock } from '@kbn/core-logging-server-mocks';

import { cleanUpOldFileIndices } from './clean_old_fleet_indices';

describe('cleanUpOldFileIndices', () => {
it('should clean old indices and old index templates', async () => {
const logger = loggingSystemMock.createLogger();
const esClient = elasticsearchServiceMock.createInternalClient();
esClient.indices.get.mockResolvedValueOnce({
'.fleet-files-agent': {},
'.fleet-files-test': {},
});
esClient.indices.get.mockImplementation(({ index }) => {
if (index === '.fleet-files-agent') {
return {
'.fleet-files-agent': {},
'.fleet-files-test': {},
} as any;
}
return {};
});

await cleanUpOldFileIndices(esClient, logger);

expect(esClient.indices.delete).toBeCalledTimes(1);
expect(esClient.indices.delete).toBeCalledWith(
expect.objectContaining({
index: '.fleet-files-agent,.fleet-files-test',
})
);

expect(esClient.indices.deleteIndexTemplate).toBeCalledTimes(1);
expect(esClient.indices.deleteIndexTemplate).toBeCalledWith(
expect.objectContaining({
name: '.fleet-files,.fleet-file-data,.fleet-filedelivery-data,.fleet-filedelivery-meta',
})
);
expect(logger.warn).not.toBeCalled();
});

it('should log a warning and not throw if an unexpected error happen', async () => {
const logger = loggingSystemMock.createLogger();
const esClient = elasticsearchServiceMock.createInternalClient();
esClient.indices.get.mockRejectedValue(new Error('test error'));

await cleanUpOldFileIndices(esClient, logger);

expect(logger.warn).toBeCalledWith('Old fleet indices cleanup failed: test error');
});

it('should handle 404 while deleting index template', async () => {
const logger = loggingSystemMock.createLogger();
const esClient = elasticsearchServiceMock.createInternalClient();
esClient.indices.get.mockResolvedValue({});
esClient.indices.deleteIndexTemplate.mockRejectedValue({
meta: {
statusCode: 404,
},
});

await cleanUpOldFileIndices(esClient, logger);

expect(esClient.indices.deleteIndexTemplate).toBeCalledTimes(1);
expect(logger.warn).not.toBeCalled();
});

it('should handle 404 when deleting old index', async () => {
const logger = loggingSystemMock.createLogger();
const esClient = elasticsearchServiceMock.createInternalClient();
esClient.indices.get.mockResolvedValueOnce({
'.fleet-files-agent': {},
'.fleet-files-test': {},
});
esClient.indices.get.mockImplementation(({ index }) => {
if (index === '.fleet-files-agent') {
return {
'.fleet-files-agent': {},
'.fleet-files-test': {},
} as any;
}
return {};
});

esClient.indices.delete.mockRejectedValue({
meta: {
statusCode: 404,
},
});

await cleanUpOldFileIndices(esClient, logger);

expect(esClient.indices.delete).toBeCalledTimes(1);
expect(logger.warn).not.toBeCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { ElasticsearchClient, Logger } from '@kbn/core/server';
import pMap from 'p-map';

const INDICES_TO_CLEAN = [
'.fleet-files-*',
'.fleet-file-data-*',
'.fleet-filedelivery-data-*',
'.fleet-filedelivery-meta-*',
];

const INDEX_TEMPLATE_TO_CLEAN = [
'.fleet-files',
'.fleet-file-data',
'.fleet-filedelivery-data',
'.fleet-filedelivery-meta',
];

/**
* In 8.10 upload feature moved from using index to datastreams, this function allows to clean those old indices.
*/
export async function cleanUpOldFileIndices(esClient: ElasticsearchClient, logger: Logger) {
try {
// Clean indices
await pMap(
INDICES_TO_CLEAN,
async (indiceToClean) => {
const res = await esClient.indices.get({
index: indiceToClean,
});
const indices = Object.keys(res);
if (indices.length) {
await esClient.indices
.delete({
index: indices.join(','),
})
.catch((err) => {
// Skip not found errors
if (err.meta?.statusCode !== 404) {
throw err;
}
});
}
},
{ concurrency: 2 }
);
await esClient.indices
.deleteIndexTemplate({
name: INDEX_TEMPLATE_TO_CLEAN.join(','),
})
.catch((err) => {
// Skip not found errors
if (err.meta?.statusCode !== 404) {
throw err;
}
});
// Clean index template
} catch (err) {
logger.warn(`Old fleet indices cleanup failed: ${err.message}`);
}
}

0 comments on commit d2825d9

Please sign in to comment.