mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution][EDR Workflows] Remove deprecated API's (#199598)
## Summary - This adds api removals for deprecated API's. - Also updates OAS documentations and api types. - Also updates/removes test. These changes are intended to be for `9.0` and Serverless GA. API's removed: - `/api/endpoint/isolate` - `/api/endpoint/unisolate` - `/api/endpoint/policy/summaries` - `/api/endpoint/suggestions/{suggestion_type}` - `/api/endpoint/action_log/{agent_id}` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
90b14e2ba9
commit
a79695deff
36 changed files with 13 additions and 2343 deletions
|
@ -7597,34 +7597,6 @@ paths:
|
|||
summary: Get response actions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_log/{agent_id}:
|
||||
get:
|
||||
deprecated: true
|
||||
description: Get an action request log for the specified agent ID.
|
||||
operationId: EndpointGetActionLog
|
||||
parameters:
|
||||
- in: path
|
||||
name: agent_id
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_AgentId'
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_ActionLogRequestQuery
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get an action request log
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_status:
|
||||
get:
|
||||
description: Get the status of response actions for the specified agent IDs.
|
||||
|
@ -7980,21 +7952,6 @@ paths:
|
|||
summary: Get metadata
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata/transforms:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetEndpointMetadataTransform
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get metadata transforms
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy_response:
|
||||
get:
|
||||
operationId: GetPolicyResponse
|
||||
|
@ -8018,33 +7975,6 @@ paths:
|
|||
summary: Get a policy response
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy/summaries:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetAgentPolicySummary
|
||||
parameters:
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
package_name:
|
||||
type: string
|
||||
policy_id:
|
||||
nullable: true
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get an agent policy summary
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/protection_updates_note/{package_policy_id}:
|
||||
get:
|
||||
operationId: GetProtectionUpdatesNote
|
||||
|
@ -8093,44 +8023,6 @@ paths:
|
|||
summary: Create or update a protection updates note
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/suggestions/{suggestion_type}:
|
||||
post:
|
||||
deprecated: true
|
||||
operationId: GetEndpointSuggestions
|
||||
parameters:
|
||||
- in: path
|
||||
name: suggestion_type
|
||||
required: true
|
||||
schema:
|
||||
enum:
|
||||
- eventFilters
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
fieldMeta: {}
|
||||
filters: {}
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- parameters
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get suggestions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/entity_store/engines:
|
||||
get:
|
||||
operationId: ListEntityEngines
|
||||
|
@ -46207,17 +46099,6 @@ components:
|
|||
required:
|
||||
- status_code
|
||||
- message
|
||||
Security_Endpoint_Management_API_ActionLogRequestQuery:
|
||||
type: object
|
||||
properties:
|
||||
end_date:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_EndDate'
|
||||
page:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_Page'
|
||||
page_size:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_PageSize'
|
||||
start_date:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_StartDate'
|
||||
Security_Endpoint_Management_API_ActionStateSuccessResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -46536,12 +46417,6 @@ components:
|
|||
description: Page number
|
||||
minimum: 1
|
||||
type: integer
|
||||
Security_Endpoint_Management_API_PageSize:
|
||||
default: 10
|
||||
description: Number of items per page
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
type: integer
|
||||
Security_Endpoint_Management_API_Parameters:
|
||||
description: Optional parameters object
|
||||
type: object
|
||||
|
|
|
@ -10916,34 +10916,6 @@ paths:
|
|||
summary: Get response actions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_log/{agent_id}:
|
||||
get:
|
||||
deprecated: true
|
||||
description: Get an action request log for the specified agent ID.
|
||||
operationId: EndpointGetActionLog
|
||||
parameters:
|
||||
- in: path
|
||||
name: agent_id
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_AgentId'
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_ActionLogRequestQuery
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get an action request log
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_status:
|
||||
get:
|
||||
description: Get the status of response actions for the specified agent IDs.
|
||||
|
@ -11258,63 +11230,6 @@ paths:
|
|||
summary: Upload a file
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/isolate:
|
||||
post:
|
||||
deprecated: true
|
||||
description: >
|
||||
Isolate an endpoint from the network.
|
||||
|
||||
> info
|
||||
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana
|
||||
host>:<port>/api/endpoint/action/isolate`.
|
||||
operationId: EndpointIsolateRedirect
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
agent_type:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_AgentTypes
|
||||
alert_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_AlertIds
|
||||
case_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_CaseIds
|
||||
comment:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_Comment
|
||||
endpoint_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_EndpointIds
|
||||
parameters:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_Parameters
|
||||
required:
|
||||
- endpoint_ids
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/isolate"
|
||||
schema:
|
||||
example: /api/endpoint/action/isolate
|
||||
type: string
|
||||
summary: Isolate an endpoint
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata:
|
||||
get:
|
||||
operationId: GetEndpointMetadataList
|
||||
|
@ -11356,21 +11271,6 @@ paths:
|
|||
summary: Get metadata
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata/transforms:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetEndpointMetadataTransform
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get metadata transforms
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy_response:
|
||||
get:
|
||||
operationId: GetPolicyResponse
|
||||
|
@ -11394,33 +11294,6 @@ paths:
|
|||
summary: Get a policy response
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy/summaries:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetAgentPolicySummary
|
||||
parameters:
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
package_name:
|
||||
type: string
|
||||
policy_id:
|
||||
nullable: true
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get an agent policy summary
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/protection_updates_note/{package_policy_id}:
|
||||
get:
|
||||
operationId: GetProtectionUpdatesNote
|
||||
|
@ -11469,101 +11342,6 @@ paths:
|
|||
summary: Create or update a protection updates note
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/suggestions/{suggestion_type}:
|
||||
post:
|
||||
deprecated: true
|
||||
operationId: GetEndpointSuggestions
|
||||
parameters:
|
||||
- in: path
|
||||
name: suggestion_type
|
||||
required: true
|
||||
schema:
|
||||
enum:
|
||||
- eventFilters
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
fieldMeta: {}
|
||||
filters: {}
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- parameters
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
summary: Get suggestions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/unisolate:
|
||||
post:
|
||||
deprecated: true
|
||||
description: >
|
||||
Release an isolated endpoint, allowing it to rejoin a network.
|
||||
|
||||
> info
|
||||
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana
|
||||
host>:<port>/api/endpoint/action/unisolate`.
|
||||
operationId: EndpointUnisolateRedirect
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
agent_type:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_AgentTypes
|
||||
alert_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_AlertIds
|
||||
case_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_CaseIds
|
||||
comment:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_Comment
|
||||
endpoint_ids:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_EndpointIds
|
||||
parameters:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_Parameters
|
||||
required:
|
||||
- endpoint_ids
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Endpoint_Management_API_SuccessResponse
|
||||
description: OK
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/unisolate"
|
||||
schema:
|
||||
example: /api/endpoint/action/unisolate
|
||||
type: string
|
||||
summary: Release an isolated endpoint
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/entity_store/engines:
|
||||
get:
|
||||
operationId: ListEntityEngines
|
||||
|
@ -54595,17 +54373,6 @@ components:
|
|||
required:
|
||||
- status_code
|
||||
- message
|
||||
Security_Endpoint_Management_API_ActionLogRequestQuery:
|
||||
type: object
|
||||
properties:
|
||||
end_date:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_EndDate'
|
||||
page:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_Page'
|
||||
page_size:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_PageSize'
|
||||
start_date:
|
||||
$ref: '#/components/schemas/Security_Endpoint_Management_API_StartDate'
|
||||
Security_Endpoint_Management_API_ActionStateSuccessResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -54924,12 +54691,6 @@ components:
|
|||
description: Page number
|
||||
minimum: 1
|
||||
type: integer
|
||||
Security_Endpoint_Management_API_PageSize:
|
||||
default: 10
|
||||
description: Number of items per page
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
type: integer
|
||||
Security_Endpoint_Management_API_Parameters:
|
||||
description: Optional parameters object
|
||||
type: object
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* 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: Action Log Schema
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { Page, PageSize, StartDate, EndDate } from '../../model/schema/common.gen';
|
||||
|
||||
export type ActionLogRequestQuery = z.infer<typeof ActionLogRequestQuery>;
|
||||
export const ActionLogRequestQuery = z.object({
|
||||
page: Page.optional(),
|
||||
page_size: PageSize.optional(),
|
||||
start_date: StartDate.optional(),
|
||||
end_date: EndDate.optional(),
|
||||
});
|
|
@ -1,45 +0,0 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Action Log Schema
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/endpoint/action_log/{agent_id}:
|
||||
get:
|
||||
summary: Get an action request log
|
||||
operationId: EndpointGetActionLog
|
||||
description: Get an action request log for the specified agent ID.
|
||||
deprecated: true
|
||||
x-codegen-enabled: false
|
||||
x-labels: [ess, serverless]
|
||||
parameters:
|
||||
- name: agent_id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/AgentId'
|
||||
- name: query
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/ActionLogRequestQuery'
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/SuccessResponse'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
ActionLogRequestQuery:
|
||||
type: object
|
||||
properties:
|
||||
page:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/Page'
|
||||
page_size:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/PageSize'
|
||||
start_date:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/StartDate'
|
||||
end_date:
|
||||
$ref: '../../model/schema/common.schema.yaml#/components/schemas/EndDate'
|
|
@ -6,4 +6,3 @@
|
|||
*/
|
||||
|
||||
export * from './action_log';
|
||||
export * from './deprecated_action_log.gen';
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* 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: Endpoint Isolate Schema
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import type { z } from '@kbn/zod';
|
||||
|
||||
import { BaseActionSchema, SuccessResponse } from '../../../model/schema/common.gen';
|
||||
|
||||
export type EndpointIsolateRedirectRequestBody = z.infer<typeof EndpointIsolateRedirectRequestBody>;
|
||||
export const EndpointIsolateRedirectRequestBody = BaseActionSchema;
|
||||
export type EndpointIsolateRedirectRequestBodyInput = z.input<
|
||||
typeof EndpointIsolateRedirectRequestBody
|
||||
>;
|
||||
|
||||
export type EndpointIsolateRedirectResponse = z.infer<typeof EndpointIsolateRedirectResponse>;
|
||||
export const EndpointIsolateRedirectResponse = SuccessResponse;
|
|
@ -1,37 +0,0 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Endpoint Isolate Schema
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/endpoint/isolate:
|
||||
post:
|
||||
summary: Isolate an endpoint
|
||||
description: |
|
||||
Isolate an endpoint from the network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/isolate`.
|
||||
operationId: EndpointIsolateRedirect
|
||||
deprecated: true
|
||||
x-codegen-enabled: true
|
||||
x-labels: [ess]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../../../model/schema/common.schema.yaml#/components/schemas/BaseActionSchema'
|
||||
responses:
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/isolate"
|
||||
schema:
|
||||
type: string
|
||||
example: "/api/endpoint/action/isolate"
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../../../model/schema/common.schema.yaml#/components/schemas/SuccessResponse'
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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: Endpoint Unisolate Schema
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import type { z } from '@kbn/zod';
|
||||
|
||||
import { BaseActionSchema, SuccessResponse } from '../../../model/schema/common.gen';
|
||||
|
||||
export type EndpointUnisolateRedirectRequestBody = z.infer<
|
||||
typeof EndpointUnisolateRedirectRequestBody
|
||||
>;
|
||||
export const EndpointUnisolateRedirectRequestBody = BaseActionSchema;
|
||||
export type EndpointUnisolateRedirectRequestBodyInput = z.input<
|
||||
typeof EndpointUnisolateRedirectRequestBody
|
||||
>;
|
||||
|
||||
export type EndpointUnisolateRedirectResponse = z.infer<typeof EndpointUnisolateRedirectResponse>;
|
||||
export const EndpointUnisolateRedirectResponse = SuccessResponse;
|
|
@ -1,37 +0,0 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Endpoint Unisolate Schema
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/endpoint/unisolate:
|
||||
post:
|
||||
summary: Release an isolated endpoint
|
||||
description: |
|
||||
Release an isolated endpoint, allowing it to rejoin a network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/unisolate`.
|
||||
operationId: EndpointUnisolateRedirect
|
||||
deprecated: true
|
||||
x-codegen-enabled: true
|
||||
x-labels: [ess]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../../../model/schema/common.schema.yaml#/components/schemas/BaseActionSchema'
|
||||
responses:
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/unisolate"
|
||||
schema:
|
||||
type: string
|
||||
example: "/api/endpoint/action/unisolate"
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../../../model/schema/common.schema.yaml#/components/schemas/SuccessResponse'
|
|
@ -7,4 +7,3 @@
|
|||
|
||||
export * from './unisolate';
|
||||
export * from './unisolate.gen';
|
||||
export * from './deprecated_unisolate.gen';
|
||||
|
|
|
@ -23,13 +23,13 @@ paths:
|
|||
schema:
|
||||
$ref: '../model/schema/common.schema.yaml#/components/schemas/SuccessResponse'
|
||||
|
||||
/api/endpoint/metadata/transforms:
|
||||
/internal/api/endpoint/metadata/transforms:
|
||||
get:
|
||||
deprecated: true
|
||||
summary: Get metadata transforms
|
||||
operationId: GetEndpointMetadataTransform
|
||||
x-codegen-enabled: false
|
||||
x-labels: [ess, serverless]
|
||||
x-internal: true
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* 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: Endpoint Policy Schema
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { SuccessResponse } from '../model/schema/common.gen';
|
||||
|
||||
export type GetAgentPolicySummaryRequestQuery = z.infer<typeof GetAgentPolicySummaryRequestQuery>;
|
||||
export const GetAgentPolicySummaryRequestQuery = z.object({
|
||||
query: z.object({
|
||||
package_name: z.string().optional(),
|
||||
policy_id: z.string().nullable().optional(),
|
||||
}),
|
||||
});
|
||||
export type GetAgentPolicySummaryRequestQueryInput = z.input<
|
||||
typeof GetAgentPolicySummaryRequestQuery
|
||||
>;
|
||||
|
||||
export type GetAgentPolicySummaryResponse = z.infer<typeof GetAgentPolicySummaryResponse>;
|
||||
export const GetAgentPolicySummaryResponse = SuccessResponse;
|
|
@ -1,32 +0,0 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Endpoint Policy Schema
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/endpoint/policy/summaries:
|
||||
get:
|
||||
summary: Get an agent policy summary
|
||||
operationId: GetAgentPolicySummary
|
||||
deprecated: true
|
||||
x-codegen-enabled: true
|
||||
x-labels: [ess, serverless]
|
||||
parameters:
|
||||
- name: query
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
package_name:
|
||||
type: string
|
||||
policy_id:
|
||||
type: string
|
||||
nullable: true
|
||||
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../model/schema/common.schema.yaml#/components/schemas/SuccessResponse'
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* 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';
|
||||
|
||||
export const GetAgentPolicySummaryRequestSchema = {
|
||||
query: schema.object({
|
||||
package_name: schema.string(),
|
||||
policy_id: schema.nullable(schema.string()),
|
||||
}),
|
||||
};
|
|
@ -6,6 +6,4 @@
|
|||
*/
|
||||
|
||||
export * from './policy_response';
|
||||
export * from './deprecated_agent_policy_summary';
|
||||
export * from './policy_response.gen';
|
||||
export * from './deprecated_agent_policy_summary.gen';
|
||||
|
|
|
@ -3,13 +3,13 @@ info:
|
|||
title: Get Suggestions Schema
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/endpoint/suggestions/{suggestion_type}:
|
||||
/internal/api/endpoint/suggestions/{suggestion_type}:
|
||||
post:
|
||||
deprecated: true
|
||||
summary: Get suggestions
|
||||
operationId: GetEndpointSuggestions
|
||||
x-codegen-enabled: true
|
||||
x-labels: [ess, serverless]
|
||||
x-internal: true
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
|
|
|
@ -152,10 +152,6 @@ import type {
|
|||
EndpointGetFileActionRequestBodyInput,
|
||||
EndpointGetFileActionResponse,
|
||||
} from './endpoint/actions/response_actions/get_file/get_file.gen';
|
||||
import type {
|
||||
EndpointIsolateRedirectRequestBodyInput,
|
||||
EndpointIsolateRedirectResponse,
|
||||
} from './endpoint/actions/response_actions/isolate/deprecated_isolate.gen';
|
||||
import type {
|
||||
EndpointIsolateActionRequestBodyInput,
|
||||
EndpointIsolateActionResponse,
|
||||
|
@ -176,10 +172,6 @@ import type {
|
|||
EndpointSuspendProcessActionRequestBodyInput,
|
||||
EndpointSuspendProcessActionResponse,
|
||||
} from './endpoint/actions/response_actions/suspend_process/suspend_process.gen';
|
||||
import type {
|
||||
EndpointUnisolateRedirectRequestBodyInput,
|
||||
EndpointUnisolateRedirectResponse,
|
||||
} from './endpoint/actions/response_actions/unisolate/deprecated_unisolate.gen';
|
||||
import type {
|
||||
EndpointUnisolateActionRequestBodyInput,
|
||||
EndpointUnisolateActionResponse,
|
||||
|
@ -197,10 +189,6 @@ import type {
|
|||
GetEndpointMetadataListRequestQueryInput,
|
||||
GetEndpointMetadataListResponse,
|
||||
} from './endpoint/metadata/get_metadata.gen';
|
||||
import type {
|
||||
GetAgentPolicySummaryRequestQueryInput,
|
||||
GetAgentPolicySummaryResponse,
|
||||
} from './endpoint/policy/deprecated_agent_policy_summary.gen';
|
||||
import type {
|
||||
GetPolicyResponseRequestQueryInput,
|
||||
GetPolicyResponseResponse,
|
||||
|
@ -1011,25 +999,6 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Isolate an endpoint from the network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/isolate`.
|
||||
|
||||
*/
|
||||
async endpointIsolateRedirect(props: EndpointIsolateRedirectProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API EndpointIsolateRedirect`);
|
||||
return this.kbnClient
|
||||
.request<EndpointIsolateRedirectResponse>({
|
||||
path: '/api/endpoint/isolate',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Terminate a running process on an endpoint.
|
||||
*/
|
||||
|
@ -1094,25 +1063,6 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Release an isolated endpoint, allowing it to rejoin a network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/unisolate`.
|
||||
|
||||
*/
|
||||
async endpointUnisolateRedirect(props: EndpointUnisolateRedirectProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API EndpointUnisolateRedirect`);
|
||||
return this.kbnClient
|
||||
.request<EndpointUnisolateRedirectResponse>({
|
||||
path: '/api/endpoint/unisolate',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Upload a file to an endpoint.
|
||||
*/
|
||||
|
@ -1233,20 +1183,6 @@ finalize it.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async getAgentPolicySummary(props: GetAgentPolicySummaryProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API GetAgentPolicySummary`);
|
||||
return this.kbnClient
|
||||
.request<GetAgentPolicySummaryResponse>({
|
||||
path: '/api/endpoint/policy/summaries',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
|
||||
query: props.query,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Retrieves the rule migrations stats for all migrations stored in the system
|
||||
*/
|
||||
|
@ -1326,7 +1262,7 @@ finalize it.
|
|||
this.log.info(`${new Date().toISOString()} Calling API GetEndpointSuggestions`);
|
||||
return this.kbnClient
|
||||
.request<GetEndpointSuggestionsResponse>({
|
||||
path: replaceParams('/api/endpoint/suggestions/{suggestion_type}', props.params),
|
||||
path: replaceParams('/internal/api/endpoint/suggestions/{suggestion_type}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
|
@ -2214,9 +2150,6 @@ export interface EndpointGetProcessesActionProps {
|
|||
export interface EndpointIsolateActionProps {
|
||||
body: EndpointIsolateActionRequestBodyInput;
|
||||
}
|
||||
export interface EndpointIsolateRedirectProps {
|
||||
body: EndpointIsolateRedirectRequestBodyInput;
|
||||
}
|
||||
export interface EndpointKillProcessActionProps {
|
||||
body: EndpointKillProcessActionRequestBodyInput;
|
||||
}
|
||||
|
@ -2229,9 +2162,6 @@ export interface EndpointSuspendProcessActionProps {
|
|||
export interface EndpointUnisolateActionProps {
|
||||
body: EndpointUnisolateActionRequestBodyInput;
|
||||
}
|
||||
export interface EndpointUnisolateRedirectProps {
|
||||
body: EndpointUnisolateRedirectRequestBodyInput;
|
||||
}
|
||||
export interface EndpointUploadActionProps {
|
||||
body: EndpointUploadActionRequestBodyInput;
|
||||
}
|
||||
|
@ -2252,9 +2182,6 @@ export interface FindAssetCriticalityRecordsProps {
|
|||
export interface FindRulesProps {
|
||||
query: FindRulesRequestQueryInput;
|
||||
}
|
||||
export interface GetAgentPolicySummaryProps {
|
||||
query: GetAgentPolicySummaryRequestQueryInput;
|
||||
}
|
||||
export interface GetAssetCriticalityRecordProps {
|
||||
query: GetAssetCriticalityRecordRequestQueryInput;
|
||||
}
|
||||
|
|
|
@ -70,30 +70,19 @@ export const BASE_INTERNAL_ENDPOINT_ROUTE = `/internal${BASE_ENDPOINT_ROUTE}`;
|
|||
export const HOST_METADATA_LIST_ROUTE = `${BASE_ENDPOINT_ROUTE}/metadata`;
|
||||
export const HOST_METADATA_GET_ROUTE = `${HOST_METADATA_LIST_ROUTE}/{id}`;
|
||||
|
||||
/** @deprecated public route, use {@link METADATA_TRANSFORMS_STATUS_INTERNAL_ROUTE} internal route */
|
||||
export const METADATA_TRANSFORMS_STATUS_ROUTE = `${BASE_ENDPOINT_ROUTE}/metadata/transforms`;
|
||||
|
||||
export const METADATA_TRANSFORMS_STATUS_INTERNAL_ROUTE = `${BASE_INTERNAL_ENDPOINT_ROUTE}/metadata/transforms`;
|
||||
|
||||
export const BASE_POLICY_RESPONSE_ROUTE = `${BASE_ENDPOINT_ROUTE}/policy_response`;
|
||||
export const BASE_POLICY_ROUTE = `${BASE_ENDPOINT_ROUTE}/policy`;
|
||||
export const AGENT_POLICY_SUMMARY_ROUTE = `${BASE_POLICY_ROUTE}/summaries`;
|
||||
export const PROTECTION_UPDATES_NOTE_ROUTE = `${BASE_ENDPOINT_ROUTE}/protection_updates_note/{package_policy_id}`;
|
||||
|
||||
/** Suggestions routes */
|
||||
/** @deprecated public route, use {@link SUGGESTIONS_INTERNAL_ROUTE} internal route */
|
||||
export const SUGGESTIONS_ROUTE = `${BASE_ENDPOINT_ROUTE}/suggestions/{suggestion_type}`;
|
||||
export const SUGGESTIONS_INTERNAL_ROUTE = `${BASE_INTERNAL_ENDPOINT_ROUTE}/suggestions/{suggestion_type}`;
|
||||
|
||||
/**
|
||||
* Action Response Routes
|
||||
*/
|
||||
|
||||
/** @deprecated use `ISOLATE_HOST_ROUTE_V2` instead */
|
||||
export const ISOLATE_HOST_ROUTE = `${BASE_ENDPOINT_ROUTE}/isolate`;
|
||||
/** @deprecated use `ISOLATE_HOST_ROUTE_V2` instead */
|
||||
export const UNISOLATE_HOST_ROUTE = `${BASE_ENDPOINT_ROUTE}/unisolate`;
|
||||
|
||||
/** Base Actions route. Used to get a list of all actions and is root to other action related routes */
|
||||
export const BASE_ENDPOINT_ACTION_ROUTE = `${BASE_ENDPOINT_ROUTE}/action`;
|
||||
|
||||
|
|
|
@ -1332,17 +1332,6 @@ export interface GetHostPolicyResponse {
|
|||
policy_response: HostPolicyResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API response for retrieving agent summary
|
||||
*/
|
||||
export interface GetAgentSummaryResponse {
|
||||
summary_response: {
|
||||
package: string;
|
||||
policy_id?: string;
|
||||
versions_count: { [key: string]: number };
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API response for retrieving exception summary
|
||||
*/
|
||||
|
|
|
@ -31,32 +31,6 @@ paths:
|
|||
summary: Get response actions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_log/{agent_id}:
|
||||
get:
|
||||
deprecated: true
|
||||
description: Get an action request log for the specified agent ID.
|
||||
operationId: EndpointGetActionLog
|
||||
parameters:
|
||||
- in: path
|
||||
name: agent_id
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/AgentId'
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/ActionLogRequestQuery'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get an action request log
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_status:
|
||||
get:
|
||||
description: Get the status of response actions for the specified agent IDs.
|
||||
|
@ -348,56 +322,6 @@ paths:
|
|||
summary: Upload a file
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/isolate:
|
||||
post:
|
||||
deprecated: true
|
||||
description: >
|
||||
Isolate an endpoint from the network.
|
||||
|
||||
> info
|
||||
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana
|
||||
host>:<port>/api/endpoint/action/isolate`.
|
||||
operationId: EndpointIsolateRedirect
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
agent_type:
|
||||
$ref: '#/components/schemas/AgentTypes'
|
||||
alert_ids:
|
||||
$ref: '#/components/schemas/AlertIds'
|
||||
case_ids:
|
||||
$ref: '#/components/schemas/CaseIds'
|
||||
comment:
|
||||
$ref: '#/components/schemas/Comment'
|
||||
endpoint_ids:
|
||||
$ref: '#/components/schemas/EndpointIds'
|
||||
parameters:
|
||||
$ref: '#/components/schemas/Parameters'
|
||||
required:
|
||||
- endpoint_ids
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/isolate"
|
||||
schema:
|
||||
example: /api/endpoint/action/isolate
|
||||
type: string
|
||||
summary: Isolate an endpoint
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata:
|
||||
get:
|
||||
operationId: GetEndpointMetadataList
|
||||
|
@ -436,20 +360,6 @@ paths:
|
|||
summary: Get metadata
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata/transforms:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetEndpointMetadataTransform
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get metadata transforms
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy_response:
|
||||
get:
|
||||
operationId: GetPolicyResponse
|
||||
|
@ -472,32 +382,6 @@ paths:
|
|||
summary: Get a policy response
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy/summaries:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetAgentPolicySummary
|
||||
parameters:
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
package_name:
|
||||
type: string
|
||||
policy_id:
|
||||
nullable: true
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get an agent policy summary
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/protection_updates_note/{package_policy_id}:
|
||||
get:
|
||||
operationId: GetProtectionUpdatesNote
|
||||
|
@ -544,106 +428,8 @@ paths:
|
|||
summary: Create or update a protection updates note
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/suggestions/{suggestion_type}:
|
||||
post:
|
||||
deprecated: true
|
||||
operationId: GetEndpointSuggestions
|
||||
parameters:
|
||||
- in: path
|
||||
name: suggestion_type
|
||||
required: true
|
||||
schema:
|
||||
enum:
|
||||
- eventFilters
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
fieldMeta: {}
|
||||
filters: {}
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- parameters
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get suggestions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/unisolate:
|
||||
post:
|
||||
deprecated: true
|
||||
description: >
|
||||
Release an isolated endpoint, allowing it to rejoin a network.
|
||||
|
||||
> info
|
||||
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana
|
||||
host>:<port>/api/endpoint/action/unisolate`.
|
||||
operationId: EndpointUnisolateRedirect
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
agent_type:
|
||||
$ref: '#/components/schemas/AgentTypes'
|
||||
alert_ids:
|
||||
$ref: '#/components/schemas/AlertIds'
|
||||
case_ids:
|
||||
$ref: '#/components/schemas/CaseIds'
|
||||
comment:
|
||||
$ref: '#/components/schemas/Comment'
|
||||
endpoint_ids:
|
||||
$ref: '#/components/schemas/EndpointIds'
|
||||
parameters:
|
||||
$ref: '#/components/schemas/Parameters'
|
||||
required:
|
||||
- endpoint_ids
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
'308':
|
||||
description: Permanent Redirect
|
||||
headers:
|
||||
Location:
|
||||
description: Permanently redirects to "/api/endpoint/action/unisolate"
|
||||
schema:
|
||||
example: /api/endpoint/action/unisolate
|
||||
type: string
|
||||
summary: Release an isolated endpoint
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
components:
|
||||
schemas:
|
||||
ActionLogRequestQuery:
|
||||
type: object
|
||||
properties:
|
||||
end_date:
|
||||
$ref: '#/components/schemas/EndDate'
|
||||
page:
|
||||
$ref: '#/components/schemas/Page'
|
||||
page_size:
|
||||
$ref: '#/components/schemas/PageSize'
|
||||
start_date:
|
||||
$ref: '#/components/schemas/StartDate'
|
||||
ActionStateSuccessResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -951,12 +737,6 @@ components:
|
|||
description: Page number
|
||||
minimum: 1
|
||||
type: integer
|
||||
PageSize:
|
||||
default: 10
|
||||
description: Number of items per page
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
type: integer
|
||||
Parameters:
|
||||
description: Optional parameters object
|
||||
type: object
|
||||
|
|
|
@ -31,32 +31,6 @@ paths:
|
|||
summary: Get response actions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_log/{agent_id}:
|
||||
get:
|
||||
deprecated: true
|
||||
description: Get an action request log for the specified agent ID.
|
||||
operationId: EndpointGetActionLog
|
||||
parameters:
|
||||
- in: path
|
||||
name: agent_id
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/AgentId'
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/ActionLogRequestQuery'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get an action request log
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/action_status:
|
||||
get:
|
||||
description: Get the status of response actions for the specified agent IDs.
|
||||
|
@ -386,20 +360,6 @@ paths:
|
|||
summary: Get metadata
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/metadata/transforms:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetEndpointMetadataTransform
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get metadata transforms
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy_response:
|
||||
get:
|
||||
operationId: GetPolicyResponse
|
||||
|
@ -422,32 +382,6 @@ paths:
|
|||
summary: Get a policy response
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/policy/summaries:
|
||||
get:
|
||||
deprecated: true
|
||||
operationId: GetAgentPolicySummary
|
||||
parameters:
|
||||
- in: query
|
||||
name: query
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
package_name:
|
||||
type: string
|
||||
policy_id:
|
||||
nullable: true
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get an agent policy summary
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/protection_updates_note/{package_policy_id}:
|
||||
get:
|
||||
operationId: GetProtectionUpdatesNote
|
||||
|
@ -494,56 +428,8 @@ paths:
|
|||
summary: Create or update a protection updates note
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
/api/endpoint/suggestions/{suggestion_type}:
|
||||
post:
|
||||
deprecated: true
|
||||
operationId: GetEndpointSuggestions
|
||||
parameters:
|
||||
- in: path
|
||||
name: suggestion_type
|
||||
required: true
|
||||
schema:
|
||||
enum:
|
||||
- eventFilters
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
fieldMeta: {}
|
||||
filters: {}
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- parameters
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SuccessResponse'
|
||||
description: OK
|
||||
summary: Get suggestions
|
||||
tags:
|
||||
- Security Endpoint Management API
|
||||
components:
|
||||
schemas:
|
||||
ActionLogRequestQuery:
|
||||
type: object
|
||||
properties:
|
||||
end_date:
|
||||
$ref: '#/components/schemas/EndDate'
|
||||
page:
|
||||
$ref: '#/components/schemas/Page'
|
||||
page_size:
|
||||
$ref: '#/components/schemas/PageSize'
|
||||
start_date:
|
||||
$ref: '#/components/schemas/StartDate'
|
||||
ActionStateSuccessResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -851,12 +737,6 @@ components:
|
|||
description: Page number
|
||||
minimum: 1
|
||||
type: integer
|
||||
PageSize:
|
||||
default: 10
|
||||
description: Number of items per page
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
type: integer
|
||||
Parameters:
|
||||
description: Optional parameters object
|
||||
type: object
|
||||
|
|
|
@ -1,378 +0,0 @@
|
|||
/*
|
||||
* 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 type { KibanaResponseFactory } from '@kbn/core/server';
|
||||
import {
|
||||
coreMock,
|
||||
elasticsearchServiceMock,
|
||||
httpServerMock,
|
||||
httpServiceMock,
|
||||
savedObjectsClientMock,
|
||||
} from '@kbn/core/server/mocks';
|
||||
import { ENDPOINT_ACTION_LOG_ROUTE } from '../../../../common/endpoint/constants';
|
||||
import { EndpointAppContextService } from '../../endpoint_app_context_services';
|
||||
import {
|
||||
createMockEndpointAppContext,
|
||||
createMockEndpointAppContextServiceSetupContract,
|
||||
createMockEndpointAppContextServiceStartContract,
|
||||
createRouteHandlerContext,
|
||||
getRegisteredVersionedRouteMock,
|
||||
} from '../../mocks';
|
||||
import { registerActionAuditLogRoutes } from './audit_log';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { Results } from './mocks';
|
||||
import { mockAuditLogSearchResult } from './mocks';
|
||||
import type { SecuritySolutionRequestHandlerContext } from '../../../types';
|
||||
import type {
|
||||
ActivityLog,
|
||||
EndpointAction,
|
||||
EndpointActionResponse,
|
||||
} from '../../../../common/endpoint/types';
|
||||
import { FleetActionGenerator } from '../../../../common/endpoint/data_generators/fleet_action_generator';
|
||||
import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator';
|
||||
import type {
|
||||
EndpointActionLogRequestParams,
|
||||
EndpointActionLogRequestQuery,
|
||||
} from '../../../../common/api/endpoint';
|
||||
import { EndpointActionLogRequestSchema } from '../../../../common/api/endpoint';
|
||||
|
||||
describe('Action Log API', () => {
|
||||
describe('schema', () => {
|
||||
it('should require at least 1 agent ID', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.params.validate({}); // no agent_ids provided
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should accept a single agent ID', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.params.validate({ agent_id: uuidv4() });
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not work when no params while requesting with query params', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.query.validate({});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should work with all required query params', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.query.validate({
|
||||
page: 10,
|
||||
page_size: 100,
|
||||
start_date: new Date(new Date().setDate(new Date().getDate() - 1)).toISOString(), // yesterday
|
||||
end_date: new Date().toISOString(), // today
|
||||
});
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not work without endDate', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.query.validate({
|
||||
page: 1,
|
||||
page_size: 100,
|
||||
start_date: new Date(new Date().setDate(new Date().getDate() - 1)).toISOString(), // yesterday
|
||||
});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should not work without startDate', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.query.validate({
|
||||
page: 1,
|
||||
page_size: 100,
|
||||
end_date: new Date().toISOString(), // today
|
||||
});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('should not work without allowed page and page_size params', () => {
|
||||
expect(() => {
|
||||
EndpointActionLogRequestSchema.query.validate({ page_size: 101 });
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('response', () => {
|
||||
const mockAgentID = 'XYZABC-000';
|
||||
let endpointAppContextService: EndpointAppContextService;
|
||||
const fleetActionGenerator = new FleetActionGenerator('seed');
|
||||
const endpointActionGenerator = new EndpointActionGenerator('seed');
|
||||
|
||||
// convenience for calling the route and handler for audit log
|
||||
let getActivityLog: (
|
||||
params: EndpointActionLogRequestParams,
|
||||
query?: EndpointActionLogRequestQuery
|
||||
) => Promise<jest.Mocked<KibanaResponseFactory>>;
|
||||
|
||||
// convenience for injecting mock action requests and responses
|
||||
// for .logs-endpoint and .fleet indices
|
||||
let mockActions: ({
|
||||
numActions,
|
||||
hasFleetActions,
|
||||
hasFleetResponses,
|
||||
hasResponses,
|
||||
}: {
|
||||
numActions: number;
|
||||
hasFleetActions?: boolean;
|
||||
hasFleetResponses?: boolean;
|
||||
hasResponses?: boolean;
|
||||
}) => void;
|
||||
|
||||
let havingErrors: () => void;
|
||||
|
||||
beforeEach(() => {
|
||||
const esClientMock = elasticsearchServiceMock.createScopedClusterClient();
|
||||
const routerMock = httpServiceMock.createRouter();
|
||||
endpointAppContextService = new EndpointAppContextService();
|
||||
endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract());
|
||||
endpointAppContextService.start(createMockEndpointAppContextServiceStartContract());
|
||||
|
||||
registerActionAuditLogRoutes(routerMock, createMockEndpointAppContext());
|
||||
|
||||
getActivityLog = async (
|
||||
params: { agent_id: string },
|
||||
query?: { page: number; page_size: number; start_date?: string; end_date?: string }
|
||||
): Promise<jest.Mocked<KibanaResponseFactory>> => {
|
||||
const req = httpServerMock.createKibanaRequest({
|
||||
params,
|
||||
query,
|
||||
});
|
||||
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
const { routeHandler } = getRegisteredVersionedRouteMock(
|
||||
routerMock,
|
||||
'get',
|
||||
ENDPOINT_ACTION_LOG_ROUTE,
|
||||
'2023-10-31'
|
||||
);
|
||||
|
||||
await routeHandler(
|
||||
coreMock.createCustomRequestHandlerContext(
|
||||
createRouteHandlerContext(esClientMock, savedObjectsClientMock.create())
|
||||
) as SecuritySolutionRequestHandlerContext,
|
||||
req,
|
||||
mockResponse
|
||||
);
|
||||
|
||||
return mockResponse;
|
||||
};
|
||||
|
||||
// some arbitrary ids for needed actions
|
||||
const getMockActionIds = (numAction: number): string[] => {
|
||||
return [...Array(numAction).keys()].map(() => Math.random().toString(36).split('.')[1]);
|
||||
};
|
||||
|
||||
// create as many actions as needed
|
||||
const getEndpointActionsData = (actionIds: string[]) => {
|
||||
const data = actionIds.map((actionId) =>
|
||||
endpointActionGenerator.generate({
|
||||
agent: { id: mockAgentID },
|
||||
EndpointActions: {
|
||||
action_id: actionId,
|
||||
},
|
||||
})
|
||||
);
|
||||
return data;
|
||||
};
|
||||
// create as many responses as needed
|
||||
const getEndpointResponseData = (actionIds: string[]) => {
|
||||
const data = actionIds.map((actionId) =>
|
||||
endpointActionGenerator.generateResponse({
|
||||
agent: { id: mockAgentID },
|
||||
EndpointActions: {
|
||||
action_id: actionId,
|
||||
},
|
||||
})
|
||||
);
|
||||
return data;
|
||||
};
|
||||
// create as many fleet actions as needed
|
||||
const getFleetResponseData = (actionIds: string[]) => {
|
||||
const data = actionIds.map((actionId) =>
|
||||
fleetActionGenerator.generateResponse({
|
||||
agent_id: mockAgentID,
|
||||
action_id: actionId,
|
||||
})
|
||||
);
|
||||
return data;
|
||||
};
|
||||
// create as many fleet responses as needed
|
||||
const getFleetActionData = (actionIds: string[]) => {
|
||||
const data = actionIds.map((actionId) =>
|
||||
fleetActionGenerator.generate({
|
||||
agents: [mockAgentID],
|
||||
action_id: actionId,
|
||||
data: {
|
||||
comment: 'some comment',
|
||||
},
|
||||
})
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
// mock actions and responses results in a single response
|
||||
mockActions = ({
|
||||
numActions,
|
||||
hasFleetActions = false,
|
||||
hasFleetResponses = false,
|
||||
hasResponses = false,
|
||||
}: {
|
||||
numActions: number;
|
||||
hasFleetActions?: boolean;
|
||||
hasFleetResponses?: boolean;
|
||||
hasResponses?: boolean;
|
||||
}) => {
|
||||
// @ts-expect-error incomplete types
|
||||
esClientMock.asInternalUser.search.mockResponseImplementationOnce(() => {
|
||||
let actions: Results[] = [];
|
||||
let fleetActions: Results[] = [];
|
||||
let responses: Results[] = [];
|
||||
let fleetResponses: Results[] = [];
|
||||
|
||||
const actionIds = getMockActionIds(numActions);
|
||||
|
||||
actions = getEndpointActionsData(actionIds).map((e) => ({
|
||||
_index: '.ds-.logs-endpoint.actions-default-2021.19.10-000001',
|
||||
_source: e,
|
||||
}));
|
||||
|
||||
if (hasFleetActions) {
|
||||
fleetActions = getFleetActionData(actionIds).map((e) => ({
|
||||
_index: '.fleet-actions-7',
|
||||
_source: e,
|
||||
}));
|
||||
}
|
||||
|
||||
if (hasFleetResponses) {
|
||||
fleetResponses = getFleetResponseData(actionIds).map((e) => ({
|
||||
_index: '.ds-.fleet-actions-results-2021.19.10-000001',
|
||||
_source: e,
|
||||
}));
|
||||
}
|
||||
|
||||
if (hasResponses) {
|
||||
responses = getEndpointResponseData(actionIds).map((e) => ({
|
||||
_index: '.ds-.logs-endpoint.action.responses-default-2021.19.10-000001',
|
||||
_source: e,
|
||||
}));
|
||||
}
|
||||
|
||||
const results = mockAuditLogSearchResult([
|
||||
...actions,
|
||||
...fleetActions,
|
||||
...responses,
|
||||
...fleetResponses,
|
||||
]);
|
||||
|
||||
return results;
|
||||
});
|
||||
};
|
||||
|
||||
havingErrors = () => {
|
||||
esClientMock.asInternalUser.search.mockImplementationOnce(() =>
|
||||
// @ts-expect-error wrong definition
|
||||
Promise.resolve(() => {
|
||||
throw new Error();
|
||||
})
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
endpointAppContextService.stop();
|
||||
});
|
||||
|
||||
it('should return an empty array when nothing in audit log', async () => {
|
||||
mockActions({ numActions: 0 });
|
||||
|
||||
const response = await getActivityLog({ agent_id: mockAgentID });
|
||||
expect(response.ok).toBeCalled();
|
||||
expect((response.ok.mock.calls[0][0]?.body as ActivityLog).data).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should return fleet actions, fleet responses and endpoint responses', async () => {
|
||||
mockActions({
|
||||
numActions: 2,
|
||||
hasFleetActions: true,
|
||||
hasFleetResponses: true,
|
||||
hasResponses: true,
|
||||
});
|
||||
|
||||
const response = await getActivityLog({ agent_id: mockAgentID });
|
||||
const responseBody = response.ok.mock.calls[0][0]?.body as ActivityLog;
|
||||
expect(response.ok).toBeCalled();
|
||||
expect(responseBody.data).toHaveLength(6);
|
||||
|
||||
expect(
|
||||
responseBody.data.filter((e) => (e.item.data as EndpointActionResponse).completed_at)
|
||||
).toHaveLength(2);
|
||||
expect(
|
||||
responseBody.data.filter((e) => (e.item.data as EndpointAction).expiration)
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should return only fleet actions and no responses', async () => {
|
||||
mockActions({ numActions: 2, hasFleetActions: true });
|
||||
|
||||
const response = await getActivityLog({ agent_id: mockAgentID });
|
||||
const responseBody = response.ok.mock.calls[0][0]?.body as ActivityLog;
|
||||
expect(response.ok).toBeCalled();
|
||||
expect(responseBody.data).toHaveLength(2);
|
||||
|
||||
expect(
|
||||
responseBody.data.filter((e) => (e.item.data as EndpointAction).expiration)
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should only have fleet data', async () => {
|
||||
mockActions({ numActions: 2, hasFleetActions: true, hasFleetResponses: true });
|
||||
|
||||
const response = await getActivityLog({ agent_id: mockAgentID });
|
||||
const responseBody = response.ok.mock.calls[0][0]?.body as ActivityLog;
|
||||
expect(response.ok).toBeCalled();
|
||||
expect(responseBody.data).toHaveLength(4);
|
||||
|
||||
expect(
|
||||
responseBody.data.filter((e) => (e.item.data as EndpointAction).expiration)
|
||||
).toHaveLength(2);
|
||||
expect(
|
||||
responseBody.data.filter((e) => (e.item.data as EndpointActionResponse).completed_at)
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('should throw errors when no results for some agentID', async () => {
|
||||
havingErrors();
|
||||
|
||||
try {
|
||||
await getActivityLog({ agent_id: mockAgentID });
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`Error fetching actions log for agent_id ${mockAgentID}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return date ranges if present in the query', async () => {
|
||||
mockActions({ numActions: 0 });
|
||||
|
||||
const startDate = new Date(new Date().setDate(new Date().getDate() - 1)).toISOString();
|
||||
const endDate = new Date().toISOString();
|
||||
const response = await getActivityLog(
|
||||
{ agent_id: mockAgentID },
|
||||
{
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
}
|
||||
);
|
||||
expect(response.ok).toBeCalled();
|
||||
expect((response.ok.mock.calls[0][0]?.body as ActivityLog).startDate).toEqual(startDate);
|
||||
expect((response.ok.mock.calls[0][0]?.body as ActivityLog).endDate).toEqual(endDate);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* 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 { EndpointActionLogRequestSchema } from '../../../../common/api/endpoint';
|
||||
import { ENDPOINT_ACTION_LOG_ROUTE } from '../../../../common/endpoint/constants';
|
||||
import { auditLogRequestHandler } from './audit_log_handler';
|
||||
|
||||
import type { SecuritySolutionPluginRouter } from '../../../types';
|
||||
import type { EndpointAppContext } from '../../types';
|
||||
import { withEndpointAuthz } from '../with_endpoint_authz';
|
||||
|
||||
/**
|
||||
* Registers the endpoint activity_log route
|
||||
* @deprecated
|
||||
* @removeBy 9.0.0
|
||||
*
|
||||
*/
|
||||
export function registerActionAuditLogRoutes(
|
||||
router: SecuritySolutionPluginRouter,
|
||||
endpointContext: EndpointAppContext
|
||||
) {
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: ENDPOINT_ACTION_LOG_ROUTE,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution'],
|
||||
},
|
||||
},
|
||||
options: { authRequired: true },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: EndpointActionLogRequestSchema,
|
||||
},
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canIsolateHost'] },
|
||||
endpointContext.logFactory.get('hostIsolationLogs'),
|
||||
auditLogRequestHandler(endpointContext)
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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 type { RequestHandler } from '@kbn/core/server';
|
||||
import type {
|
||||
EndpointActionLogRequestParams,
|
||||
EndpointActionLogRequestQuery,
|
||||
} from '../../../../common/api/endpoint';
|
||||
import type { SecuritySolutionRequestHandlerContext } from '../../../types';
|
||||
import { getAuditLogResponse } from '../../services/actions/actions_audit_log';
|
||||
import type { EndpointAppContext } from '../../types';
|
||||
|
||||
export const auditLogRequestHandler = (
|
||||
endpointContext: EndpointAppContext
|
||||
): RequestHandler<
|
||||
EndpointActionLogRequestParams,
|
||||
EndpointActionLogRequestQuery,
|
||||
unknown,
|
||||
SecuritySolutionRequestHandlerContext
|
||||
> => {
|
||||
const logger = endpointContext.logFactory.get('audit_log');
|
||||
|
||||
return async (context, req, res) => {
|
||||
const {
|
||||
params: { agent_id: elasticAgentId },
|
||||
query: { page, page_size: pageSize, start_date: startDate, end_date: endDate },
|
||||
} = req;
|
||||
|
||||
const body = await getAuditLogResponse({
|
||||
elasticAgentId,
|
||||
page,
|
||||
pageSize,
|
||||
startDate,
|
||||
endDate,
|
||||
context,
|
||||
logger,
|
||||
});
|
||||
return res.ok({
|
||||
body,
|
||||
});
|
||||
};
|
||||
};
|
|
@ -12,7 +12,6 @@ import type { SecuritySolutionPluginRouter } from '../../../types';
|
|||
import type { EndpointAppContext } from '../../types';
|
||||
import { registerActionStatusRoutes } from './status';
|
||||
import { registerActionStateRoutes } from './state';
|
||||
import { registerActionAuditLogRoutes } from './audit_log';
|
||||
import { registerActionListRoutes } from './list';
|
||||
import { registerResponseActionRoutes } from './response_actions';
|
||||
|
||||
|
@ -25,7 +24,6 @@ export function registerActionRoutes(
|
|||
) {
|
||||
registerActionStatusRoutes(router, endpointContext);
|
||||
registerActionStateRoutes(router, endpointContext, canEncrypt);
|
||||
registerActionAuditLogRoutes(router, endpointContext);
|
||||
registerActionListRoutes(router, endpointContext);
|
||||
registerActionDetailsRoutes(router, endpointContext);
|
||||
registerResponseActionRoutes(router, endpointContext);
|
||||
|
|
|
@ -28,12 +28,10 @@ import {
|
|||
EXECUTE_ROUTE,
|
||||
GET_FILE_ROUTE,
|
||||
GET_PROCESSES_ROUTE,
|
||||
ISOLATE_HOST_ROUTE,
|
||||
ISOLATE_HOST_ROUTE_V2,
|
||||
KILL_PROCESS_ROUTE,
|
||||
SCAN_ROUTE,
|
||||
SUSPEND_PROCESS_ROUTE,
|
||||
UNISOLATE_HOST_ROUTE,
|
||||
UNISOLATE_HOST_ROUTE_V2,
|
||||
UPLOAD_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
|
@ -245,28 +243,6 @@ describe('Response actions', () => {
|
|||
getActionDetailsByIdSpy.mockClear();
|
||||
});
|
||||
|
||||
it('correctly redirects legacy isolate to new route', async () => {
|
||||
await callRoute(ISOLATE_HOST_ROUTE, {
|
||||
body: { endpoint_ids: ['XYZ'] },
|
||||
version: '2023-10-31',
|
||||
});
|
||||
expect(mockResponse.custom).toBeCalled();
|
||||
const response = mockResponse.custom.mock.calls[0][0];
|
||||
expect(response.statusCode).toEqual(308);
|
||||
expect(response.headers?.location).toEqual(ISOLATE_HOST_ROUTE_V2);
|
||||
});
|
||||
|
||||
it('correctly redirects legacy release to new route', async () => {
|
||||
await callRoute(UNISOLATE_HOST_ROUTE, {
|
||||
body: { endpoint_ids: ['XYZ'] },
|
||||
version: '2023-10-31',
|
||||
});
|
||||
expect(mockResponse.custom).toBeCalled();
|
||||
const response = mockResponse.custom.mock.calls[0][0];
|
||||
expect(response.statusCode).toEqual(308);
|
||||
expect(response.headers?.location).toEqual(UNISOLATE_HOST_ROUTE_V2);
|
||||
});
|
||||
|
||||
it('succeeds when an endpoint ID is provided', async () => {
|
||||
await callRoute(ISOLATE_HOST_ROUTE_V2, {
|
||||
body: { endpoint_ids: ['XYZ'] },
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import type { RequestHandler } from '@kbn/core/server';
|
||||
import type { TypeOf } from '@kbn/config-schema';
|
||||
|
||||
import { responseActionsWithLegacyActionProperty } from '../../services/actions/constants';
|
||||
import { stringify } from '../../utils/stringify';
|
||||
|
@ -24,7 +23,6 @@ import {
|
|||
GetProcessesRouteRequestSchema,
|
||||
IsolateRouteRequestSchema,
|
||||
KillProcessRouteRequestSchema,
|
||||
type NoParametersRequestSchema,
|
||||
type ResponseActionGetFileRequestBody,
|
||||
type ResponseActionsRequestBody,
|
||||
type ScanActionRequestBody,
|
||||
|
@ -39,12 +37,10 @@ import {
|
|||
EXECUTE_ROUTE,
|
||||
GET_FILE_ROUTE,
|
||||
GET_PROCESSES_ROUTE,
|
||||
ISOLATE_HOST_ROUTE,
|
||||
ISOLATE_HOST_ROUTE_V2,
|
||||
KILL_PROCESS_ROUTE,
|
||||
SCAN_ROUTE,
|
||||
SUSPEND_PROCESS_ROUTE,
|
||||
UNISOLATE_HOST_ROUTE,
|
||||
UNISOLATE_HOST_ROUTE_V2,
|
||||
UPLOAD_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
|
@ -73,58 +69,6 @@ export function registerResponseActionRoutes(
|
|||
) {
|
||||
const logger = endpointContext.logFactory.get('hostIsolation');
|
||||
|
||||
/**
|
||||
* @deprecated use ISOLATE_HOST_ROUTE_V2 instead
|
||||
*/
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: ISOLATE_HOST_ROUTE,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution'],
|
||||
},
|
||||
},
|
||||
options: { authRequired: true },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: IsolateRouteRequestSchema,
|
||||
},
|
||||
},
|
||||
withEndpointAuthz({ all: ['canIsolateHost'] }, logger, redirectHandler(ISOLATE_HOST_ROUTE_V2))
|
||||
);
|
||||
|
||||
/**
|
||||
* @deprecated use RELEASE_HOST_ROUTE instead
|
||||
*/
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: UNISOLATE_HOST_ROUTE,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution'],
|
||||
},
|
||||
},
|
||||
options: { authRequired: true },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: UnisolateRouteRequestSchema,
|
||||
},
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canUnIsolateHost'] },
|
||||
logger,
|
||||
redirectHandler(UNISOLATE_HOST_ROUTE_V2)
|
||||
)
|
||||
);
|
||||
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
|
@ -475,20 +419,3 @@ async function handleActionCreation(
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
function redirectHandler(
|
||||
location: string
|
||||
): RequestHandler<
|
||||
unknown,
|
||||
unknown,
|
||||
TypeOf<typeof NoParametersRequestSchema.body>,
|
||||
SecuritySolutionRequestHandlerContext
|
||||
> {
|
||||
return async (context, _req, res) => {
|
||||
const basePath = (await context.securitySolution).getServerBasePath();
|
||||
return res.custom({
|
||||
statusCode: 308,
|
||||
headers: { location: `${basePath}${location}` },
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import {
|
|||
HOST_METADATA_GET_ROUTE,
|
||||
HOST_METADATA_LIST_ROUTE,
|
||||
METADATA_TRANSFORMS_STATUS_INTERNAL_ROUTE,
|
||||
METADATA_TRANSFORMS_STATUS_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
import { withEndpointAuthz } from '../with_endpoint_authz';
|
||||
|
||||
|
@ -95,31 +94,6 @@ export function registerEndpointRoutes(
|
|||
)
|
||||
);
|
||||
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: METADATA_TRANSFORMS_STATUS_ROUTE,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution'],
|
||||
},
|
||||
},
|
||||
options: { authRequired: true },
|
||||
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
|
||||
deprecated: true,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: false,
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canReadSecuritySolution'] },
|
||||
logger,
|
||||
getMetadataTransformStatsHandler(endpointAppContext, logger)
|
||||
)
|
||||
);
|
||||
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'internal',
|
||||
|
|
|
@ -7,12 +7,11 @@
|
|||
|
||||
import { EndpointAppContextService } from '../../endpoint_app_context_services';
|
||||
import {
|
||||
createMockEndpointAppContext,
|
||||
createMockEndpointAppContextServiceSetupContract,
|
||||
createMockEndpointAppContextServiceStartContract,
|
||||
createRouteHandlerContext,
|
||||
} from '../../mocks';
|
||||
import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler } from './handlers';
|
||||
import { getHostPolicyResponseHandler } from './handlers';
|
||||
import type { KibanaResponseFactory, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import {
|
||||
elasticsearchServiceMock,
|
||||
|
@ -23,8 +22,6 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
|||
import type { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types';
|
||||
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';
|
||||
import { requestContextMock } from '../../../lib/detection_engine/routes/__mocks__';
|
||||
import type { Agent } from '@kbn/fleet-plugin/common/types/models';
|
||||
import type { AgentClient } from '@kbn/fleet-plugin/server/services';
|
||||
import { get } from 'lodash';
|
||||
import type { ScopedClusterClientMock } from '@kbn/core-elasticsearch-client-server-mocks';
|
||||
import type { TypeOf } from '@kbn/config-schema';
|
||||
|
@ -127,141 +124,6 @@ describe('test policy response handler', () => {
|
|||
expect(getInternalFleetServicesSpy).toHaveBeenCalledWith('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('test agent policy summary handler', () => {
|
||||
let mockAgentClient: jest.Mocked<AgentClient>;
|
||||
|
||||
let agentListResult: {
|
||||
agents: Agent[];
|
||||
total: number;
|
||||
page: number;
|
||||
perPage: number;
|
||||
};
|
||||
|
||||
let emptyAgentListResult: {
|
||||
agents: Agent[];
|
||||
total: number;
|
||||
page: number;
|
||||
perPage: number;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockScopedClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
mockSavedObjectClient = savedObjectsClientMock.create();
|
||||
mockResponse = httpServerMock.createResponseFactory();
|
||||
endpointAppContextService = new EndpointAppContextService();
|
||||
emptyAgentListResult = {
|
||||
agents: [],
|
||||
total: 2,
|
||||
page: 1,
|
||||
perPage: 1,
|
||||
};
|
||||
|
||||
agentListResult = {
|
||||
agents: [
|
||||
{
|
||||
local_metadata: {
|
||||
elastic: {
|
||||
agent: {
|
||||
version: '8.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as Agent,
|
||||
{
|
||||
local_metadata: {
|
||||
elastic: {
|
||||
agent: {
|
||||
version: '8.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as Agent,
|
||||
{
|
||||
local_metadata: {
|
||||
elastic: {
|
||||
agent: {
|
||||
version: '8.1.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown as Agent,
|
||||
],
|
||||
total: 2,
|
||||
page: 1,
|
||||
perPage: 1,
|
||||
};
|
||||
endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract());
|
||||
endpointAppContextService.start({
|
||||
...createMockEndpointAppContextServiceStartContract(),
|
||||
});
|
||||
mockAgentClient = endpointAppContextService.getInternalFleetServices()
|
||||
.agent as jest.Mocked<AgentClient>;
|
||||
});
|
||||
|
||||
afterEach(() => endpointAppContextService.stop());
|
||||
|
||||
it('should return the summary of all the agent with the given policy name', async () => {
|
||||
mockAgentClient.listAgents
|
||||
.mockImplementation(() => Promise.resolve(emptyAgentListResult))
|
||||
.mockImplementationOnce(() => Promise.resolve(agentListResult));
|
||||
|
||||
const policySummarysHandler = getAgentPolicySummaryHandler({
|
||||
...createMockEndpointAppContext(),
|
||||
service: endpointAppContextService,
|
||||
});
|
||||
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
query: { policy_id: '41a1b470-221b-11eb-8fba-fb9c0d46ace3', package_name: 'endpoint' },
|
||||
});
|
||||
|
||||
await policySummarysHandler(
|
||||
requestContextMock.convertContext(
|
||||
createRouteHandlerContext(mockScopedClient, mockSavedObjectClient)
|
||||
),
|
||||
mockRequest,
|
||||
mockResponse
|
||||
);
|
||||
expect(mockResponse.ok).toBeCalled();
|
||||
expect(mockResponse.ok.mock.calls[0][0]?.body).toEqual({
|
||||
summary_response: {
|
||||
policy_id: '41a1b470-221b-11eb-8fba-fb9c0d46ace3',
|
||||
package: 'endpoint',
|
||||
versions_count: { '8.0.0': 2, '8.1.0': 1 },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the agent summary', async () => {
|
||||
mockAgentClient.listAgents
|
||||
.mockImplementationOnce(() => Promise.resolve(agentListResult))
|
||||
.mockImplementationOnce(() => Promise.resolve(emptyAgentListResult));
|
||||
|
||||
const agentPolicySummaryHandler = getAgentPolicySummaryHandler({
|
||||
...createMockEndpointAppContext(),
|
||||
service: endpointAppContextService,
|
||||
});
|
||||
|
||||
const mockRequest = httpServerMock.createKibanaRequest({
|
||||
query: { package_name: 'endpoint' },
|
||||
});
|
||||
|
||||
await agentPolicySummaryHandler(
|
||||
requestContextMock.convertContext(
|
||||
createRouteHandlerContext(mockScopedClient, mockSavedObjectClient)
|
||||
),
|
||||
mockRequest,
|
||||
mockResponse
|
||||
);
|
||||
expect(mockResponse.ok).toBeCalled();
|
||||
expect(mockResponse.ok.mock.calls[0][0]?.body).toEqual({
|
||||
summary_response: {
|
||||
package: 'endpoint',
|
||||
versions_count: { '8.0.0': 2, '8.1.0': 1 },
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,13 +10,8 @@ import type { TypeOf } from '@kbn/config-schema';
|
|||
import type { SecuritySolutionRequestHandlerContext } from '../../../types';
|
||||
import type { EndpointAppContextService } from '../../endpoint_app_context_services';
|
||||
import { errorHandler } from '../error_handler';
|
||||
import type {
|
||||
GetPolicyResponseSchema,
|
||||
GetAgentPolicySummaryRequestSchema,
|
||||
} from '../../../../common/api/endpoint';
|
||||
import type { EndpointAppContext } from '../../types';
|
||||
import { getAgentPolicySummary, getPolicyResponseByAgentId } from './service';
|
||||
import type { GetAgentSummaryResponse } from '../../../../common/endpoint/types';
|
||||
import type { GetPolicyResponseSchema } from '../../../../common/api/endpoint';
|
||||
import { getPolicyResponseByAgentId } from './service';
|
||||
import { NotFoundError } from '../../errors';
|
||||
|
||||
export const getHostPolicyResponseHandler = function (
|
||||
|
@ -50,30 +45,3 @@ export const getHostPolicyResponseHandler = function (
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const getAgentPolicySummaryHandler = function (
|
||||
endpointAppContext: EndpointAppContext
|
||||
): RequestHandler<undefined, TypeOf<typeof GetAgentPolicySummaryRequestSchema.query>, undefined> {
|
||||
return async (_, request, response) => {
|
||||
const result = await getAgentPolicySummary(
|
||||
endpointAppContext,
|
||||
request,
|
||||
request.query.package_name,
|
||||
request.query?.policy_id || undefined
|
||||
);
|
||||
const responseBody = {
|
||||
package: request.query.package_name,
|
||||
versions_count: { ...result },
|
||||
};
|
||||
|
||||
const body: GetAgentSummaryResponse = {
|
||||
summary_response: request.query?.policy_id
|
||||
? { ...responseBody, ...{ policy_id: request.query?.policy_id } }
|
||||
: responseBody,
|
||||
};
|
||||
|
||||
return response.ok({
|
||||
body,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,16 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
GetPolicyResponseSchema,
|
||||
GetAgentPolicySummaryRequestSchema,
|
||||
} from '../../../../common/api/endpoint';
|
||||
import { GetPolicyResponseSchema } from '../../../../common/api/endpoint';
|
||||
import type { EndpointAppContext } from '../../types';
|
||||
import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler } from './handlers';
|
||||
import {
|
||||
AGENT_POLICY_SUMMARY_ROUTE,
|
||||
BASE_POLICY_RESPONSE_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
import { getHostPolicyResponseHandler } from './handlers';
|
||||
import { BASE_POLICY_RESPONSE_ROUTE } from '../../../../common/endpoint/constants';
|
||||
import { withEndpointAuthz } from '../with_endpoint_authz';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../types';
|
||||
|
||||
|
@ -45,29 +39,4 @@ export function registerPolicyRoutes(
|
|||
getHostPolicyResponseHandler(endpointAppContext.service)
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @removeBy 9.0.0
|
||||
*
|
||||
*/
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: AGENT_POLICY_SUMMARY_ROUTE,
|
||||
options: { authRequired: true },
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: GetAgentPolicySummaryRequestSchema,
|
||||
},
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ all: ['canAccessEndpointManagement'] },
|
||||
logger,
|
||||
getAgentPolicySummaryHandler(endpointAppContext)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -68,38 +68,6 @@ export async function getPolicyResponseByAgentId(
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const transformAgentVersionMap = (versionMap: Map<string, number>): { [key: string]: number } => {
|
||||
const data: { [key: string]: number } = {};
|
||||
versionMap.forEach((value, key) => {
|
||||
data[key] = value;
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
export async function getAgentPolicySummary(
|
||||
endpointAppContext: EndpointAppContext,
|
||||
request: KibanaRequest,
|
||||
packageName: string,
|
||||
policyId?: string,
|
||||
pageSize: number = 1000
|
||||
): Promise<{ [key: string]: number }> {
|
||||
const agentQuery = `packages:"${packageName}"`;
|
||||
if (policyId) {
|
||||
return transformAgentVersionMap(
|
||||
await agentVersionsMap(
|
||||
endpointAppContext,
|
||||
request,
|
||||
`${agentQuery} AND policy_id:${policyId}`,
|
||||
pageSize
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return transformAgentVersionMap(
|
||||
await agentVersionsMap(endpointAppContext, request, agentQuery, pageSize)
|
||||
);
|
||||
}
|
||||
|
||||
export async function agentVersionsMap(
|
||||
endpointAppContext: EndpointAppContext,
|
||||
request: KibanaRequest,
|
||||
|
|
|
@ -24,7 +24,6 @@ import type { EndpointAppContext } from '../../types';
|
|||
import {
|
||||
eventsIndexPattern,
|
||||
SUGGESTIONS_INTERNAL_ROUTE,
|
||||
SUGGESTIONS_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
import { withEndpointAuthz } from '../with_endpoint_authz';
|
||||
import { errorHandler } from '../error_handler';
|
||||
|
@ -38,33 +37,6 @@ export function registerEndpointSuggestionsRoutes(
|
|||
config$: Observable<ConfigSchema>,
|
||||
endpointContext: EndpointAppContext
|
||||
) {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: SUGGESTIONS_ROUTE,
|
||||
security: {
|
||||
authz: {
|
||||
requiredPrivileges: ['securitySolution'],
|
||||
},
|
||||
},
|
||||
options: { authRequired: true },
|
||||
// @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo}
|
||||
deprecated: true,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: EndpointSuggestionsSchema,
|
||||
},
|
||||
},
|
||||
withEndpointAuthz(
|
||||
{ any: ['canWriteEventFilters'] },
|
||||
endpointContext.logFactory.get('endpointSuggestions'),
|
||||
getEndpointSuggestionsRequestHandler(config$, getLogger(endpointContext))
|
||||
)
|
||||
);
|
||||
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'internal',
|
||||
|
|
|
@ -1,288 +0,0 @@
|
|||
/*
|
||||
* 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 type { Logger } from '@kbn/core/server';
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { TransportResult } from '@elastic/elasticsearch';
|
||||
import { AGENT_ACTIONS_INDEX, AGENT_ACTIONS_RESULTS_INDEX } from '@kbn/fleet-plugin/common';
|
||||
import {
|
||||
ENDPOINT_ACTION_RESPONSES_INDEX_PATTERN,
|
||||
ENDPOINT_ACTIONS_DS,
|
||||
ENDPOINT_ACTIONS_INDEX,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
import type { SecuritySolutionRequestHandlerContext } from '../../../types';
|
||||
import type {
|
||||
ActivityLog,
|
||||
ActivityLogEntry,
|
||||
EndpointAction,
|
||||
EndpointActionResponse,
|
||||
LogsEndpointAction,
|
||||
LogsEndpointActionResponse,
|
||||
} from '../../../../common/endpoint/types';
|
||||
import { doesLogsEndpointActionsIndexExist } from '../../utils';
|
||||
|
||||
import {
|
||||
categorizeActionResults,
|
||||
categorizeResponseResults,
|
||||
getDateFilters,
|
||||
getUniqueLogData,
|
||||
} from './utils';
|
||||
import { ACTION_REQUEST_INDICES, ACTION_RESPONSE_INDICES } from './constants';
|
||||
|
||||
const queryOptions = {
|
||||
headers: {
|
||||
'X-elastic-product-origin': 'fleet',
|
||||
},
|
||||
ignore: [404],
|
||||
};
|
||||
|
||||
/**
|
||||
* Used only for the deprecated `/api/endpoint/action_log/{agent_id}` legacy API route
|
||||
*
|
||||
* Use newer response action services instead
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const getAuditLogResponse = async ({
|
||||
elasticAgentId,
|
||||
page,
|
||||
pageSize,
|
||||
startDate,
|
||||
endDate,
|
||||
context,
|
||||
logger,
|
||||
}: {
|
||||
elasticAgentId: string;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
context: SecuritySolutionRequestHandlerContext;
|
||||
logger: Logger;
|
||||
}): Promise<ActivityLog> => {
|
||||
const size = Math.floor(pageSize / 2);
|
||||
const from = page <= 1 ? 0 : page * size - size + 1;
|
||||
|
||||
const data = await getActivityLog({
|
||||
context,
|
||||
from,
|
||||
size,
|
||||
startDate,
|
||||
endDate,
|
||||
elasticAgentId,
|
||||
logger,
|
||||
});
|
||||
|
||||
return {
|
||||
page,
|
||||
pageSize,
|
||||
startDate,
|
||||
endDate,
|
||||
data,
|
||||
};
|
||||
};
|
||||
|
||||
const getActivityLog = async ({
|
||||
context,
|
||||
size,
|
||||
from,
|
||||
startDate,
|
||||
endDate,
|
||||
elasticAgentId,
|
||||
logger,
|
||||
}: {
|
||||
context: SecuritySolutionRequestHandlerContext;
|
||||
elasticAgentId: string;
|
||||
size: number;
|
||||
from: number;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
logger: Logger;
|
||||
}): Promise<ActivityLogEntry[]> => {
|
||||
let actionsResult: TransportResult<estypes.SearchResponse<unknown>, unknown>;
|
||||
let responsesResult: TransportResult<estypes.SearchResponse<unknown>, unknown>;
|
||||
|
||||
try {
|
||||
// fetch actions with matching agent_id
|
||||
const { actionIds, actionRequests } = await getActionRequestsResult({
|
||||
context,
|
||||
logger,
|
||||
elasticAgentId,
|
||||
startDate,
|
||||
endDate,
|
||||
size,
|
||||
from,
|
||||
});
|
||||
actionsResult = actionRequests;
|
||||
|
||||
// fetch responses with matching unique set of `action_id`s
|
||||
responsesResult = await getActionResponsesResult({
|
||||
actionIds: [...new Set(actionIds)], // de-dupe `action_id`s
|
||||
context,
|
||||
logger,
|
||||
elasticAgentId,
|
||||
startDate,
|
||||
endDate,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
if (actionsResult?.statusCode !== 200) {
|
||||
logger.error(`Error fetching actions log for agent_id ${elasticAgentId}`);
|
||||
throw new Error(`Error fetching actions log for agent_id ${elasticAgentId}`);
|
||||
}
|
||||
|
||||
// label record as `action`, `fleetAction`
|
||||
const responses = categorizeResponseResults({
|
||||
results: responsesResult?.body?.hits?.hits as Array<
|
||||
estypes.SearchHit<EndpointActionResponse | LogsEndpointActionResponse>
|
||||
>,
|
||||
});
|
||||
|
||||
// label record as `response`, `fleetResponse`
|
||||
const actions = categorizeActionResults({
|
||||
results: actionsResult?.body?.hits?.hits as Array<
|
||||
estypes.SearchHit<EndpointAction | LogsEndpointAction>
|
||||
>,
|
||||
});
|
||||
|
||||
// filter out the duplicate endpoint actions that also have fleetActions
|
||||
// include endpoint actions that have no fleet actions
|
||||
const uniqueLogData = getUniqueLogData([...responses, ...actions]);
|
||||
|
||||
// sort by @timestamp in desc order, newest first
|
||||
const sortedData = getTimeSortedData(uniqueLogData);
|
||||
|
||||
return sortedData;
|
||||
};
|
||||
|
||||
const getTimeSortedData = (data: ActivityLog['data']): ActivityLog['data'] => {
|
||||
return data.sort((a, b) =>
|
||||
new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1
|
||||
);
|
||||
};
|
||||
|
||||
const getActionRequestsResult = async ({
|
||||
context,
|
||||
logger,
|
||||
elasticAgentId,
|
||||
startDate,
|
||||
endDate,
|
||||
size,
|
||||
from,
|
||||
}: {
|
||||
context: SecuritySolutionRequestHandlerContext;
|
||||
logger: Logger;
|
||||
elasticAgentId: string;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
size: number;
|
||||
from: number;
|
||||
}): Promise<{
|
||||
actionIds: string[];
|
||||
actionRequests: TransportResult<estypes.SearchResponse<unknown>, unknown>;
|
||||
}> => {
|
||||
const dateFilters = getDateFilters({ startDate, endDate });
|
||||
const baseActionFilters = [
|
||||
{ term: { agents: elasticAgentId } },
|
||||
{ term: { input_type: 'endpoint' } },
|
||||
{ term: { type: 'INPUT_ACTION' } },
|
||||
];
|
||||
const actionsFilters = [...baseActionFilters, ...dateFilters];
|
||||
const esClient = (await context.core).elasticsearch.client.asInternalUser;
|
||||
|
||||
const hasLogsEndpointActionsIndex = await doesLogsEndpointActionsIndexExist({
|
||||
esClient,
|
||||
logger,
|
||||
indexName: ENDPOINT_ACTIONS_INDEX,
|
||||
});
|
||||
|
||||
const actionsSearchQuery: estypes.SearchRequest = {
|
||||
index: hasLogsEndpointActionsIndex ? ACTION_REQUEST_INDICES : AGENT_ACTIONS_INDEX,
|
||||
size,
|
||||
from,
|
||||
query: {
|
||||
bool: {
|
||||
filter: actionsFilters,
|
||||
},
|
||||
},
|
||||
sort: [
|
||||
{
|
||||
'@timestamp': {
|
||||
order: 'desc',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let actionRequests: TransportResult<estypes.SearchResponse<unknown>, unknown>;
|
||||
try {
|
||||
actionRequests = await esClient.search(actionsSearchQuery, { ...queryOptions, meta: true });
|
||||
const actionIds = actionRequests?.body?.hits?.hits?.map((e) => {
|
||||
return e._index.includes(ENDPOINT_ACTIONS_DS)
|
||||
? (e._source as LogsEndpointAction).EndpointActions.action_id
|
||||
: (e._source as EndpointAction).action_id;
|
||||
});
|
||||
|
||||
return { actionIds, actionRequests };
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const getActionResponsesResult = async ({
|
||||
context,
|
||||
logger,
|
||||
elasticAgentId,
|
||||
actionIds,
|
||||
startDate,
|
||||
endDate,
|
||||
}: {
|
||||
context: SecuritySolutionRequestHandlerContext;
|
||||
logger: Logger;
|
||||
elasticAgentId: string;
|
||||
actionIds: string[];
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
}): Promise<TransportResult<estypes.SearchResponse<unknown>, unknown>> => {
|
||||
const dateFilters = getDateFilters({ startDate, endDate });
|
||||
const baseResponsesFilter = [
|
||||
{ term: { agent_id: elasticAgentId } },
|
||||
{ terms: { action_id: actionIds } },
|
||||
];
|
||||
const responsesFilters = [...baseResponsesFilter, ...dateFilters];
|
||||
const esClient = (await context.core).elasticsearch.client.asInternalUser;
|
||||
|
||||
const hasLogsEndpointActionResponsesIndex = await doesLogsEndpointActionsIndexExist({
|
||||
esClient,
|
||||
logger,
|
||||
indexName: ENDPOINT_ACTION_RESPONSES_INDEX_PATTERN,
|
||||
});
|
||||
|
||||
const responsesSearchQuery: estypes.SearchRequest = {
|
||||
index: hasLogsEndpointActionResponsesIndex
|
||||
? ACTION_RESPONSE_INDICES
|
||||
: AGENT_ACTIONS_RESULTS_INDEX,
|
||||
size: 1000,
|
||||
query: {
|
||||
bool: {
|
||||
filter: responsesFilters,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let actionResponses: TransportResult<estypes.SearchResponse<unknown>, unknown>;
|
||||
try {
|
||||
actionResponses = await esClient.search(responsesSearchQuery, { ...queryOptions, meta: true });
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
return actionResponses;
|
||||
};
|
|
@ -56,12 +56,10 @@ import { EndpointGetActionsStatusRequestQueryInput } from '@kbn/security-solutio
|
|||
import { EndpointGetFileActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/get_file/get_file.gen';
|
||||
import { EndpointGetProcessesActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen';
|
||||
import { EndpointIsolateActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/isolate/isolate.gen';
|
||||
import { EndpointIsolateRedirectRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/isolate/deprecated_isolate.gen';
|
||||
import { EndpointKillProcessActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen';
|
||||
import { EndpointScanActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/scan/scan.gen';
|
||||
import { EndpointSuspendProcessActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen';
|
||||
import { EndpointUnisolateActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen';
|
||||
import { EndpointUnisolateRedirectRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/unisolate/deprecated_unisolate.gen';
|
||||
import { EndpointUploadActionRequestBodyInput } from '@kbn/security-solution-plugin/common/api/endpoint/actions/response_actions/upload/upload.gen';
|
||||
import {
|
||||
ExportRulesRequestQueryInput,
|
||||
|
@ -74,7 +72,6 @@ import {
|
|||
import { FinalizeAlertsMigrationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/signals_migration/finalize_signals_migration/finalize_signals_migration.gen';
|
||||
import { FindAssetCriticalityRecordsRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/asset_criticality/list_asset_criticality.gen';
|
||||
import { FindRulesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen';
|
||||
import { GetAgentPolicySummaryRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/deprecated_agent_policy_summary.gen';
|
||||
import { GetAssetCriticalityRecordRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/asset_criticality/get_asset_criticality.gen';
|
||||
import { GetDraftTimelinesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen';
|
||||
import { GetEndpointMetadataListRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/metadata/get_metadata.gen';
|
||||
|
@ -614,20 +611,6 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Isolate an endpoint from the network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/isolate`.
|
||||
|
||||
*/
|
||||
endpointIsolateRedirect(props: EndpointIsolateRedirectProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.post(routeWithNamespace('/api/endpoint/isolate', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Terminate a running process on an endpoint.
|
||||
*/
|
||||
|
@ -678,23 +661,6 @@ If a record already exists for the specified entity, that record is overwritten
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Release an isolated endpoint, allowing it to rejoin a network.
|
||||
> info
|
||||
> This URL will return a 308 permanent redirect to `POST <kibana host>:<port>/api/endpoint/action/unisolate`.
|
||||
|
||||
*/
|
||||
endpointUnisolateRedirect(
|
||||
props: EndpointUnisolateRedirectProps,
|
||||
kibanaSpace: string = 'default'
|
||||
) {
|
||||
return supertest
|
||||
.post(routeWithNamespace('/api/endpoint/unisolate', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Upload a file to an endpoint.
|
||||
*/
|
||||
|
@ -781,14 +747,6 @@ finalize it.
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
getAgentPolicySummary(props: GetAgentPolicySummaryProps, kibanaSpace: string = 'default') {
|
||||
return supertest
|
||||
.get(routeWithNamespace('/api/endpoint/policy/summaries', kibanaSpace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
/**
|
||||
* Retrieves the rule migrations stats for all migrations stored in the system
|
||||
*/
|
||||
|
@ -843,7 +801,7 @@ finalize it.
|
|||
return supertest
|
||||
.post(
|
||||
routeWithNamespace(
|
||||
replaceParams('/api/endpoint/suggestions/{suggestion_type}', props.params),
|
||||
replaceParams('/internal/api/endpoint/suggestions/{suggestion_type}', props.params),
|
||||
kibanaSpace
|
||||
)
|
||||
)
|
||||
|
@ -1535,9 +1493,6 @@ export interface EndpointGetProcessesActionProps {
|
|||
export interface EndpointIsolateActionProps {
|
||||
body: EndpointIsolateActionRequestBodyInput;
|
||||
}
|
||||
export interface EndpointIsolateRedirectProps {
|
||||
body: EndpointIsolateRedirectRequestBodyInput;
|
||||
}
|
||||
export interface EndpointKillProcessActionProps {
|
||||
body: EndpointKillProcessActionRequestBodyInput;
|
||||
}
|
||||
|
@ -1550,9 +1505,6 @@ export interface EndpointSuspendProcessActionProps {
|
|||
export interface EndpointUnisolateActionProps {
|
||||
body: EndpointUnisolateActionRequestBodyInput;
|
||||
}
|
||||
export interface EndpointUnisolateRedirectProps {
|
||||
body: EndpointUnisolateRedirectRequestBodyInput;
|
||||
}
|
||||
export interface EndpointUploadActionProps {
|
||||
body: EndpointUploadActionRequestBodyInput;
|
||||
}
|
||||
|
@ -1573,9 +1525,6 @@ export interface FindAssetCriticalityRecordsProps {
|
|||
export interface FindRulesProps {
|
||||
query: FindRulesRequestQueryInput;
|
||||
}
|
||||
export interface GetAgentPolicySummaryProps {
|
||||
query: GetAgentPolicySummaryRequestQueryInput;
|
||||
}
|
||||
export interface GetAssetCriticalityRecordProps {
|
||||
query: GetAssetCriticalityRecordRequestQueryInput;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import { wrapErrorAndRejectPromise } from '@kbn/security-solution-plugin/common/
|
|||
import {
|
||||
ACTION_DETAILS_ROUTE,
|
||||
ACTION_STATUS_ROUTE,
|
||||
AGENT_POLICY_SUMMARY_ROUTE,
|
||||
BASE_ENDPOINT_ACTION_ROUTE,
|
||||
BASE_POLICY_RESPONSE_ROUTE,
|
||||
EXECUTE_ROUTE,
|
||||
|
@ -145,15 +144,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
},
|
||||
];
|
||||
|
||||
const superuserApiList: ApiCallsInterface[] = [
|
||||
{
|
||||
method: 'get',
|
||||
path: `${AGENT_POLICY_SUMMARY_ROUTE}?package_name=endpoint`,
|
||||
version: '2023-10-31',
|
||||
body: undefined,
|
||||
},
|
||||
];
|
||||
|
||||
function replacePathIds(path: string) {
|
||||
return path.replace('{action_id}', actionId).replace('{agentId}', agentId);
|
||||
}
|
||||
|
@ -188,7 +178,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
...canReadActionsLogManagementApiList,
|
||||
...canIsolateHostApiList,
|
||||
...canWriteProcessOperationsApiList,
|
||||
...superuserApiList,
|
||||
]) {
|
||||
it(`should return 403 when [${apiListItem.method.toUpperCase()} ${
|
||||
apiListItem.path
|
||||
|
@ -224,11 +213,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
describe('with minimal_all and actions_log_management_read', () => {
|
||||
for (const apiListItem of [
|
||||
...canIsolateHostApiList,
|
||||
...canWriteProcessOperationsApiList,
|
||||
...superuserApiList,
|
||||
]) {
|
||||
for (const apiListItem of [...canIsolateHostApiList, ...canWriteProcessOperationsApiList]) {
|
||||
it(`should return 403 when [${apiListItem.method.toUpperCase()} ${
|
||||
apiListItem.path
|
||||
}]`, async () => {
|
||||
|
@ -265,24 +250,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
describe('with minimal_all, actions_log_management_all, host_isolation_all, and process_operations_all', () => {
|
||||
for (const apiListItem of superuserApiList) {
|
||||
it(`should return 403 when [${apiListItem.method.toUpperCase()} ${
|
||||
apiListItem.path
|
||||
}]`, async () => {
|
||||
await endpointOperationsAnalystSupertest[apiListItem.method](
|
||||
replacePathIds(apiListItem.path)
|
||||
)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send(getBodyPayload(apiListItem))
|
||||
.expect(403, {
|
||||
statusCode: 403,
|
||||
error: 'Forbidden',
|
||||
message: 'Endpoint authorization failure',
|
||||
})
|
||||
.catch(wrapErrorAndRejectPromise);
|
||||
});
|
||||
}
|
||||
|
||||
for (const apiListItem of [
|
||||
...canReadSecuritySolutionApiList,
|
||||
...canReadActionsLogManagementApiList,
|
||||
|
@ -330,17 +297,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
.expect(200);
|
||||
});
|
||||
}
|
||||
for (const apiListItem of [...superuserApiList]) {
|
||||
// Admin user has no access to these APIs
|
||||
it(`@skipInServerless should return 200 when [${apiListItem.method.toUpperCase()} ${
|
||||
apiListItem.path
|
||||
}]`, async () => {
|
||||
await adminSupertest[apiListItem.method](replacePathIds(apiListItem.path))
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send(getBodyPayload(apiListItem))
|
||||
.expect(200);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue