Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/ftr_platform_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ enabled:
- x-pack/platform/test/api_integration/apis/management/config.ts
- x-pack/platform/test/api_integration/apis/management/index_management/disabled_data_enrichers/config.ts
- x-pack/platform/test/api_integration/apis/maps/config.ts
- x-pack/platform/test/api_integration/apis/lens/config.ts
- x-pack/platform/test/api_integration/apis/ml/config.ts
- x-pack/platform/test/api_integration/apis/monitoring/config.ts
- x-pack/platform/test/api_integration/apis/monitoring_collection/config.ts
Expand Down
4 changes: 2 additions & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,8 @@ src/platform/plugins/shared/discover/public/context_awareness/profile_providers/
/x-pack/test/functional/page_objects/lens_page.ts @elastic/kibana-visualizations
/x-pack/test/functional/es_archives/lens @elastic/kibana-visualizations
/x-pack/test/examples/embedded_lens @elastic/kibana-visualizations
/x-pack/test/api_integration/fixtures/kbn_archiver/lens/constant_keyword.json @elastic/kibana-visualizations
/x-pack/test/api_integration/fixtures/kbn_archiver/lens/ @elastic/kibana-visualizations
/x-pack/platform/test/api_integration/apis/lens @elastic/kibana-visualizations
/src/platform/test/plugin_functional/test_suites/custom_visualizations @elastic/kibana-visualizations
/src/platform/test/plugin_functional/plugins/kbn_tp_custom_visualizations @elastic/kibana-visualizations
/x-pack/test/functional/fixtures/kbn_archiver/visualize @elastic/kibana-visualizations
Expand Down Expand Up @@ -2742,7 +2743,6 @@ x-pack/solutions/security/plugins/security_solution/public/security_integrations
x-pack/solutions/security/plugins/security_solution/server/security_integrations @elastic/security-service-integrations
x-pack/solutions/security/plugins/security_solution/server/lib/security_integrations @elastic/security-service-integrations


# Kibana design
# scss overrides should be below this line for specificity
**/*.scss @elastic/kibana-design
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,21 @@ export type LensSavedObject = LensCrudTypes['Item'];
export type PartialLensSavedObject = LensCrudTypes['PartialItem'];

// ----------- GET --------------

export type LensGetIn = LensCrudTypes['GetIn'];

export type LensGetOut = LensCrudTypes['GetOut'];

// ----------- CREATE --------------

export type LensCreateIn = LensCrudTypes['CreateIn'];

export type LensCreateOut = LensCrudTypes['CreateOut'];
// ----------- UPDATE --------------

// ----------- UPDATE --------------
export type LensUpdateIn = LensCrudTypes['UpdateIn'];
export type LensUpdateOut = LensCrudTypes['UpdateOut'];
// ----------- DELETE --------------

// ----------- DELETE --------------
export type LensDeleteIn = LensCrudTypes['DeleteIn'];
export type LensDeleteOut = LensCrudTypes['DeleteOut'];
// ----------- SEARCH --------------

// ----------- SEARCH --------------
export type LensSearchIn = LensCrudTypes['SearchIn'];
export type LensSearchOut = LensCrudTypes['SearchOut'];
11 changes: 11 additions & 0 deletions x-pack/platform/plugins/shared/lens/server/api/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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.
*/

export const PUBLIC_API_VERSION = '1';
export const PUBLIC_API_CONTENT_MANAGEMENT_VERSION = 1;
export const PUBLIC_API_PATH = '/api/lens';
export const PUBLIC_API_ACCESS = 'internal';
13 changes: 13 additions & 0 deletions x-pack/platform/plugins/shared/lens/server/api/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { RegisterAPIRoutesArgs } from '../types';
import { registerLensVisualizationsAPIRoutes } from './visualizations';

export function registerLensAPIRoutes(args: RegisterAPIRoutesArgs) {
registerLensVisualizationsAPIRoutes(args);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 { schema } from '@kbn/config-schema';

import { boomify, isBoom } from '@hapi/boom';
import { CONTENT_ID, type LensSavedObject } from '../../../../common/content_management';
import {
PUBLIC_API_PATH,
PUBLIC_API_VERSION,
PUBLIC_API_CONTENT_MANAGEMENT_VERSION,
PUBLIC_API_ACCESS,
} from '../../constants';
import {
lensAttributesSchema,
lensCreateOptionsSchema,
lensSavedObjectSchema,
} from '../../../content_management/v1';
import { RegisterAPIRouteFn } from '../../types';

export const registerLensVisualizationsCreateAPIRoute: RegisterAPIRouteFn = (
router,
{ contentManagement }
) => {
const createRoute = router.post({
path: `${PUBLIC_API_PATH}/visualizations`,
access: PUBLIC_API_ACCESS,
enableQueryVersion: true,
summary: 'Create Lens visualization',
description: 'Create a new Lens visualization.',
options: {
tags: ['oas-tag:Lens'],
availability: {
stability: 'experimental',
},
},
security: {
authz: {
enabled: false,
reason: 'Relies on Content Client for authorization',
},
},
});

createRoute.addVersion(
{
version: PUBLIC_API_VERSION,
validate: {
request: {
body: schema.object({
options: lensCreateOptionsSchema,
data: lensAttributesSchema,
}),
},
response: {
201: {
body: () => lensSavedObjectSchema,
description: 'Created',
},
400: {
description: 'Malformed request',
},
401: {
description: 'Unauthorized',
},
403: {
description: 'Forbidden',
},
500: {
description: 'Internal Server Error',
},
},
},
},
async (ctx, req, res) => {
let result;
const { data, options } = req.body;
const client = contentManagement.contentClient
.getForRequest({ request: req, requestHandlerContext: ctx })
.for<LensSavedObject>(CONTENT_ID, PUBLIC_API_CONTENT_MANAGEMENT_VERSION);

try {
({ result } = await client.create(data, options));
} catch (error) {
if (isBoom(error) && error.output.statusCode === 403) {
return res.forbidden();
}

return boomify(error); // forward unknown error
}

return res.created({ body: result.item });
}
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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 { schema } from '@kbn/config-schema';

import { boomify, isBoom } from '@hapi/boom';
import { CONTENT_ID, type LensSavedObject } from '../../../../common/content_management';
import {
PUBLIC_API_PATH,
PUBLIC_API_VERSION,
PUBLIC_API_CONTENT_MANAGEMENT_VERSION,
PUBLIC_API_ACCESS,
} from '../../constants';
import { RegisterAPIRouteFn } from '../../types';

export const registerLensVisualizationsDeleteAPIRoute: RegisterAPIRouteFn = (
router,
{ contentManagement }
) => {
const deleteRoute = router.delete({
path: `${PUBLIC_API_PATH}/visualizations/{id}`,
access: PUBLIC_API_ACCESS,
enableQueryVersion: true,
summary: 'Delete Lens visualization',
description: 'Delete a Lens visualization by id.',
options: {
tags: ['oas-tag:Lens'],
availability: {
stability: 'experimental',
},
},
security: {
authz: {
enabled: false,
reason: 'Relies on Content Client for authorization',
},
},
});

deleteRoute.addVersion(
{
version: PUBLIC_API_VERSION,
validate: {
request: {
params: schema.object({
id: schema.string({
meta: {
description: 'The saved object id of a Lens visualization.',
},
}),
}),
},
response: {
204: {
description: 'No Content',
},
400: {
description: 'Malformed request',
},
401: {
description: 'Unauthorized',
},
403: {
description: 'Forbidden',
},
404: {
description: 'Resource not found',
},
500: {
description: 'Internal Server Error',
},
},
},
},
async (ctx, req, res) => {
const client = contentManagement.contentClient
.getForRequest({ request: req, requestHandlerContext: ctx })
.for<LensSavedObject>(CONTENT_ID, PUBLIC_API_CONTENT_MANAGEMENT_VERSION);

try {
await client.delete(req.params.id);
} catch (error) {
if (isBoom(error)) {
if (error.output.statusCode === 404) {
return res.notFound({
body: {
message: `A Lens visualization with saved object id [${req.params.id}] was not found.`,
},
});
}
if (error.output.statusCode === 403) {
return res.forbidden();
}
}

return boomify(error); // forward unknown error
}

return res.noContent();
}
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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 { schema } from '@kbn/config-schema';

import { boomify, isBoom } from '@hapi/boom';
import { CONTENT_ID, type LensSavedObject } from '../../../../common/content_management';
import {
PUBLIC_API_PATH,
PUBLIC_API_VERSION,
PUBLIC_API_CONTENT_MANAGEMENT_VERSION,
PUBLIC_API_ACCESS,
} from '../../constants';
import { lensSavedObjectSchema } from '../../../content_management/v1';
import { RegisterAPIRouteFn } from '../../types';

export const registerLensVisualizationsGetAPIRoute: RegisterAPIRouteFn = (
router,
{ contentManagement }
) => {
const getRoute = router.get({
path: `${PUBLIC_API_PATH}/visualizations/{id}`,
access: PUBLIC_API_ACCESS,
enableQueryVersion: true,
summary: 'Get Lens visualization',
description: 'Get a Lens visualization from id.',
options: {
tags: ['oas-tag:Lens'],
availability: {
stability: 'experimental',
},
},
security: {
authz: {
enabled: false,
reason: 'Relies on Content Client for authorization',
},
},
});

getRoute.addVersion(
{
version: PUBLIC_API_VERSION,
validate: {
request: {
params: schema.object({
id: schema.string({
meta: {
description: 'The saved object id of a Lens visualization.',
},
}),
}),
},
response: {
200: {
body: () => lensSavedObjectSchema,
description: 'Ok',
},
400: {
description: 'Malformed request',
},
401: {
description: 'Unauthorized',
},
403: {
description: 'Forbidden',
},
404: {
description: 'Resource not found',
},
500: {
description: 'Internal Server Error',
},
},
},
},
async (ctx, req, res) => {
let result;
const client = contentManagement.contentClient
.getForRequest({ request: req, requestHandlerContext: ctx })
.for<LensSavedObject>(CONTENT_ID, PUBLIC_API_CONTENT_MANAGEMENT_VERSION);

try {
({ result } = await client.get(req.params.id));
} catch (error) {
if (isBoom(error)) {
if (error.output.statusCode === 404) {
return res.notFound({
body: {
message: `A Lens visualization with saved object id [${req.params.id}] was not found.`,
},
});
}
if (error.output.statusCode === 403) {
return res.forbidden();
}
}

return boomify(error); // forward unknown error
}

return res.ok({ body: result.item });
}
);
};
Loading