mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[http] Only allow 2023-10-31
when registering public versions (#159553)
## Summary Adds logic (and tests) to ensure that all registered public routes are set to `2023-10-31` for now. This check is only performed in dev mode which allows us to test our existing route default logic. ### Notes This works best as a runtime check given the versioned router API, but perhaps I missed a way to do this with just type checking?
This commit is contained in:
parent
9ebe5d5f53
commit
2b81164ff9
36 changed files with 211 additions and 162 deletions
|
@ -116,7 +116,7 @@ describe('Versioned route', () => {
|
|||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('only allows versions date strings for public APIs', () => {
|
||||
it('only allows correctly formatted version date strings for public APIs', () => {
|
||||
const versionedRouter = CoreVersionedRouter.from({ router });
|
||||
expect(() =>
|
||||
versionedRouter
|
||||
|
@ -136,80 +136,10 @@ describe('Versioned route', () => {
|
|||
expect(() =>
|
||||
versionedRouter
|
||||
.get({ path: '/test/{id}', access: 'public' })
|
||||
.addVersion({ version: '2020-02-02', validate: false }, handlerFn)
|
||||
.addVersion({ version: '2023-10-31', validate: false }, handlerFn)
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('runs request and response validations', async () => {
|
||||
let handler: RequestHandler;
|
||||
|
||||
let validatedBody = false;
|
||||
let validatedParams = false;
|
||||
let validatedQuery = false;
|
||||
let validatedOutputBody = false;
|
||||
|
||||
(router.post as jest.Mock).mockImplementation((opts: unknown, fn) => (handler = fn));
|
||||
const versionedRouter = CoreVersionedRouter.from({ router, isDev: true });
|
||||
versionedRouter.post({ path: '/test/{id}', access: 'internal' }).addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedBody = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
params: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedParams = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
query: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedQuery = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
body: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedOutputBody = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
handlerFn
|
||||
);
|
||||
|
||||
const kibanaResponse = await handler!(
|
||||
{} as any,
|
||||
createRequest({
|
||||
version: '1',
|
||||
body: { foo: 1 },
|
||||
params: { foo: 1 },
|
||||
query: { foo: 1 },
|
||||
}),
|
||||
responseFactory
|
||||
);
|
||||
|
||||
expect(kibanaResponse.status).toBe(200);
|
||||
expect(validatedBody).toBe(true);
|
||||
expect(validatedParams).toBe(true);
|
||||
expect(validatedQuery).toBe(true);
|
||||
expect(validatedOutputBody).toBe(true);
|
||||
});
|
||||
it('passes through the expected values to the IRouter registrar', () => {
|
||||
const versionedRouter = CoreVersionedRouter.from({ router });
|
||||
const opts: Parameters<typeof versionedRouter.post>[0] = {
|
||||
|
@ -238,4 +168,94 @@ describe('Versioned route', () => {
|
|||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it('allows public versions other than "2023-10-31"', () => {
|
||||
expect(() =>
|
||||
CoreVersionedRouter.from({ router, isDev: false })
|
||||
.get({ access: 'public', path: '/foo' })
|
||||
.addVersion({ version: '2023-01-31', validate: false }, (ctx, req, res) => res.ok())
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
describe('when in dev', () => {
|
||||
// NOTE: Temporary test to ensure single public API version is enforced
|
||||
it('only allows "2023-10-31" as public route versions', () => {
|
||||
expect(() =>
|
||||
CoreVersionedRouter.from({ router, isDev: true })
|
||||
.get({ access: 'public', path: '/foo' })
|
||||
.addVersion({ version: '2023-01-31', validate: false }, (ctx, req, res) => res.ok())
|
||||
).toThrow(/Invalid public version/);
|
||||
});
|
||||
|
||||
it('runs request AND response validations', async () => {
|
||||
let handler: RequestHandler;
|
||||
|
||||
let validatedBody = false;
|
||||
let validatedParams = false;
|
||||
let validatedQuery = false;
|
||||
let validatedOutputBody = false;
|
||||
|
||||
(router.post as jest.Mock).mockImplementation((opts: unknown, fn) => (handler = fn));
|
||||
const versionedRouter = CoreVersionedRouter.from({ router, isDev: true });
|
||||
versionedRouter.post({ path: '/test/{id}', access: 'internal' }).addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedBody = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
params: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedParams = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
query: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedQuery = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
body: schema.object({
|
||||
foo: schema.number({
|
||||
validate: () => {
|
||||
validatedOutputBody = true;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
handlerFn
|
||||
);
|
||||
|
||||
const kibanaResponse = await handler!(
|
||||
{} as any,
|
||||
createRequest({
|
||||
version: '1',
|
||||
body: { foo: 1 },
|
||||
params: { foo: 1 },
|
||||
query: { foo: 1 },
|
||||
}),
|
||||
responseFactory
|
||||
);
|
||||
|
||||
expect(kibanaResponse.status).toBe(200);
|
||||
expect(validatedBody).toBe(true);
|
||||
expect(validatedParams).toBe(true);
|
||||
expect(validatedQuery).toBe(true);
|
||||
expect(validatedOutputBody).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ import type { Method } from './types';
|
|||
import type { CoreVersionedRouter } from './core_versioned_router';
|
||||
|
||||
import { validate } from './validate';
|
||||
import { isValidRouteVersion } from './is_valid_route_version';
|
||||
import { isAllowedPublicVersion, isValidRouteVersion } from './is_valid_route_version';
|
||||
import { injectResponseHeaders } from './inject_response_headers';
|
||||
|
||||
import { resolvers } from './handler_resolvers';
|
||||
|
@ -195,6 +195,15 @@ export class CoreVersionedRoute implements VersionedRoute {
|
|||
}
|
||||
|
||||
private validateVersion(version: string) {
|
||||
// We do an additional check here while we only have a single allowed public version
|
||||
// for all public Kibana HTTP APIs
|
||||
if (this.router.isDev && this.isPublic) {
|
||||
const message = isAllowedPublicVersion(version);
|
||||
if (message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
const message = isValidRouteVersion(this.isPublic, version);
|
||||
if (message) {
|
||||
throw new Error(message);
|
||||
|
|
|
@ -6,7 +6,18 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { isValidRouteVersion } from './is_valid_route_version';
|
||||
import { isValidRouteVersion, isAllowedPublicVersion } from './is_valid_route_version';
|
||||
|
||||
describe('isAllowedPublicVersion', () => {
|
||||
test('allows 2023-10-31', () => {
|
||||
expect(isAllowedPublicVersion('2023-10-31')).toBe(undefined);
|
||||
});
|
||||
test('disallows non-"2023-10-31" strings', () => {
|
||||
expect(isAllowedPublicVersion('2020-01-01')).toMatch(/Invalid public version/);
|
||||
expect(isAllowedPublicVersion('foo')).toMatch(/Invalid public version/);
|
||||
expect(isAllowedPublicVersion('')).toMatch(/Invalid public version/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValidRouteVersion', () => {
|
||||
describe('public', () => {
|
||||
|
@ -37,6 +48,7 @@ describe('isValidRouteVersion', () => {
|
|||
['11 '],
|
||||
[' 11 '],
|
||||
['-1'],
|
||||
['010'],
|
||||
])('%p returns an error message', (value: string) => {
|
||||
expect(isValidRouteVersion(false, value)).toMatch(/Invalid version number/);
|
||||
});
|
||||
|
|
|
@ -5,11 +5,23 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
|
||||
const PUBLIC_VERSION_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
||||
const INTERNAL_VERSION_REGEX = /^[0-9]+$/;
|
||||
const INTERNAL_VERSION_REGEX = /^[1-9][0-9]*$/;
|
||||
|
||||
/**
|
||||
* To bring all of Kibana's first public API versions in-sync with an initial
|
||||
* release date we only allow one public version temporarily.
|
||||
* @internal
|
||||
*/
|
||||
const ALLOWED_PUBLIC_VERSION = '2023-10-31';
|
||||
|
||||
export function isAllowedPublicVersion(version: string): undefined | string {
|
||||
if (ALLOWED_PUBLIC_VERSION !== version) {
|
||||
return `Invalid public version, for now please use "${ALLOWED_PUBLIC_VERSION}" as the version for all public routes. Received "${version}".}"`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For public routes we must check that the version is a string that is YYYY-MM-DD.
|
||||
|
|
|
@ -81,7 +81,7 @@ createServerRouteFactory<{}, { options: { tags: string[] } }>()({
|
|||
});
|
||||
|
||||
createServerRouteFactory<{}, { options: { tags: string[] } }>()({
|
||||
endpoint: 'GET /api/endpoint_with_params 2023-05-22',
|
||||
endpoint: 'GET /api/endpoint_with_params 2023-10-31',
|
||||
options: {
|
||||
tags: [],
|
||||
},
|
||||
|
|
|
@ -172,8 +172,8 @@ describe('Routing versioned requests', () => {
|
|||
it('returns the version in response headers', async () => {
|
||||
router.versioned
|
||||
.get({ path: '/my-path', access: 'public' })
|
||||
.addVersion({ validate: false, version: '2020-02-02' }, async (ctx, req, res) => {
|
||||
return res.ok({ body: { v: '2020-02-02' } });
|
||||
.addVersion({ validate: false, version: '2023-10-31' }, async (ctx, req, res) => {
|
||||
return res.ok({ body: { foo: 'bar' } });
|
||||
});
|
||||
|
||||
await server.start();
|
||||
|
@ -181,10 +181,10 @@ describe('Routing versioned requests', () => {
|
|||
await expect(
|
||||
supertest
|
||||
.get('/my-path')
|
||||
.set('Elastic-Api-Version', '2020-02-02')
|
||||
.set('Elastic-Api-Version', '2023-10-31')
|
||||
.expect(200)
|
||||
.then(({ header }) => header)
|
||||
).resolves.toEqual(expect.objectContaining({ 'elastic-api-version': '2020-02-02' }));
|
||||
).resolves.toEqual(expect.objectContaining({ 'elastic-api-version': '2023-10-31' }));
|
||||
});
|
||||
|
||||
it('runs response validation when in dev', async () => {
|
||||
|
@ -259,19 +259,15 @@ describe('Routing versioned requests', () => {
|
|||
).resolves.toMatch(/Please specify.+version/);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['public', '2022-02-02', '2022-02-03'],
|
||||
['internal', '1', '2'],
|
||||
])('requires version headers to be set %p when in dev', async (access, v1, v2) => {
|
||||
it('requires version headers to be set for public endpoints when in dev', async () => {
|
||||
await setupServer({ dev: true });
|
||||
router.versioned
|
||||
.get({ path: '/my-path', access: access as 'internal' | 'public' })
|
||||
.get({
|
||||
path: '/my-path',
|
||||
access: 'public',
|
||||
})
|
||||
.addVersion(
|
||||
{ version: v1, validate: { response: { 200: { body: schema.number() } } } },
|
||||
async (ctx, req, res) => res.ok()
|
||||
)
|
||||
.addVersion(
|
||||
{ version: v2, validate: { response: { 200: { body: schema.number() } } } },
|
||||
{ version: '2023-10-31', validate: { response: { 200: { body: schema.number() } } } },
|
||||
async (ctx, req, res) => res.ok()
|
||||
);
|
||||
await server.start();
|
||||
|
|
|
@ -40,7 +40,7 @@ export function Onboarding() {
|
|||
const privileges: PrivilegeType[] = [PrivilegeType.EVENT];
|
||||
|
||||
const { agentKey } = await callApmApi(
|
||||
'POST /api/apm/agent_keys 2023-05-22',
|
||||
'POST /api/apm/agent_keys 2023-10-31',
|
||||
{
|
||||
signal: null,
|
||||
params: {
|
||||
|
|
|
@ -23,7 +23,7 @@ const stories: Meta<{}> = {
|
|||
const transactionTypeStatus = FETCH_STATUS.SUCCESS;
|
||||
|
||||
mockApmApiCallResponse(
|
||||
`GET /api/apm/services/{serviceName}/annotation/search 2023-05-22`,
|
||||
`GET /api/apm/services/{serviceName}/annotation/search 2023-10-31`,
|
||||
() => ({ annotations: [] })
|
||||
);
|
||||
mockApmApiCallResponse(
|
||||
|
|
|
@ -41,7 +41,7 @@ export function ServicePage({ newConfig, setNewConfig, onClickNext }: Props) {
|
|||
(callApmApi) => {
|
||||
if (newConfig.service.name) {
|
||||
return callApmApi(
|
||||
'GET /api/apm/settings/agent-configuration/environments 2023-05-22',
|
||||
'GET /api/apm/settings/agent-configuration/environments 2023-10-31',
|
||||
{
|
||||
params: {
|
||||
query: { serviceName: omitAllOption(newConfig.service.name) },
|
||||
|
@ -65,7 +65,7 @@ export function ServicePage({ newConfig, setNewConfig, onClickNext }: Props) {
|
|||
}
|
||||
|
||||
const { agentName } = await callApmApi(
|
||||
'GET /api/apm/settings/agent-configuration/agent_name 2023-05-22',
|
||||
'GET /api/apm/settings/agent-configuration/agent_name 2023-10-31',
|
||||
{
|
||||
params: { query: { serviceName } },
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export async function saveConfig({
|
|||
toasts: NotificationsStart['toasts'];
|
||||
}) {
|
||||
try {
|
||||
await callApmApi('PUT /api/apm/settings/agent-configuration 2023-05-22', {
|
||||
await callApmApi('PUT /api/apm/settings/agent-configuration 2023-10-31', {
|
||||
signal: null,
|
||||
params: {
|
||||
query: { overwrite: isEditMode },
|
||||
|
|
|
@ -31,7 +31,7 @@ export function AgentConfigurations() {
|
|||
status,
|
||||
} = useFetcher(
|
||||
(callApmApi) =>
|
||||
callApmApi('GET /api/apm/settings/agent-configuration 2023-05-22'),
|
||||
callApmApi('GET /api/apm/settings/agent-configuration 2023-10-31'),
|
||||
[],
|
||||
{ preservePreviousData: false, showToastOnError: false }
|
||||
);
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
|
||||
|
||||
type Config =
|
||||
APIReturnType<'GET /api/apm/settings/agent-configuration 2023-05-22'>['configurations'][0];
|
||||
APIReturnType<'GET /api/apm/settings/agent-configuration 2023-10-31'>['configurations'][0];
|
||||
|
||||
interface Props {
|
||||
config: Config;
|
||||
|
@ -72,7 +72,7 @@ async function deleteConfig(
|
|||
) {
|
||||
try {
|
||||
await callApmApi(
|
||||
'DELETE /api/apm/settings/agent-configuration 2023-05-22',
|
||||
'DELETE /api/apm/settings/agent-configuration 2023-10-31',
|
||||
{
|
||||
signal: null,
|
||||
params: {
|
||||
|
|
|
@ -29,7 +29,7 @@ import { TimestampTooltip } from '../../../../shared/timestamp_tooltip';
|
|||
import { ConfirmDeleteModal } from './confirm_delete_modal';
|
||||
|
||||
type Config =
|
||||
APIReturnType<'GET /api/apm/settings/agent-configuration 2023-05-22'>['configurations'][0];
|
||||
APIReturnType<'GET /api/apm/settings/agent-configuration 2023-10-31'>['configurations'][0];
|
||||
|
||||
interface Props {
|
||||
status: FETCH_STATUS;
|
||||
|
|
|
@ -81,7 +81,7 @@ export function CreateAgentKeyFlyout({ onCancel, onSuccess, onError }: Props) {
|
|||
}
|
||||
|
||||
const { agentKey } = await callApmApi(
|
||||
'POST /api/apm/agent_keys 2023-05-22',
|
||||
'POST /api/apm/agent_keys 2023-10-31',
|
||||
{
|
||||
signal: null,
|
||||
params: {
|
||||
|
|
|
@ -22,7 +22,7 @@ export function EditAgentConfigurationRouteView() {
|
|||
const res = useFetcher(
|
||||
(callApmApi) => {
|
||||
return callApmApi(
|
||||
'GET /api/apm/settings/agent-configuration/view 2023-05-22',
|
||||
'GET /api/apm/settings/agent-configuration/view 2023-10-31',
|
||||
{
|
||||
params: { query: { name, environment } },
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export function AnnotationsContextProvider({
|
|||
(callApmApi) => {
|
||||
if (start && end && serviceName) {
|
||||
return callApmApi(
|
||||
'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22',
|
||||
'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31',
|
||||
{
|
||||
params: {
|
||||
path: {
|
||||
|
|
|
@ -96,7 +96,7 @@ const invalidateAgentKeyRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const createAgentKeyRoute = createApmServerRoute({
|
||||
endpoint: 'POST /api/apm/agent_keys 2023-05-22',
|
||||
endpoint: 'POST /api/apm/agent_keys 2023-10-31',
|
||||
options: { tags: ['access:apm', 'access:apm_write'] },
|
||||
params: t.type({
|
||||
body: t.type({
|
||||
|
|
|
@ -69,7 +69,7 @@ const fleetAgentsRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const saveApmServerSchemaRoute = createApmServerRoute({
|
||||
endpoint: 'POST /api/apm/fleet/apm_server_schema 2023-05-22',
|
||||
endpoint: 'POST /api/apm/fleet/apm_server_schema 2023-10-31',
|
||||
options: { tags: ['access:apm', 'access:apm_write'] },
|
||||
params: t.type({
|
||||
body: t.type({
|
||||
|
|
|
@ -382,7 +382,7 @@ const serviceNodeMetadataRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const serviceAnnotationsRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22',
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31',
|
||||
params: t.type({
|
||||
path: t.type({
|
||||
serviceName: t.string,
|
||||
|
@ -433,7 +433,7 @@ const serviceAnnotationsRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const serviceAnnotationsCreateRoute = createApmServerRoute({
|
||||
endpoint: 'POST /api/apm/services/{serviceName}/annotation 2023-05-22',
|
||||
endpoint: 'POST /api/apm/services/{serviceName}/annotation 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:apm', 'access:apm_write'],
|
||||
},
|
||||
|
|
|
@ -40,7 +40,7 @@ function throwNotFoundIfAgentConfigNotAvailable(
|
|||
|
||||
// get list of configurations
|
||||
const agentConfigurationRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-10-31',
|
||||
options: { tags: ['access:apm'] },
|
||||
handler: async (
|
||||
resources
|
||||
|
@ -66,7 +66,7 @@ const agentConfigurationRoute = createApmServerRoute({
|
|||
|
||||
// get a single configuration
|
||||
const getSingleAgentConfigurationRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-10-31',
|
||||
params: t.partial({
|
||||
query: serviceRt,
|
||||
}),
|
||||
|
@ -103,7 +103,7 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({
|
|||
|
||||
// delete configuration
|
||||
const deleteAgentConfigurationRoute = createApmServerRoute({
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:apm', 'access:apm_write'],
|
||||
},
|
||||
|
@ -171,7 +171,7 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
|
|||
|
||||
// create/update configuration
|
||||
const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:apm', 'access:apm_write'],
|
||||
},
|
||||
|
@ -248,7 +248,7 @@ export type AgentConfigSearchParams = t.TypeOf<typeof searchParamsRt>;
|
|||
|
||||
// Lookup single configuration (used by APM Server)
|
||||
const agentConfigurationSearchRoute = createApmServerRoute({
|
||||
endpoint: 'POST /api/apm/settings/agent-configuration/search 2023-05-22',
|
||||
endpoint: 'POST /api/apm/settings/agent-configuration/search 2023-10-31',
|
||||
params: t.type({
|
||||
body: searchParamsRt,
|
||||
}),
|
||||
|
@ -319,7 +319,7 @@ const agentConfigurationSearchRoute = createApmServerRoute({
|
|||
|
||||
// get environments for service
|
||||
const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/environments 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/environments 2023-10-31',
|
||||
params: t.partial({
|
||||
query: t.partial({ serviceName: t.string }),
|
||||
}),
|
||||
|
@ -368,7 +368,7 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
|
|||
|
||||
// get agentName for service
|
||||
const agentConfigurationAgentNameRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/agent_name 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/agent_name 2023-10-31',
|
||||
params: t.type({
|
||||
query: t.type({ serviceName: t.string }),
|
||||
}),
|
||||
|
|
|
@ -50,7 +50,7 @@ function throwNotImplementedIfSourceMapNotAvailable(
|
|||
}
|
||||
|
||||
const listSourceMapRoute = createApmServerRoute({
|
||||
endpoint: 'GET /api/apm/sourcemaps 2023-05-22',
|
||||
endpoint: 'GET /api/apm/sourcemaps 2023-10-31',
|
||||
options: { tags: ['access:apm'] },
|
||||
params: t.partial({
|
||||
query: t.partial({
|
||||
|
@ -88,7 +88,7 @@ const listSourceMapRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const uploadSourceMapRoute = createApmServerRoute({
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-05-22',
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:apm', 'access:apm_write'],
|
||||
body: { accepts: ['multipart/form-data'] },
|
||||
|
@ -170,7 +170,7 @@ const uploadSourceMapRoute = createApmServerRoute({
|
|||
});
|
||||
|
||||
const deleteSourceMapRoute = createApmServerRoute({
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31',
|
||||
options: { tags: ['access:apm', 'access:apm_write'] },
|
||||
params: t.type({
|
||||
path: t.type({
|
||||
|
|
|
@ -61,7 +61,7 @@ export const savedObjectsApiProvider = (httpService: HttpService) => ({
|
|||
path: `${ML_EXTERNAL_BASE_PATH}/saved_objects/sync`,
|
||||
method: 'GET',
|
||||
query: { simulate },
|
||||
version: '2023-05-15',
|
||||
version: '2023-10-31',
|
||||
});
|
||||
},
|
||||
initSavedObjects(simulate: boolean = false) {
|
||||
|
|
|
@ -88,7 +88,7 @@ export function savedObjectsRoutes(
|
|||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-05-15',
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: {
|
||||
query: syncJobObjects,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Dataset } from '@kbn/rule-registry-plugin/server';
|
|||
import { createObservabilityServerRoute } from '../create_observability_server_route';
|
||||
|
||||
const alertsDynamicIndexPatternRoute = createObservabilityServerRoute({
|
||||
endpoint: 'GET /api/observability/rules/alerts/dynamic_index_pattern 2023-05-22',
|
||||
endpoint: 'GET /api/observability/rules/alerts/dynamic_index_pattern 2023-10-31',
|
||||
options: {
|
||||
tags: [],
|
||||
},
|
||||
|
|
|
@ -55,7 +55,7 @@ const isLicenseAtLeastPlatinum = async (context: ObservabilityRequestHandlerCont
|
|||
};
|
||||
|
||||
const createSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'POST /api/observability/slos 2023-05-22',
|
||||
endpoint: 'POST /api/observability/slos 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_write'],
|
||||
},
|
||||
|
@ -82,7 +82,7 @@ const createSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const updateSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'PUT /api/observability/slos/{id} 2023-05-22',
|
||||
endpoint: 'PUT /api/observability/slos/{id} 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_write'],
|
||||
},
|
||||
|
@ -108,7 +108,7 @@ const updateSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const deleteSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'DELETE /api/observability/slos/{id} 2023-05-22',
|
||||
endpoint: 'DELETE /api/observability/slos/{id} 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_write'],
|
||||
},
|
||||
|
@ -140,7 +140,7 @@ const deleteSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const getSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'GET /api/observability/slos/{id} 2023-05-22',
|
||||
endpoint: 'GET /api/observability/slos/{id} 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_read'],
|
||||
},
|
||||
|
@ -165,7 +165,7 @@ const getSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const enableSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'POST /api/observability/slos/{id}/enable 2023-05-22',
|
||||
endpoint: 'POST /api/observability/slos/{id}/enable 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_write'],
|
||||
},
|
||||
|
@ -191,7 +191,7 @@ const enableSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const disableSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'POST /api/observability/slos/{id}/disable 2023-05-22',
|
||||
endpoint: 'POST /api/observability/slos/{id}/disable 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_write'],
|
||||
},
|
||||
|
@ -217,7 +217,7 @@ const disableSLORoute = createObservabilityServerRoute({
|
|||
});
|
||||
|
||||
const findSLORoute = createObservabilityServerRoute({
|
||||
endpoint: 'GET /api/observability/slos 2023-05-22',
|
||||
endpoint: 'GET /api/observability/slos 2023-10-31',
|
||||
options: {
|
||||
tags: ['access:slo_read'],
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body, status } = await supertest
|
||||
.get(`/s/${idSpace1}/api/ml/saved_objects/sync`)
|
||||
.auth(user, ml.securityCommon.getPasswordForUser(user))
|
||||
.set(getCommonRequestHeader('2023-05-15'));
|
||||
.set(getCommonRequestHeader('2023-10-31'));
|
||||
ml.api.assertResponseStatusCode(expectedStatusCode, status, body);
|
||||
|
||||
return body;
|
||||
|
|
|
@ -30,7 +30,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body, status } = await supertest
|
||||
.get(`/s/${idSpace1}/api/ml/saved_objects/sync`)
|
||||
.auth(user, ml.securityCommon.getPasswordForUser(user))
|
||||
.set(getCommonRequestHeader('2023-05-15'));
|
||||
.set(getCommonRequestHeader('2023-10-31'));
|
||||
ml.api.assertResponseStatusCode(expectedStatusCode, status, body);
|
||||
|
||||
return body;
|
||||
|
|
|
@ -43,10 +43,10 @@ export default function featureControlsTests({ getService }: FtrProviderContext)
|
|||
}
|
||||
|
||||
function createAgent(
|
||||
body: APIClientRequestParamsOf<'PUT /api/apm/settings/agent-configuration 2023-05-22'>['params']['body']
|
||||
body: APIClientRequestParamsOf<'PUT /api/apm/settings/agent-configuration 2023-10-31'>['params']['body']
|
||||
) {
|
||||
return apmApiClient.writeUser({
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: {
|
||||
body,
|
||||
},
|
||||
|
@ -54,10 +54,10 @@ export default function featureControlsTests({ getService }: FtrProviderContext)
|
|||
}
|
||||
|
||||
function deleteAgent(
|
||||
body: APIClientRequestParamsOf<'DELETE /api/apm/settings/agent-configuration 2023-05-22'>['params']['body']
|
||||
body: APIClientRequestParamsOf<'DELETE /api/apm/settings/agent-configuration 2023-10-31'>['params']['body']
|
||||
) {
|
||||
return apmApiClient.writeUser({
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: {
|
||||
body,
|
||||
},
|
||||
|
|
|
@ -53,14 +53,14 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) {
|
|||
|
||||
async function createConfiguration(configuration: any) {
|
||||
return apmApiClient.writeUser({
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: { body: configuration },
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteConfiguration(configuration: any) {
|
||||
return apmApiClient.writeUser({
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: { body: { service: configuration.service } },
|
||||
});
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) {
|
|||
sourcemap: SourceMap;
|
||||
}) {
|
||||
const response = await apmApiClient.writeUser({
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-05-22',
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-10-31',
|
||||
type: 'form-data',
|
||||
params: {
|
||||
body: {
|
||||
|
@ -202,11 +202,11 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) {
|
|||
});
|
||||
|
||||
describe('Source maps', () => {
|
||||
let resp: APIReturnType<'POST /api/apm/sourcemaps 2023-05-22'>;
|
||||
let resp: APIReturnType<'POST /api/apm/sourcemaps 2023-10-31'>;
|
||||
|
||||
after(async () => {
|
||||
await apmApiClient.writeUser({
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31',
|
||||
params: { path: { id: resp.id } },
|
||||
});
|
||||
});
|
||||
|
|
|
@ -83,7 +83,7 @@ export default function customLinksTests({ getService }: FtrProviderContext) {
|
|||
|
||||
it('for agent configs', async () => {
|
||||
const { status, body } = await apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: {
|
||||
query: {
|
||||
_inspect: true,
|
||||
|
|
|
@ -29,7 +29,7 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
|
|||
const es = getService('es');
|
||||
|
||||
function expectContainsObj(
|
||||
source: APIReturnType<'POST /api/apm/services/{serviceName}/annotation 2023-05-22'>,
|
||||
source: APIReturnType<'POST /api/apm/services/{serviceName}/annotation 2023-10-31'>,
|
||||
expected: JsonObject
|
||||
) {
|
||||
expect(source).to.eql(
|
||||
|
@ -43,10 +43,10 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
|
|||
}
|
||||
|
||||
function createAnnotation(
|
||||
body: APIClientRequestParamsOf<'POST /api/apm/services/{serviceName}/annotation 2023-05-22'>['params']['body']
|
||||
body: APIClientRequestParamsOf<'POST /api/apm/services/{serviceName}/annotation 2023-10-31'>['params']['body']
|
||||
) {
|
||||
return apmApiClient.annotationWriterUser({
|
||||
endpoint: 'POST /api/apm/services/{serviceName}/annotation 2023-05-22',
|
||||
endpoint: 'POST /api/apm/services/{serviceName}/annotation 2023-10-31',
|
||||
params: {
|
||||
path: {
|
||||
serviceName: 'opbeans-java',
|
||||
|
@ -58,11 +58,11 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
|
|||
|
||||
function getAnnotation(
|
||||
query: RecursivePartial<
|
||||
APIClientRequestParamsOf<'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22'>['params']['query']
|
||||
APIClientRequestParamsOf<'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31'>['params']['query']
|
||||
>
|
||||
) {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22',
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31',
|
||||
params: {
|
||||
path: {
|
||||
serviceName: 'opbeans-java',
|
||||
|
|
|
@ -29,7 +29,7 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
|
|||
{ config: 'basic', archives: [] },
|
||||
() => {
|
||||
describe('when there are multiple service versions', () => {
|
||||
let response: APIReturnType<'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22'>;
|
||||
let response: APIReturnType<'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31'>;
|
||||
|
||||
before(async () => {
|
||||
const indexExists = await es.indices.exists({ index: indexName });
|
||||
|
@ -119,7 +119,7 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
|
|||
|
||||
response = (
|
||||
await apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-05-22',
|
||||
endpoint: 'GET /api/apm/services/{serviceName}/annotation/search 2023-10-31',
|
||||
params: {
|
||||
path: {
|
||||
serviceName: 'opbeans-java',
|
||||
|
|
|
@ -27,28 +27,28 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
|
|||
|
||||
async function getEnvironments(serviceName: string) {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/environments 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/environments 2023-10-31',
|
||||
params: { query: { serviceName } },
|
||||
});
|
||||
}
|
||||
|
||||
function getAgentName(serviceName: string) {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/agent_name 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/agent_name 2023-10-31',
|
||||
params: { query: { serviceName } },
|
||||
});
|
||||
}
|
||||
|
||||
function searchConfigurations(configuration: AgentConfigSearchParams) {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'POST /api/apm/settings/agent-configuration/search 2023-05-22',
|
||||
endpoint: 'POST /api/apm/settings/agent-configuration/search 2023-10-31',
|
||||
params: { body: configuration },
|
||||
});
|
||||
}
|
||||
|
||||
function getAllConfigurations() {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration 2023-10-31',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
|
|||
const supertestClient = user === 'read' ? apmApiClient.readUser : apmApiClient.writeUser;
|
||||
|
||||
return supertestClient({
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: { body: configuration },
|
||||
});
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
|
|||
const supertestClient = user === 'read' ? apmApiClient.readUser : apmApiClient.writeUser;
|
||||
|
||||
return supertestClient({
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: { query: { overwrite: true }, body: config },
|
||||
});
|
||||
}
|
||||
|
@ -77,14 +77,14 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
|
|||
const supertestClient = user === 'read' ? apmApiClient.readUser : apmApiClient.writeUser;
|
||||
|
||||
return supertestClient({
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31',
|
||||
params: { body: { service } },
|
||||
});
|
||||
}
|
||||
|
||||
function findExactConfiguration(name: string, environment: string) {
|
||||
return apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-05-22',
|
||||
endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-10-31',
|
||||
params: {
|
||||
query: {
|
||||
name,
|
||||
|
@ -397,7 +397,7 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
|
|||
};
|
||||
|
||||
let agentConfiguration:
|
||||
| APIReturnType<'GET /api/apm/settings/agent-configuration/view 2023-05-22'>
|
||||
| APIReturnType<'GET /api/apm/settings/agent-configuration/view 2023-10-31'>
|
||||
| undefined;
|
||||
|
||||
before(async () => {
|
||||
|
|
|
@ -22,7 +22,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
|
||||
async function createAgentKey(apiClient: ApmApiSupertest, privileges = allApplicationPrivileges) {
|
||||
return await apiClient({
|
||||
endpoint: 'POST /api/apm/agent_keys 2023-05-22',
|
||||
endpoint: 'POST /api/apm/agent_keys 2023-10-31',
|
||||
params: {
|
||||
body: {
|
||||
name: agentKeyName,
|
||||
|
|
|
@ -85,7 +85,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
sourcemap: SourceMap;
|
||||
}) {
|
||||
const response = await apmApiClient.writeUser({
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-05-22',
|
||||
endpoint: 'POST /api/apm/sourcemaps 2023-10-31',
|
||||
type: 'form-data',
|
||||
params: {
|
||||
body: {
|
||||
|
@ -107,7 +107,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
|
||||
async function deleteSourcemap(id: string) {
|
||||
await apmApiClient.writeUser({
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31',
|
||||
params: { path: { id } },
|
||||
});
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
const query = page && perPage ? { page, perPage } : {};
|
||||
|
||||
const response = await apmApiClient.readUser({
|
||||
endpoint: 'GET /api/apm/sourcemaps 2023-05-22',
|
||||
endpoint: 'GET /api/apm/sourcemaps 2023-10-31',
|
||||
params: { query },
|
||||
});
|
||||
return response.body;
|
||||
|
@ -136,11 +136,11 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
}
|
||||
}
|
||||
|
||||
let resp: APIReturnType<'POST /api/apm/sourcemaps 2023-05-22'>;
|
||||
let resp: APIReturnType<'POST /api/apm/sourcemaps 2023-10-31'>;
|
||||
describe('upload source map', () => {
|
||||
after(async () => {
|
||||
await apmApiClient.writeUser({
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-05-22',
|
||||
endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31',
|
||||
params: { path: { id: resp.id } },
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1248,7 +1248,7 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
|
|||
async syncSavedObjects(simulate: boolean = false, space?: string) {
|
||||
const { body, status } = await kbnSupertest
|
||||
.get(`${space ? `/s/${space}` : ''}/api/ml/saved_objects/sync?simulate=${simulate}`)
|
||||
.set(getCommonRequestHeader('2023-05-15'));
|
||||
.set(getCommonRequestHeader('2023-10-31'));
|
||||
this.assertResponseStatusCode(200, status, body);
|
||||
|
||||
return body;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue