[Security Solution] Move remaining DE route schemas to /common/api (#162856)

Closes https://github.com/elastic/security-team/issues/7098

After this PR is merged, all DE APIs listed
[here](https://docs.google.com/spreadsheets/d/1VCoJ74EkyGuj59VwWj_3v2ecB84pNCpzGqkYnS0SUKw/edit?pli=1#gid=0)
will have a corresponding folder and schema file in `/common/api`.
This commit is contained in:
Marshall Main 2023-08-04 09:20:10 -07:00 committed by GitHub
parent f2b07fc47d
commit dd6839336c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 150 additions and 64 deletions

View file

@ -7,10 +7,12 @@
export * from './alert_tags';
export * from './fleet_integrations';
export * from './index_management';
export * from './model';
export * from './prebuilt_rules';
export * from './rule_exceptions';
export * from './rule_management';
export * from './rule_monitoring';
export * from './rule_preview';
export * from './signals';
export * from './signals_migration';

View file

@ -0,0 +1,10 @@
/*
* 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 interface CreateIndexResponse {
acknowledged: boolean;
}

View file

@ -0,0 +1,10 @@
/*
* 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 interface DeleteIndexResponse {
acknowledged: boolean;
}

View file

@ -0,0 +1,12 @@
/*
* 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 * from './create_index/create_index_route';
export * from './delete_index/delete_index_route';
export * from './read_alerts_index_exists/read_alerts_index_exists_route';
export * from './read_index/read_index_route';
export * from './read_privileges/read_privileges_route';

View file

@ -0,0 +1,10 @@
/*
* 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 interface ReadAlertsIndexExistsResponse {
indexExists: boolean;
}

View file

@ -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 interface ReadIndexResponse {
name: string;
index_mapping_outdated: boolean | null;
}

View file

@ -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 interface ReadPrivilegesResponse {
is_authenticated: boolean;
has_encryption_key: boolean;
}

View file

@ -178,8 +178,8 @@ export const BaseCreateProps = baseSchema.create;
// with some variations for each route. These intersect with type specific schemas below
// to create the full schema for each route.
type SharedCreateProps = t.TypeOf<typeof SharedCreateProps>;
const SharedCreateProps = t.intersection([
export type SharedCreateProps = t.TypeOf<typeof SharedCreateProps>;
export const SharedCreateProps = t.intersection([
baseSchema.create,
t.exact(t.partial({ rule_id: RuleSignatureId })),
]);
@ -542,28 +542,3 @@ export const RulePatchProps = t.intersection([TypeSpecificPatchProps, SharedPatc
export type RuleResponse = t.TypeOf<typeof RuleResponse>;
export const RuleResponse = t.intersection([SharedResponseProps, TypeSpecificResponse]);
// -------------------------------------------------------------------------------------------------
// Rule preview schemas
// TODO: Move to the rule_preview subdomain
export type PreviewRulesSchema = t.TypeOf<typeof previewRulesSchema>;
export const previewRulesSchema = t.intersection([
SharedCreateProps,
TypeSpecificCreateProps,
t.type({ invocationCount: t.number, timeframeEnd: t.string }),
]);
export interface RulePreviewLogs {
errors: string[];
warnings: string[];
startedAt?: string;
duration: number;
}
export interface PreviewResponse {
previewId: string | undefined;
logs: RulePreviewLogs[] | undefined;
isAborted: boolean | undefined;
}

View file

@ -0,0 +1,17 @@
/*
* 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 * as t from 'io-ts';
export const CreateSharedExceptionListRequest = t.exact(
t.type({
name: t.string,
description: t.string,
})
);
export type CreateSharedExceptionListRequest = t.TypeOf<typeof CreateSharedExceptionListRequest>;
export type CreateSharedExceptionListRequestDecoded = CreateSharedExceptionListRequest;

View file

@ -6,5 +6,6 @@
*/
export * from './create_rule_exceptions/create_rule_exceptions_route';
export * from './create_shared_exceptions_list/create_shared_exceptions_list_route';
export * from './find_exception_references/find_exception_references_route';
export * from './urls';

View file

@ -0,0 +1,8 @@
/*
* 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 * from './preview_rules_route';

View file

@ -0,0 +1,29 @@
/*
* 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 * as t from 'io-ts';
import { SharedCreateProps, TypeSpecificCreateProps } from '../model';
export type PreviewRulesSchema = t.TypeOf<typeof previewRulesSchema>;
export const previewRulesSchema = t.intersection([
SharedCreateProps,
TypeSpecificCreateProps,
t.type({ invocationCount: t.number, timeframeEnd: t.string }),
]);
export interface RulePreviewLogs {
errors: string[];
warnings: string[];
startedAt?: string;
duration: number;
}
export interface PreviewResponse {
previewId: string | undefined;
logs: RulePreviewLogs[] | undefined;
isAborted: boolean | undefined;
}

View file

@ -53,10 +53,7 @@ import type {
BulkActionEditPayload,
} from '../../../../common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route';
import { BulkActionType } from '../../../../common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route';
import type {
PreviewResponse,
RuleResponse,
} from '../../../../common/api/detection_engine/model/rule_schema';
import type { PreviewResponse, RuleResponse } from '../../../../common/api/detection_engine';
import { KibanaServices } from '../../../common/lib/kibana';
import * as i18n from '../../../detections/pages/detection_engine/rules/translations';

View file

@ -7,7 +7,7 @@
import React, { Fragment, useMemo } from 'react';
import { EuiCallOut, EuiText, EuiSpacer, EuiAccordion } from '@elastic/eui';
import type { RulePreviewLogs } from '../../../../../common/api/detection_engine/model/rule_schema';
import type { RulePreviewLogs } from '../../../../../common/api/detection_engine';
import * as i18n from './translations';
interface PreviewLogsComponentProps {

View file

@ -9,7 +9,7 @@ import { useEffect, useState, useCallback } from 'react';
import type { List } from '@kbn/securitysolution-io-ts-list-types';
import { usePreviewRule } from './use_preview_rule';
import { formatPreviewRule } from '../../../../detection_engine/rule_creation_ui/pages/rule_creation/helpers';
import type { RulePreviewLogs } from '../../../../../common/api/detection_engine/model/rule_schema';
import type { RulePreviewLogs } from '../../../../../common/api/detection_engine';
import type {
AboutStepRule,
DefineStepRule,

View file

@ -8,10 +8,7 @@
import { useEffect, useMemo, useState } from 'react';
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
import type {
PreviewResponse,
RuleCreateProps,
} from '../../../../../common/api/detection_engine/model/rule_schema';
import type { PreviewResponse, RuleCreateProps } from '../../../../../common/api/detection_engine';
import { previewRule } from '../../../../detection_engine/rule_management/api/api';
import { transformOutput } from '../../../containers/detection_engine/rules/transforms';

View file

@ -7,7 +7,7 @@
import { chunk, get } from 'lodash';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { ElasticsearchClient } from '@kbn/core/server';
import type { ElasticsearchClient, IKibanaResponse } from '@kbn/core/server';
import {
transformError,
getBootstrapIndexExists,
@ -20,6 +20,7 @@ import type {
SecuritySolutionPluginRouter,
} from '../../../../types';
import { DETECTION_ENGINE_INDEX_URL } from '../../../../../common/constants';
import type { CreateIndexResponse } from '../../../../../common/api/detection_engine';
import { buildSiemResponse } from '../utils';
import {
getSignalsTemplate,
@ -43,7 +44,7 @@ export const createIndexRoute = (router: SecuritySolutionPluginRouter) => {
tags: ['access:securitySolution'],
},
},
async (context, _, response) => {
async (context, _, response): Promise<IKibanaResponse<CreateIndexResponse>> => {
const siemResponse = buildSiemResponse(response);
try {

View file

@ -12,9 +12,12 @@ import {
deletePolicy,
deleteAllIndex,
} from '@kbn/securitysolution-es-utils';
import type { IKibanaResponse } from '@kbn/core/server';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_INDEX_URL } from '../../../../../common/constants';
import { buildSiemResponse } from '../utils';
import type { DeleteIndexResponse } from '../../../../../common/api/detection_engine';
/**
* Deletes all of the indexes, template, ilm policies, and aliases. You can check
@ -36,7 +39,7 @@ export const deleteIndexRoute = (router: SecuritySolutionPluginRouter) => {
tags: ['access:securitySolution'],
},
},
async (context, _, response) => {
async (context, _, response): Promise<IKibanaResponse<DeleteIndexResponse>> => {
const siemResponse = buildSiemResponse(response);
try {

View file

@ -6,10 +6,12 @@
*/
import { transformError, getIndexExists } from '@kbn/securitysolution-es-utils';
import type { IKibanaResponse } from '@kbn/core/server';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_ALERTS_INDEX_URL } from '../../../../../common/constants';
import { buildSiemResponse } from '../utils';
import type { ReadAlertsIndexExistsResponse } from '../../../../../common/api/detection_engine';
export const readAlertsIndexExistsRoute = (router: SecuritySolutionPluginRouter) => {
router.get(
@ -20,7 +22,7 @@ export const readAlertsIndexExistsRoute = (router: SecuritySolutionPluginRouter)
tags: ['access:securitySolution'],
},
},
async (context, _, response) => {
async (context, _, response): Promise<IKibanaResponse<ReadAlertsIndexExistsResponse>> => {
const siemResponse = buildSiemResponse(response);
try {

View file

@ -7,6 +7,7 @@
import { transformError, getBootstrapIndexExists } from '@kbn/securitysolution-es-utils';
import type { RuleDataPluginService } from '@kbn/rule-registry-plugin/server';
import type { IKibanaResponse } from '@kbn/core/server';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_INDEX_URL } from '../../../../../common/constants';
@ -15,6 +16,7 @@ import { fieldAliasesOutdated } from './check_template_version';
import { getIndexVersion } from './get_index_version';
import { isOutdated } from '../../migrations/helpers';
import { SIGNALS_TEMPLATE_VERSION } from './get_signals_template';
import type { ReadIndexResponse } from '../../../../../common/api/detection_engine';
export const readIndexRoute = (
router: SecuritySolutionPluginRouter,
@ -28,7 +30,7 @@ export const readIndexRoute = (
tags: ['access:securitySolution'],
},
},
async (context, _, response) => {
async (context, _, response): Promise<IKibanaResponse<ReadIndexResponse>> => {
const siemResponse = buildSiemResponse(response);
try {

View file

@ -8,9 +8,11 @@
import { merge } from 'lodash/fp';
import { readPrivileges, transformError } from '@kbn/securitysolution-es-utils';
import type { IKibanaResponse } from '@kbn/core/server';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_PRIVILEGES_URL } from '../../../../../common/constants';
import { buildSiemResponse } from '../utils';
import type { ReadPrivilegesResponse } from '../../../../../common/api/detection_engine';
export const readPrivilegesRoute = (
router: SecuritySolutionPluginRouter,
@ -24,7 +26,7 @@ export const readPrivilegesRoute = (
tags: ['access:securitySolution'],
},
},
async (context, request, response) => {
async (context, request, response): Promise<IKibanaResponse<ReadPrivilegesResponse>> => {
const siemResponse = buildSiemResponse(response);
try {

View file

@ -28,8 +28,8 @@ import { RuleExecutionStatus } from '../../../../../../common/api/detection_engi
import type {
PreviewResponse,
RulePreviewLogs,
} from '../../../../../../common/api/detection_engine/model/rule_schema';
import { previewRulesSchema } from '../../../../../../common/api/detection_engine/model/rule_schema';
} from '../../../../../../common/api/detection_engine';
import { previewRulesSchema } from '../../../../../../common/api/detection_engine';
import type { StartPlugins, SetupPlugins } from '../../../../../plugin';
import { buildSiemResponse } from '../../../routes/utils';

View file

@ -4,40 +4,26 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import * as t from 'io-ts';
import { v4 as uuidv4 } from 'uuid';
import type { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types';
import type { IKibanaResponse } from '@kbn/core/server';
import { CreateSharedExceptionListRequest } from '../../../../../common/api/detection_engine';
import { SHARED_EXCEPTION_LIST_URL } from '../../../../../common/constants';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { buildSiemResponse } from '../../../detection_engine/routes/utils';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
/**
* URL path parameters of the API route.
*/
export const CreateSharedExceptionListRequestParams = t.exact(
t.type({
name: t.string,
description: t.string,
})
);
export type CreateSharedExceptionListRequestParams = t.TypeOf<
typeof CreateSharedExceptionListRequestParams
>;
export type CreateSharedExceptionListRequestParamsDecoded = CreateSharedExceptionListRequestParams;
export const createSharedExceptionListRoute = (router: SecuritySolutionPluginRouter) => {
router.post(
{
path: SHARED_EXCEPTION_LIST_URL,
validate: {
body: buildRouteValidation<
typeof CreateSharedExceptionListRequestParams,
CreateSharedExceptionListRequestParams
>(CreateSharedExceptionListRequestParams),
typeof CreateSharedExceptionListRequest,
CreateSharedExceptionListRequest
>(CreateSharedExceptionListRequest),
},
options: {
tags: ['access:securitySolution'],