mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[8.7] Only log deprecation warnings for calls to Saved Objects routes from non-kibana request (#152971) (#153053)
# Backport This will backport the following commits from `main` to `8.7`: - [Only log deprecation warnings for calls to Saved Objects routes from non-kibana request (#152971)](https://github.com/elastic/kibana/pull/152971) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Christiane (Tina) Heiligers","email":"christiane.heiligers@elastic.co"},"sourceCommit":{"committedDate":"2023-03-09T17:23:21Z","message":"Only log deprecation warnings for calls to Saved Objects routes from non-kibana request (#152971)\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"e37e83428abe9bb8971419672969bcaa9db9918e","branchLabelMapping":{"^v8.8.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","Feature:Saved Objects","release_note:skip","backport:prev-minor","v8.8.0"],"number":152971,"url":"https://github.com/elastic/kibana/pull/152971","mergeCommit":{"message":"Only log deprecation warnings for calls to Saved Objects routes from non-kibana request (#152971)\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"e37e83428abe9bb8971419672969bcaa9db9918e"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.8.0","labelRegex":"^v8.8.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/152971","number":152971,"mergeCommit":{"message":"Only log deprecation warnings for calls to Saved Objects routes from non-kibana request (#152971)\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"e37e83428abe9bb8971419672969bcaa9db9918e"}}]}] BACKPORT-->
This commit is contained in:
parent
ac4f4e5e6a
commit
6e8c4f5c3d
14 changed files with 201 additions and 34 deletions
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfAnyTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -51,9 +55,12 @@ export const registerBulkCreateRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn(
|
||||
"The bulk create saved object API '/api/saved_objects/_bulk_create' is deprecated."
|
||||
);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/api/saved_objects/_bulk_create',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { overwrite } = req.query;
|
||||
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfAnyTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -37,9 +41,12 @@ export const registerBulkDeleteRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn(
|
||||
"The bulk update saved object API '/api/saved_objects/_bulk_update' is deprecated."
|
||||
);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/api/saved_objects/_bulk_delete',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { force } = req.query;
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
usageStatsClient.incrementSavedObjectsBulkDelete({ request: req }).catch(() => {});
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfAnyTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -36,7 +40,12 @@ export const registerBulkGetRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The bulk get saved object API '/api/saved_objects/_bulk_get' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/api/saved_objects/_bulk_get',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
usageStatsClient.incrementSavedObjectsBulkGet({ request: req }).catch(() => {});
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfAnyTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -34,9 +38,12 @@ export const registerBulkResolveRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn(
|
||||
"The bulk resolve saved object API '/api/saved_objects/_bulk_resolve' is deprecated."
|
||||
);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/api/saved_objects/_bulk_resolve',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
usageStatsClient.incrementSavedObjectsBulkResolve({ request: req }).catch(() => {});
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfAnyTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -46,9 +50,12 @@ export const registerBulkUpdateRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn(
|
||||
"The bulk update saved object API '/api/saved_objects/_bulk_update' is deprecated."
|
||||
);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'put',
|
||||
path: '/api/saved_objects/_bulk_update',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
usageStatsClient.incrementSavedObjectsBulkUpdate({ request: req }).catch(() => {});
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -50,7 +54,12 @@ export const registerCreateRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The create saved object API '/api/saved_objects/{type}/{id}' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/api/saved_objects/{type}/{id?}',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { type, id } = req.params;
|
||||
const { overwrite } = req.query;
|
||||
const { attributes, migrationVersion, coreMigrationVersion, references, initialNamespaces } =
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -35,7 +39,12 @@ export const registerDeleteRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The delete saved object API '/api/saved_objects/{type}/{id}' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'delete',
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { type, id } = req.params;
|
||||
const { force } = req.query;
|
||||
const { getClient, typeRegistry } = (await context.core).savedObjects;
|
||||
|
|
|
@ -11,7 +11,7 @@ import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-serve
|
|||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwOnHttpHiddenTypes } from './utils';
|
||||
|
||||
import { logWarnOnExternalRequest } from './utils';
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
logger: Logger;
|
||||
|
@ -61,7 +61,12 @@ export const registerFindRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The find saved object API '/api/saved_objects/_find' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/api/saved_objects/_find',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const query = req.query;
|
||||
|
||||
const namespaces =
|
||||
|
|
|
@ -10,7 +10,11 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -32,7 +36,12 @@ export const registerGetRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The get saved object API '/api/saved_objects/{type}/{id}' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { type, id } = req.params;
|
||||
|
||||
const usageStatsClient = coreUsageData.getClient();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { schema } from '@kbn/config-schema';
|
|||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { throwIfTypeNotVisibleByAPI } from './utils';
|
||||
import { throwIfTypeNotVisibleByAPI, logWarnOnExternalRequest } from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -32,9 +32,12 @@ export const registerResolveRoute = (
|
|||
},
|
||||
},
|
||||
router.handleLegacyErrors(async (context, req, res) => {
|
||||
logger.warn(
|
||||
"The resolve saved object API '/api/saved_objects/resolve/{type}/{id}' is deprecated."
|
||||
);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/api/saved_objects/resolve/{type}/{id}',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { type, id } = req.params;
|
||||
const { savedObjects } = await context.core;
|
||||
|
||||
|
|
|
@ -11,7 +11,11 @@ import type { SavedObjectsUpdateOptions } from '@kbn/core-saved-objects-api-serv
|
|||
import type { Logger } from '@kbn/logging';
|
||||
import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
|
||||
import type { InternalSavedObjectRouter } from '../internal_types';
|
||||
import { catchAndReturnBoomErrors, throwIfTypeNotVisibleByAPI } from './utils';
|
||||
import {
|
||||
catchAndReturnBoomErrors,
|
||||
logWarnOnExternalRequest,
|
||||
throwIfTypeNotVisibleByAPI,
|
||||
} from './utils';
|
||||
|
||||
interface RouteDependencies {
|
||||
coreUsageData: InternalCoreUsageDataSetup;
|
||||
|
@ -47,7 +51,12 @@ export const registerUpdateRoute = (
|
|||
},
|
||||
},
|
||||
catchAndReturnBoomErrors(async (context, req, res) => {
|
||||
logger.warn("The update saved object API '/api/saved_objects/{type}/{id}' is deprecated.");
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
req,
|
||||
logger,
|
||||
});
|
||||
const { type, id } = req.params;
|
||||
const { attributes, version, references, upsert } = req.body;
|
||||
const options: SavedObjectsUpdateOptions = { version, references, upsert };
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
throwOnGloballyHiddenTypes,
|
||||
throwIfTypeNotVisibleByAPI,
|
||||
throwIfAnyTypeNotVisibleByAPI,
|
||||
logWarnOnExternalRequest,
|
||||
} from './utils';
|
||||
import { Readable } from 'stream';
|
||||
import { createPromiseFromStreams, createConcatStream } from '@kbn/utils';
|
||||
|
@ -27,6 +28,8 @@ import type {
|
|||
} from '@kbn/core-http-server';
|
||||
import { kibanaResponseFactory } from '@kbn/core-http-router-server-internal';
|
||||
import { typeRegistryInstanceMock } from '../saved_objects_service.test.mocks';
|
||||
import { httpServerMock } from '@kbn/core-http-server-mocks';
|
||||
import { loggerMock, type MockedLogger } from '@kbn/logging-mocks';
|
||||
|
||||
async function readStreamToCompletion(stream: Readable) {
|
||||
return createPromiseFromStreams([stream, createConcatStream([])]);
|
||||
|
@ -341,3 +344,60 @@ describe('throwIfAnyTypeNotVisibleByAPI', () => {
|
|||
expect(() => throwIfAnyTypeNotVisibleByAPI(['config'], registry)).not.toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('logWarnOnExternalRequest', () => {
|
||||
let logger: MockedLogger;
|
||||
const firstPartyRequestHeaders = { 'kbn-version': 'a', referer: 'b' };
|
||||
const kibRequest = httpServerMock.createKibanaRequest({ headers: firstPartyRequestHeaders });
|
||||
const extRequest = httpServerMock.createKibanaRequest();
|
||||
|
||||
beforeEach(() => {
|
||||
logger = loggerMock.create();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('logs on external requests to non-bulk apis', () => {
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/resolve/{type}/{id}',
|
||||
req: extRequest,
|
||||
logger,
|
||||
});
|
||||
expect(logger.warn).toHaveBeenCalledTimes(1);
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
'The get saved object API /resolve/{type}/{id} is deprecated.'
|
||||
);
|
||||
});
|
||||
|
||||
it('logs on external requests to bulk apis', () => {
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/_bulk_resolve',
|
||||
req: extRequest,
|
||||
logger,
|
||||
});
|
||||
expect(logger.warn).toHaveBeenCalledTimes(1);
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
'The post saved object API /_bulk_resolve is deprecated.'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not log a warning on internal requests', () => {
|
||||
logWarnOnExternalRequest({
|
||||
method: 'get',
|
||||
path: '/resolve/{type}/{id}',
|
||||
req: kibRequest,
|
||||
logger,
|
||||
});
|
||||
expect(logger.warn).toHaveBeenCalledTimes(0);
|
||||
logWarnOnExternalRequest({
|
||||
method: 'post',
|
||||
path: '/_bulk_resolve',
|
||||
req: kibRequest,
|
||||
logger,
|
||||
});
|
||||
expect(logger.warn).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,13 +16,14 @@ import {
|
|||
createConcatStream,
|
||||
} from '@kbn/utils';
|
||||
import Boom from '@hapi/boom';
|
||||
import type { RequestHandlerWrapper } from '@kbn/core-http-server';
|
||||
import type {
|
||||
import type { KibanaRequest, RequestHandlerWrapper } from '@kbn/core-http-server';
|
||||
import {
|
||||
SavedObject,
|
||||
ISavedObjectTypeRegistry,
|
||||
SavedObjectsExportResultDetails,
|
||||
} from '@kbn/core-saved-objects-server';
|
||||
import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server';
|
||||
import { Logger } from '@kbn/logging';
|
||||
|
||||
export async function createSavedObjectsStreamFromNdJson(ndJsonStream: Readable) {
|
||||
const savedObjects = await createPromiseFromStreams([
|
||||
|
@ -152,3 +153,27 @@ export interface BulkGetItem {
|
|||
fields?: string[];
|
||||
namespaces?: string[];
|
||||
}
|
||||
|
||||
export function isKibanaRequest({ headers }: KibanaRequest) {
|
||||
// The presence of these two request headers gives us a good indication that this is a first-party request from the Kibana client.
|
||||
// We can't be 100% certain, but this is a reasonable attempt.
|
||||
return headers && headers['kbn-version'] && headers.referer;
|
||||
}
|
||||
|
||||
export interface LogWarnOnExternalRequest {
|
||||
method: string;
|
||||
path: string;
|
||||
req: KibanaRequest;
|
||||
logger: Logger;
|
||||
}
|
||||
/**
|
||||
* Only log a warning when the request is internal
|
||||
* Allows us to silence the logs for development
|
||||
* @internal
|
||||
*/
|
||||
export function logWarnOnExternalRequest(params: LogWarnOnExternalRequest) {
|
||||
const { method, path, req, logger } = params;
|
||||
if (!isKibanaRequest(req)) {
|
||||
logger.warn(`The ${method} saved object API ${path} is deprecated.`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
"@kbn/core-elasticsearch-server-mocks",
|
||||
"@kbn/utils",
|
||||
"@kbn/core-http-router-server-internal",
|
||||
"@kbn/logging-mocks",
|
||||
"@kbn/core-saved-objects-utils-server",
|
||||
],
|
||||
"exclude": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue