Skip to content

Commit

Permalink
[Entity Analytics] Add return types to all our routes (elastic#189726)
Browse files Browse the repository at this point in the history
## Summary
Add return types to all of our route handlers.

Before we did things like this in _some_ APIs:

```
const resBody: CreateAssetCriticalityRecordResponse = { blah : 'blah'};
```

And I have moved to this style:

```
      async (
        context,
        request,
        response
      ): Promise<IKibanaResponse<CreateAssetCriticalityRecordResponse>> => {
```

This keeps the API docs in sync, I saw that this is how they do it in
the elastic assistant plugin and liked it. I think it is clearer to have
this stuff in the route definition, near the URL and request validation.

---------

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
hop-dev and elasticmachine authored Aug 2, 2024
1 parent 3c431ff commit bc79b99
Show file tree
Hide file tree
Showing 27 changed files with 454 additions and 321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,11 @@
* version: 1
*/

import { z } from 'zod';
import type { z } from 'zod';

export type EntityAnalyticsPrivileges = z.infer<typeof EntityAnalyticsPrivileges>;
export const EntityAnalyticsPrivileges = z.object({
has_all_required: z.boolean(),
has_read_permissions: z.boolean().optional(),
has_write_permissions: z.boolean().optional(),
privileges: z.object({
elasticsearch: z.object({
cluster: z
.object({
manage_index_templates: z.boolean().optional(),
manage_transform: z.boolean().optional(),
})
.optional(),
index: z
.object({})
.catchall(
z.object({
read: z.boolean().optional(),
write: z.boolean().optional(),
})
)
.optional(),
}),
}),
});
import { EntityAnalyticsPrivileges } from '../common/common.gen';

export type AssetCriticalityGetPrivilegesResponse = z.infer<
typeof AssetCriticalityGetPrivilegesResponse
>;
export const AssetCriticalityGetPrivilegesResponse = EntityAnalyticsPrivileges;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ paths:
get:
x-labels: [ess, serverless]
x-internal: true
x-codegen-enabled: true
operationId: AssetCriticalityGetPrivileges
summary: Get Asset Criticality Privileges
responses:
Expand All @@ -15,49 +16,11 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/EntityAnalyticsPrivileges'
$ref: '../common/common.schema.yaml#/components/schemas/EntityAnalyticsPrivileges'
example:
elasticsearch:
index:
'.asset-criticality.asset-criticality-*':
read: true
write: false
has_all_required: false
components:
schemas:
EntityAnalyticsPrivileges:
type: object
properties:
has_all_required:
type: boolean
has_read_permissions:
type: boolean
has_write_permissions:
type: boolean
privileges:
type: object
properties:
elasticsearch:
type: object
properties:
cluster:
type: object
properties:
manage_index_templates:
type: boolean
manage_transform:
type: boolean
index:
type: object
additionalProperties:
type: object
properties:
read:
type: boolean
write:
type: boolean
required:
- elasticsearch
required:
- has_all_required
- privileges
has_all_required: false
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ import { z } from 'zod';

import { AssetCriticalityLevel } from '../asset_criticality/common.gen';

export type EntityAnalyticsPrivileges = z.infer<typeof EntityAnalyticsPrivileges>;
export const EntityAnalyticsPrivileges = z.object({
has_all_required: z.boolean(),
has_read_permissions: z.boolean().optional(),
has_write_permissions: z.boolean().optional(),
privileges: z.object({
elasticsearch: z.object({
cluster: z
.object({
manage_index_templates: z.boolean().optional(),
manage_transform: z.boolean().optional(),
})
.optional(),
index: z
.object({})
.catchall(
z.object({
read: z.boolean().optional(),
write: z.boolean().optional(),
})
)
.optional(),
}),
}),
});

export type EntityAfterKey = z.infer<typeof EntityAfterKey>;
export const EntityAfterKey = z.object({}).catchall(z.string());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,42 @@ info:
paths: {}
components:
schemas:
EntityAnalyticsPrivileges:
type: object
properties:
has_all_required:
type: boolean
has_read_permissions:
type: boolean
has_write_permissions:
type: boolean
privileges:
type: object
properties:
elasticsearch:
type: object
properties:
cluster:
type: object
properties:
manage_index_templates:
type: boolean
manage_transform:
type: boolean
index:
type: object
additionalProperties:
type: object
properties:
read:
type: boolean
write:
type: boolean
required:
- elasticsearch
required:
- has_all_required
- privileges
EntityAfterKey:
type: object
additionalProperties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
export * from './asset_criticality';
export * from './risk_engine';
export * from './risk_score';
export { EntityAnalyticsPrivileges } from './common';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.
*/

/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: Get Risk Engine Privileges Schema
* version: 1
*/

import type { z } from 'zod';

import { EntityAnalyticsPrivileges } from '../common/common.gen';

export type RiskEngineGetPrivilegesResponse = z.infer<typeof RiskEngineGetPrivilegesResponse>;
export const RiskEngineGetPrivilegesResponse = EntityAnalyticsPrivileges;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
openapi: 3.0.0
info:
title: Get Risk Engine Privileges Schema
version: '1'
paths:
/internal/risk_engine/privileges:
get:
x-labels: [ess, serverless]
x-internal: true
x-codegen-enabled: true
operationId: RiskEngineGetPrivileges
summary: Get Risk Engine Privileges
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '../common/common.schema.yaml#/components/schemas/EntityAnalyticsPrivileges'
example:
elasticsearch:
index:
'risk-score.risk-score-*':
read: true
write: false
has_all_required: false
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './engine_status_route.gen';
export * from './calculation_route.gen';
export * from './preview_route.gen';
export * from './entity_calculation_route.gen';
export * from './get_risk_engine_privileges.gen';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import type { EntityAnalyticsPrivileges } from '../../api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen';
import type { EntityAnalyticsPrivileges } from '../../api/entity_analytics';
import { getMissingRiskEnginePrivileges } from './privileges';

describe('getMissingRiskEnginePrivileges', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import type { NonEmptyArray } from 'fp-ts/NonEmptyArray';
import type { EntityAnalyticsPrivileges } from '../../api/entity_analytics/asset_criticality/get_asset_criticality_privileges.gen';
import type { EntityAnalyticsPrivileges } from '../../api/entity_analytics';
import type { RiskEngineIndexPrivilege } from './constants';
import {
RISK_ENGINE_REQUIRED_ES_CLUSTER_PRIVILEGES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {
import type {
AssetCriticalityRecord,
EntityAnalyticsPrivileges,
} from '../../../common/api/entity_analytics/asset_criticality';
} from '../../../common/api/entity_analytics';
import type { RiskScoreEntity } from '../../../common/search_strategy';
import {
RISK_ENGINE_STATUS_URL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Logger } from '@kbn/core/server';
import type { IKibanaResponse, Logger } from '@kbn/core/server';
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
import { transformError } from '@kbn/securitysolution-es-utils';
import { Readable } from 'node:stream';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
import type { BulkUpsertAssetCriticalityRecordsResponse } from '../../../../../common/api/entity_analytics';
import { BulkUpsertAssetCriticalityRecordsRequestBody } from '../../../../../common/api/entity_analytics';
import {
BulkUpsertAssetCriticalityRecordsRequestBody,
type BulkUpsertAssetCriticalityRecordsResponse,
} from '../../../../../common/api/entity_analytics';
import type { ConfigType } from '../../../../config';
import {
ASSET_CRITICALITY_PUBLIC_BULK_UPLOAD_URL,
Expand Down Expand Up @@ -46,7 +48,11 @@ export const assetCriticalityPublicBulkUploadRoute = (
},
},
},
async (context, request, response) => {
async (
context,
request,
response
): Promise<IKibanaResponse<BulkUpsertAssetCriticalityRecordsResponse>> => {
const { errorRetries, maxBulkRequestBodySizeBytes } =
config.entityAnalytics.assetCriticality.csvUpload;
const { records } = request.body;
Expand Down Expand Up @@ -90,9 +96,7 @@ export const assetCriticalityPublicBulkUploadRoute = (
() => `Asset criticality Bulk upload completed in ${tookMs}ms ${JSON.stringify(stats)}`
);

const resBody: BulkUpsertAssetCriticalityRecordsResponse = { errors, stats };

return response.ok({ body: resBody });
return response.ok({ body: { errors, stats } });
} catch (e) {
logger.error(`Error during asset criticality bulk upload: ${e}`);
const error = transformError(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Logger } from '@kbn/core/server';
import type { IKibanaResponse, Logger } from '@kbn/core/server';
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
import { transformError } from '@kbn/securitysolution-es-utils';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
import { GetAssetCriticalityRecordRequestQuery } from '../../../../../common/api/entity_analytics';
import {
GetAssetCriticalityRecordRequestQuery,
type GetAssetCriticalityRecordResponse,
} from '../../../../../common/api/entity_analytics';
import {
ASSET_CRITICALITY_PUBLIC_URL,
APP_ID,
Expand Down Expand Up @@ -42,7 +45,11 @@ export const assetCriticalityPublicGetRoute = (
},
},
},
async (context, request, response) => {
async (
context,
request,
response
): Promise<IKibanaResponse<GetAssetCriticalityRecordResponse>> => {
const siemResponse = buildSiemResponse(response);
try {
await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Logger } from '@kbn/core/server';
import type { IKibanaResponse, Logger } from '@kbn/core/server';
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
import { transformError } from '@kbn/securitysolution-es-utils';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
Expand Down Expand Up @@ -43,7 +43,11 @@ export const assetCriticalityPublicListRoute = (
},
},
},
async (context, request, response) => {
async (
context,
request,
response
): Promise<IKibanaResponse<FindAssetCriticalityRecordsResponse>> => {
const siemResponse = buildSiemResponse(response);
try {
await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING);
Expand Down Expand Up @@ -81,7 +85,7 @@ export const assetCriticalityPublicListRoute = (
},
});

const body: FindAssetCriticalityRecordsResponse = {
const body = {
records,
total,
page,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Logger } from '@kbn/core/server';
import type { IKibanaResponse, Logger } from '@kbn/core/server';
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
import { transformError } from '@kbn/securitysolution-es-utils';
import type { AssetCriticalityGetPrivilegesResponse } from '../../../../../common/api/entity_analytics';
import {
ASSET_CRITICALITY_INTERNAL_PRIVILEGES_URL,
APP_ID,
Expand Down Expand Up @@ -38,7 +39,11 @@ export const assetCriticalityInternalPrivilegesRoute = (
version: API_VERSIONS.internal.v1,
validate: false,
},
async (context, request, response) => {
async (
context,
request,
response
): Promise<IKibanaResponse<AssetCriticalityGetPrivilegesResponse>> => {
const siemResponse = buildSiemResponse(response);
try {
await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING);
Expand Down
Loading

0 comments on commit bc79b99

Please sign in to comment.