Skip to content

Commit

Permalink
[ILM] Fixed snapshot repositories and policies routes (elastic#129200)
Browse files Browse the repository at this point in the history
* [ILM] Fixed snapshot repositories and policies routes

* [ILM] Updated console.log to error

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
yuliacech and kibanamachine authored Apr 12, 2022
1 parent 294fe2b commit d7c6bfb
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,16 @@
* 2.0.
*/

import { ElasticsearchClient } from 'kibana/server';

import { RouteDependencies } from '../../../types';
import { addBasePath } from '../../../services';

async function fetchSnapshotPolicies(client: ElasticsearchClient): Promise<any> {
const response = await client.slm.getLifecycle();
return response.body;
}

export function registerFetchRoute({ router, license, lib: { handleEsError } }: RouteDependencies) {
router.get(
{ path: addBasePath('/snapshot_policies'), validate: false },
license.guardApiRoute(async (context, request, response) => {
try {
const policiesByName = await fetchSnapshotPolicies(
context.core.elasticsearch.client.asCurrentUser
);
const policiesByName =
await context.core.elasticsearch.client.asCurrentUser.slm.getLifecycle();
return response.ok({ body: Object.keys(policiesByName) });
} catch (error) {
return handleEsError({ error, response });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const registerFetchRoute = ({ router, license }: RouteDependencies) => {
name: '*',
});
const repos: ListSnapshotReposResponse = {
repositories: Object.keys(esResult.body),
repositories: Object.keys(esResult),
};
return response.ok({ body: repos });
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export const DEFAULT_POLICY_NAME = 'watch-history-ilm-policy';
export const INDEX_TEMPLATE_NAME = 'api-integration-tests-template';
export const INDEX_TEMPLATE_PATTERN_PREFIX = 'api_integration_tests_';
export const NODE_CUSTOM_ATTRIBUTE = 'name:apiIntegrationTestNode';
export const SNAPSHOT_REPOSITORY_NAME = 'test_repo';
export const CLOUD_REPOSITORY_NAME = 'found-snapshots';
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ export default function ({ loadTestFile }) {
loadTestFile(require.resolve('./templates'));
loadTestFile(require.resolve('./indices'));
loadTestFile(require.resolve('./nodes'));
loadTestFile(require.resolve('./snapshot_policies'));
loadTestFile(require.resolve('./snapshot_repositories'));
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
import { API_BASE_PATH, SNAPSHOT_REPOSITORY_NAME } from './constants';

export const registerSnapshotPoliciesHelpers = (getService: FtrProviderContext['getService']) => {
const supertest = getService('supertest');
const es = getService('es');

let policiesCreated: string[] = [];

const loadSnapshotPolicies = () => supertest.get(`${API_BASE_PATH}/snapshot_policies`);

const createSnapshotPolicy = (policyName: string, repositoryName?: string) => {
return es.slm
.putLifecycle({
policy_id: policyName,
config: {
indices: 'test_index',
},
name: policyName,
repository: repositoryName ?? SNAPSHOT_REPOSITORY_NAME,
schedule: '0 30 1 * * ?',
})
.then(() => policiesCreated.push(policyName));
};

const deletePolicy = (policyName: string) => es.slm.deleteLifecycle({ policy_id: policyName });

const cleanupPolicies = () =>
Promise.all(policiesCreated.map(deletePolicy))
.then(() => {
policiesCreated = [];
})
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`[Cleanup error] Error deleting ES resources: ${err.message}`);
});

return {
loadSnapshotPolicies,
createSnapshotPolicy,
cleanupPolicies,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { registerSnapshotPoliciesHelpers } from './snapshot_policies.helpers';
import { registerSnapshotRepositoriesHelpers } from './snapshot_repositories.helpers';
import { SNAPSHOT_REPOSITORY_NAME } from './constants';

const snapshotPolicyName = 'test_snapshot_policy';
export default function ({ getService }: FtrProviderContext) {
const deployment = getService('deployment');

const { loadSnapshotPolicies, createSnapshotPolicy, cleanupPolicies } =
registerSnapshotPoliciesHelpers(getService);

const { createSnapshotRepository, cleanupRepositories } =
registerSnapshotRepositoriesHelpers(getService);

describe('snapshot policies', () => {
before(async () => Promise.all([cleanupPolicies(), cleanupRepositories()]));
after(async () => Promise.all([cleanupPolicies(), cleanupRepositories()]));

it('returns empty array if no policies', async () => {
const { body } = await loadSnapshotPolicies().expect(200);
expect(body).to.eql([]);
});

it('returns policies', async () => {
const isCloud = await deployment.isCloud();
if (!isCloud) {
await createSnapshotRepository(SNAPSHOT_REPOSITORY_NAME);
}
await createSnapshotPolicy(snapshotPolicyName);
const { body } = await loadSnapshotPolicies().expect(200);

expect(body).to.have.length(1);
expect(body[0]).to.eql(snapshotPolicyName);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
import { API_BASE_PATH } from './constants';

export const registerSnapshotRepositoriesHelpers = (
getService: FtrProviderContext['getService']
) => {
const supertest = getService('supertest');
const es = getService('es');

let repositoriesCreated: string[] = [];

const loadSnapshotRepositories = () => supertest.get(`${API_BASE_PATH}/snapshot_repositories`);

const createSnapshotRepository = (repositoryName: string) => {
return es.snapshot
.createRepository({
name: repositoryName,
body: {
type: 'fs',
settings: {
location: '/tmp/repo',
},
},
verify: false,
})
.then(() => repositoriesCreated.push(repositoryName));
};

const deleteRepository = (repositoryName: string) => {
return es.snapshot.deleteRepository({ name: repositoryName });
};

const cleanupRepositories = () =>
Promise.all(repositoriesCreated.map(deleteRepository))
.then(() => {
repositoriesCreated = [];
})
.catch((err) => {
// eslint-disable-next-line no-console
console.error(`[Cleanup error] Error deleting ES resources: ${err.message}`);
});

return {
loadSnapshotRepositories,
createSnapshotRepository,
cleanupRepositories,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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 expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { registerSnapshotRepositoriesHelpers } from './snapshot_repositories.helpers';
import { CLOUD_REPOSITORY_NAME } from './constants';

const repositoryName = 'test_repository';

export default function ({ getService }: FtrProviderContext) {
const deployment = getService('deployment');
let isCloud: boolean;

const { loadSnapshotRepositories, createSnapshotRepository, cleanupRepositories } =
registerSnapshotRepositoriesHelpers(getService);

describe('snapshot repositories', () => {
before(async () => {
isCloud = await deployment.isCloud();
await Promise.all([cleanupRepositories()]);
});
after(async () => Promise.all([cleanupRepositories()]));

it('returns empty array if no repositories ', async () => {
const {
body: { repositories },
} = await loadSnapshotRepositories().expect(200);
if (!isCloud) {
expect(repositories).to.eql([]);
}
});

it('returns cloud default repository if on Cloud', async () => {
const {
body: { repositories },
} = await loadSnapshotRepositories().expect(200);
if (isCloud) {
expect(repositories).to.have.length(1);
expect(repositories).to.eql([CLOUD_REPOSITORY_NAME]);
}
});

it('returns repositories', async () => {
await createSnapshotRepository(repositoryName);
const {
body: { repositories },
} = await loadSnapshotRepositories().expect(200);

if (isCloud) {
expect(repositories).to.have.length(2);
expect(repositories[0]).to.contain(repositoryName);
} else {
expect(repositories).to.have.length(1);
expect(repositories[0]).to.eql(repositoryName);
}
});
});
}

0 comments on commit d7c6bfb

Please sign in to comment.