Skip to content

Commit

Permalink
[Reporting] Add deprecation notice to the upgrade assistant (#104303)
Browse files Browse the repository at this point in the history
* add deprecation notice to the upgrade assistant

* fix types and update jest snapshot

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
jloleysens and kibanamachine authored Jul 22, 2021
1 parent d5b5a42 commit 58e2dd3
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 66 deletions.
52 changes: 0 additions & 52 deletions x-pack/plugins/reporting/server/deprecations.ts

This file was deleted.

28 changes: 28 additions & 0 deletions x-pack/plugins/reporting/server/deprecations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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 { CoreSetup } from 'src/core/server';
import { ReportingCore } from '../core';

import { getDeprecationsInfo as getIlmPolicyDeprecationsInfo } from './migrate_existing_indices_ilm_policy';
import { getDeprecationsInfo as getReportingRoleDeprecationsInfo } from './reporting_role';

export const registerDeprecations = ({
core,
reportingCore,
}: {
core: CoreSetup;
reportingCore: ReportingCore;
}) => {
core.deprecations.registerDeprecations({
getDeprecations: async (ctx) => {
return [
...(await getIlmPolicyDeprecationsInfo(ctx, { reportingCore })),
...(await getReportingRoleDeprecationsInfo(ctx, { reportingCore })),
];
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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 { GetDeprecationsContext } from 'src/core/server';
import { elasticsearchServiceMock, savedObjectsClientMock } from 'src/core/server/mocks';

import { ReportingCore } from '../core';
import { createMockConfigSchema, createMockReportingCore } from '../test_helpers';

import { getDeprecationsInfo } from './migrate_existing_indices_ilm_policy';

type ScopedClusterClientMock = ReturnType<
typeof elasticsearchServiceMock.createScopedClusterClient
>;

const { createApiResponse } = elasticsearchServiceMock;

describe("Migrate existing indices' ILM policy deprecations", () => {
let esClient: ScopedClusterClientMock;
let deprecationsCtx: GetDeprecationsContext;
let reportingCore: ReportingCore;

beforeEach(async () => {
esClient = elasticsearchServiceMock.createScopedClusterClient();
deprecationsCtx = { esClient, savedObjectsClient: savedObjectsClientMock.create() };
reportingCore = await createMockReportingCore(createMockConfigSchema());
});

const createIndexSettings = (lifecycleName: string) => ({
aliases: {},
mappings: {},
settings: {
index: {
lifecycle: {
name: lifecycleName,
},
},
},
});

it('returns deprecation information when reporting indices are not using the reporting ILM policy', async () => {
esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce(
createApiResponse({
body: {
indexA: createIndexSettings('not-reporting-lifecycle'),
indexB: createIndexSettings('kibana-reporting'),
},
})
);

expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
"api": Object {
"method": "PUT",
"path": "/api/reporting/deprecations/migrate_ilm_policy",
},
"manualSteps": Array [
"Update all reporting indices to use the \\"kibana-reporting\\" policy using the index settings API.",
],
},
"level": "warning",
"message": "New reporting indices will be managed by the \\"kibana-reporting\\" provisioned ILM policy. You must edit this policy to manage the report lifecycle. This change targets all indices prefixed with \\".reporting-*\\".",
},
]
`);
});

it('does not return deprecations when all reporting indices are managed by the provisioned ILM policy', async () => {
esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce(
createApiResponse({
body: {
indexA: createIndexSettings('kibana-reporting'),
indexB: createIndexSettings('kibana-reporting'),
},
})
);

expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot(
`Array []`
);

esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce(
createApiResponse({
body: {},
})
);

expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot(
`Array []`
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { DeprecationsDetails, GetDeprecationsContext } from 'src/core/server';
import { API_MIGRATE_ILM_POLICY_URL, ILM_POLICY_NAME } from '../../common/constants';
import { ReportingCore } from '../core';
import { deprecations } from '../lib/deprecations';

interface ExtraDependencies {
reportingCore: ReportingCore;
}

export const getDeprecationsInfo = async (
{ esClient }: GetDeprecationsContext,
{ reportingCore }: ExtraDependencies
): Promise<DeprecationsDetails[]> => {
const store = await reportingCore.getStore();
const indexPattern = store.getReportingIndexPattern();

const migrationStatus = await deprecations.checkIlmMigrationStatus({
reportingCore,
elasticsearchClient: esClient.asInternalUser,
});

if (migrationStatus !== 'ok') {
return [
{
level: 'warning',
message: i18n.translate('xpack.reporting.deprecations.migrateIndexIlmPolicyActionMessage', {
defaultMessage: `New reporting indices will be managed by the "{reportingIlmPolicy}" provisioned ILM policy. You must edit this policy to manage the report lifecycle. This change targets all indices prefixed with "{indexPattern}".`,
values: {
reportingIlmPolicy: ILM_POLICY_NAME,
indexPattern,
},
}),
correctiveActions: {
manualSteps: [
i18n.translate(
'xpack.reporting.deprecations.migrateIndexIlmPolicy.manualStepOneMessage',
{
defaultMessage:
'Update all reporting indices to use the "{reportingIlmPolicy}" policy using the index settings API.',
values: { reportingIlmPolicy: ILM_POLICY_NAME },
}
),
],
api: {
method: 'PUT',
path: API_MIGRATE_ILM_POLICY_URL,
},
},
},
];
}

return [];
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* 2.0.
*/

import { ReportingCore } from '.';
import { registerDeprecations } from './deprecations';
import { createMockConfigSchema, createMockReportingCore } from './test_helpers';
import { coreMock, elasticsearchServiceMock } from 'src/core/server/mocks';
import { ReportingCore } from '..';
import { getDeprecationsInfo } from './reporting_role';
import { createMockConfigSchema, createMockReportingCore } from '../test_helpers';
import { elasticsearchServiceMock } from 'src/core/server/mocks';
import { GetDeprecationsContext, IScopedClusterClient } from 'kibana/server';

let reportingCore: ReportingCore;
Expand All @@ -26,17 +26,22 @@ beforeEach(async () => {
});

test('logs no deprecations when setup has no issues', async () => {
const { getDeprecations } = await registerDeprecations(reportingCore, coreMock.createSetup());
expect(await getDeprecations(context)).toMatchInlineSnapshot(`Array []`);
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`Array []`);
});

test('logs a plain message when only a reporting_user role issue is found', async () => {
esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({
body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } },
});

const { getDeprecations } = await registerDeprecations(reportingCore, coreMock.createSetup());
expect(await getDeprecations(context)).toMatchInlineSnapshot(`
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
Expand All @@ -61,8 +66,11 @@ test('logs multiple entries when multiple reporting_user role issues are found',
},
});

const { getDeprecations } = await registerDeprecations(reportingCore, coreMock.createSetup());
expect(await getDeprecations(context)).toMatchInlineSnapshot(`
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
Expand All @@ -87,8 +95,11 @@ test('logs an expanded message when a config issue and a reporting_user role iss
const mockReportingConfig = createMockConfigSchema({ roles: { enabled: true } });
reportingCore = await createMockReportingCore(mockReportingConfig);

const { getDeprecations } = await registerDeprecations(reportingCore, coreMock.createSetup());
expect(await getDeprecations(context)).toMatchInlineSnapshot(`
expect(
await getDeprecationsInfo(context, {
reportingCore,
})
).toMatchInlineSnapshot(`
Array [
Object {
"correctiveActions": Object {
Expand Down
48 changes: 48 additions & 0 deletions x-pack/plugins/reporting/server/deprecations/reporting_role.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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 { GetDeprecationsContext, DeprecationsDetails } from 'src/core/server';
import { ReportingCore } from '..';

const deprecatedRole = 'reporting_user';
const upgradableConfig = 'xpack.reporting.roles.enabled: false';

interface ExtraDependencies {
reportingCore: ReportingCore;
}

export const getDeprecationsInfo = async (
{ esClient }: GetDeprecationsContext,
{ reportingCore }: ExtraDependencies
): Promise<DeprecationsDetails[]> => {
const usingDeprecatedConfig = !reportingCore.getContract().usesUiCapabilities();
const deprecations: DeprecationsDetails[] = [];
const { body: users } = await esClient.asCurrentUser.security.getUser();

const reportingUsers = Object.entries(users)
.filter(([username, user]) => user.roles.includes(deprecatedRole))
.map(([, user]) => user.username);
const numReportingUsers = reportingUsers.length;

if (numReportingUsers > 0) {
const usernames = reportingUsers.join('", "');
deprecations.push({
message: `The deprecated "${deprecatedRole}" role has been found for ${numReportingUsers} user(s): "${usernames}"`,
documentationUrl: 'https://www.elastic.co/guide/en/kibana/current/secure-reporting.html',
level: 'critical',
correctiveActions: {
manualSteps: [
...(usingDeprecatedConfig ? [`Set "${upgradableConfig}" in kibana.yml`] : []),
`Create one or more custom roles that provide Kibana application privileges to reporting features in **Management > Security > Roles**.`,
`Assign the custom role(s) as desired, and remove the "${deprecatedRole}" role from the user(s).`,
],
},
});
}

return deprecations;
};
5 changes: 4 additions & 1 deletion x-pack/plugins/reporting/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export class ReportingPlugin
});

registerUiSettings(core);
registerDeprecations(reportingCore, core);
registerDeprecations({
core,
reportingCore,
});
registerReportingUsageCollector(reportingCore, plugins);
registerRoutes(reportingCore, this.logger);

Expand Down

0 comments on commit 58e2dd3

Please sign in to comment.