From ed740633937850716f4fcb6f3488c8d0d63dec2b Mon Sep 17 00:00:00 2001
From: Julia Bardi
Date: Tue, 2 Apr 2024 14:39:53 +0200
Subject: [PATCH 1/4] added CPU metrics to request diagnostics
---
.../fleet/common/types/rest_spec/agent.ts | 11 ++
.../components/agent_diagnostics/index.tsx | 134 ++++++++----------
.../agent_request_diagnostics_modal/index.tsx | 18 ++-
.../fleet/public/hooks/use_request/agents.ts | 8 +-
.../agent/request_diagnostics_handler.test.ts | 5 +-
.../agent/request_diagnostics_handler.ts | 9 +-
.../services/agents/request_diagnostics.ts | 17 ++-
.../request_diagnostics_action_runner.ts | 6 +
.../fleet/server/types/rest_spec/agent.ts | 10 ++
9 files changed, 134 insertions(+), 84 deletions(-)
diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
index 07553dbc21acf..3e5244bf67353 100644
--- a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
+++ b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts
@@ -152,6 +152,16 @@ export interface PostBulkAgentReassignRequest {
};
}
+export enum RequestDiagnosticsAdditionalMetrics {
+ 'CPU' = 'CPU',
+}
+
+export interface PostRequestDiagnosticsRequest {
+ body: {
+ additional_metrics: RequestDiagnosticsAdditionalMetrics[];
+ };
+}
+
export type PostRequestDiagnosticsResponse = BulkAgentAction;
export type PostBulkRequestDiagnosticsResponse = BulkAgentAction;
@@ -159,6 +169,7 @@ export interface PostRequestBulkDiagnosticsRequest {
body: {
agents: string[] | string;
batchSize?: number;
+ additional_metrics: RequestDiagnosticsAdditionalMetrics[];
};
}
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
index c16066b0e771b..e1079fea1fd4a 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
@@ -6,6 +6,7 @@
*/
import type { EuiTableFieldDataColumnType } from '@elastic/eui';
+import { EuiPortal } from '@elastic/eui';
import { EuiToolTip } from '@elastic/eui';
import {
EuiBasicTable,
@@ -30,14 +31,9 @@ import {
MINIMUM_DIAGNOSTICS_AGENT_VERSION,
} from '../../../../../../../../common/services';
-import {
- sendGetAgentUploads,
- sendPostRequestDiagnostics,
- useAuthz,
- useLink,
- useStartServices,
-} from '../../../../../hooks';
+import { sendGetAgentUploads, useAuthz, useLink, useStartServices } from '../../../../../hooks';
import type { AgentDiagnostics, Agent } from '../../../../../../../../common/types/models';
+import { AgentRequestDiagnosticsModal } from '../../../components/agent_request_diagnostics_modal';
const FlexStartEuiFlexItem = styled(EuiFlexItem)`
align-self: flex-start;
@@ -60,6 +56,7 @@ export const AgentDiagnosticsTab: React.FunctionComponent
const [diagnosticsEntries, setDiagnosticEntries] = useState([]);
const [prevDiagnosticsEntries, setPrevDiagnosticEntries] = useState([]);
const [loadInterval, setLoadInterval] = useState(10000);
+ const [isRequestDiagnosticsModalOpen, setIsRequestDiagnosticsModalOpen] = useState(false);
const loadData = useCallback(async () => {
try {
@@ -194,93 +191,80 @@ export const AgentDiagnosticsTab: React.FunctionComponent
},
];
- async function onSubmit() {
- try {
- setIsSubmitting(true);
- const { error } = await sendPostRequestDiagnostics(agent.id);
- if (error) {
- throw error;
- }
- setIsSubmitting(false);
- const successMessage = i18n.translate(
- 'xpack.fleet.requestDiagnostics.successSingleNotificationTitle',
- {
- defaultMessage: 'Request diagnostics submitted',
- }
- );
- notifications.toasts.addSuccess(successMessage);
- loadData();
- } catch (error) {
- setIsSubmitting(false);
- notifications.toasts.addError(error, {
- title: i18n.translate('xpack.fleet.requestDiagnostics.fatalErrorNotificationTitle', {
- defaultMessage:
- 'Error requesting diagnostics {count, plural, one {agent} other {agents}}',
- values: { count: 1 },
- }),
- });
- }
- }
-
const requestDiagnosticsButton = (
{
+ setIsRequestDiagnosticsModalOpen(true);
+ }}
disabled={
isSubmitting || !isAgentRequestDiagnosticsSupported(agent) || !authz.fleet.readAgents
}
>
);
return (
-
-
-
- }
- >
-
+ {isRequestDiagnosticsModalOpen && (
+
+ {
+ setIsRequestDiagnosticsModalOpen(false);
+ }}
/>
-
-
-
- {isAgentRequestDiagnosticsSupported(agent) ? (
- requestDiagnosticsButton
- ) : (
-
+ )}
+
+
+
}
>
- {requestDiagnosticsButton}
-
- )}
-
-
- {isLoading ? (
-
- ) : (
- items={diagnosticsEntries} columns={columns} />
- )}
-
-
+
+
+
+
+ {isAgentRequestDiagnosticsSupported(agent) ? (
+ requestDiagnosticsButton
+ ) : (
+
+ }
+ >
+ {requestDiagnosticsButton}
+
+ )}
+
+
+ {isLoading ? (
+
+ ) : (
+ items={diagnosticsEntries} columns={columns} />
+ )}
+
+
+ >
);
};
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
index 0d3ccbd804e52..75b335076195c 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
@@ -8,9 +8,10 @@
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
-import { EuiConfirmModal } from '@elastic/eui';
+import { EuiCheckbox, EuiConfirmModal } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
+import { RequestDiagnosticsAdditionalMetrics } from '../../../../../../../common/types';
import type { Agent } from '../../../../types';
import {
sendPostRequestDiagnostics,
@@ -35,15 +36,20 @@ export const AgentRequestDiagnosticsModal: React.FunctionComponent = ({
const isSingleAgent = Array.isArray(agents) && agents.length === 1;
const { getPath } = useLink();
const history = useHistory();
+ const [cpuMetricsEnabled, setCPUMetricsEnabled] = useState(false);
async function onSubmit() {
try {
setIsSubmitting(true);
+ const additionalMetrics = cpuMetricsEnabled ? [RequestDiagnosticsAdditionalMetrics.CPU] : [];
const { error } = isSingleAgent
- ? await sendPostRequestDiagnostics((agents[0] as Agent).id)
+ ? await sendPostRequestDiagnostics((agents[0] as Agent).id, {
+ additional_metrics: additionalMetrics,
+ })
: await sendPostBulkRequestDiagnostics({
agents: typeof agents === 'string' ? agents : agents.map((agent) => agent.id),
+ additional_metrics: additionalMetrics,
});
if (error) {
throw error;
@@ -122,6 +128,14 @@ export const AgentRequestDiagnosticsModal: React.FunctionComponent = ({
defaultMessage="Diagnostics files are stored in Elasticsearch, and as such can incur storage costs."
/>
+
+ setCPUMetricsEnabled(!cpuMetricsEnabled)}
+ />
+
);
};
diff --git a/x-pack/plugins/fleet/public/hooks/use_request/agents.ts b/x-pack/plugins/fleet/public/hooks/use_request/agents.ts
index 70576d65ef575..e83243b9efa4d 100644
--- a/x-pack/plugins/fleet/public/hooks/use_request/agents.ts
+++ b/x-pack/plugins/fleet/public/hooks/use_request/agents.ts
@@ -14,6 +14,7 @@ import type {
PostBulkRequestDiagnosticsResponse,
PostBulkUpdateAgentTagsRequest,
PostRequestBulkDiagnosticsRequest,
+ PostRequestDiagnosticsRequest,
PostRequestDiagnosticsResponse,
UpdateAgentRequest,
} from '../../../common/types';
@@ -206,10 +207,15 @@ export function sendPostAgentUpgrade(
});
}
-export function sendPostRequestDiagnostics(agentId: string, options?: RequestOptions) {
+export function sendPostRequestDiagnostics(
+ agentId: string,
+ body: PostRequestDiagnosticsRequest['body'],
+ options?: RequestOptions
+) {
return sendRequest({
path: agentRouteService.getRequestDiagnosticsPath(agentId),
method: 'post',
+ body,
version: API_VERSIONS.public.v1,
...options,
});
diff --git a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.test.ts b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.test.ts
index 4442d7694d4bb..77efd46704366 100644
--- a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.test.ts
+++ b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.test.ts
@@ -50,7 +50,10 @@ describe('request diagnostics handler', () => {
},
},
} as unknown as RequestHandlerContext;
- mockRequest = httpServerMock.createKibanaRequest({ params: { agentId: 'agent1' } });
+ mockRequest = httpServerMock.createKibanaRequest({
+ params: { agentId: 'agent1' },
+ body: { additional_metrics: ['CPU'] },
+ });
});
it('should return ok if agent supports request diagnostics', async () => {
diff --git a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
index d4598101580ef..f82bc8fda927c 100644
--- a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
+++ b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
@@ -21,7 +21,7 @@ import { getAgentById } from '../../services/agents';
export const requestDiagnosticsHandler: RequestHandler<
TypeOf,
undefined,
- undefined
+ TypeOf
> = async (context, request, response) => {
const coreContext = await context.core;
const esClient = coreContext.elasticsearch.client.asInternalUser;
@@ -38,7 +38,11 @@ export const requestDiagnosticsHandler: RequestHandler<
});
}
- const result = await AgentService.requestDiagnostics(esClient, request.params.agentId);
+ const result = await AgentService.requestDiagnostics(
+ esClient,
+ request.params.agentId,
+ request.body.additional_metrics
+ );
return response.ok({ body: { actionId: result.actionId } });
} catch (error) {
@@ -61,6 +65,7 @@ export const bulkRequestDiagnosticsHandler: RequestHandler<
const result = await AgentService.bulkRequestDiagnostics(esClient, soClient, {
...agentOptions,
batchSize: request.body.batchSize,
+ additionalMetrics: request.body.additional_metrics,
});
return response.ok({ body: { actionId: result.actionId } });
diff --git a/x-pack/plugins/fleet/server/services/agents/request_diagnostics.ts b/x-pack/plugins/fleet/server/services/agents/request_diagnostics.ts
index 51b56d0e0007e..e2ed7e7ae8f1f 100644
--- a/x-pack/plugins/fleet/server/services/agents/request_diagnostics.ts
+++ b/x-pack/plugins/fleet/server/services/agents/request_diagnostics.ts
@@ -7,6 +7,8 @@
import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
+import type { RequestDiagnosticsAdditionalMetrics } from '../../../common/types';
+
import { SO_SEARCH_LIMIT } from '../../constants';
import type { GetAgentsOptions } from '.';
@@ -22,13 +24,17 @@ const REQUEST_DIAGNOSTICS_TIMEOUT_MS = 3 * 60 * 1000; // 3 hours;
export async function requestDiagnostics(
esClient: ElasticsearchClient,
- agentId: string
+ agentId: string,
+ additionalMetrics?: RequestDiagnosticsAdditionalMetrics[]
): Promise<{ actionId: string }> {
const response = await createAgentAction(esClient, {
agents: [agentId],
created_at: new Date().toISOString(),
type: 'REQUEST_DIAGNOSTICS',
expiration: new Date(Date.now() + REQUEST_DIAGNOSTICS_TIMEOUT_MS).toISOString(),
+ data: {
+ additional_metrics: additionalMetrics,
+ },
});
return { actionId: response.id };
}
@@ -38,11 +44,14 @@ export async function bulkRequestDiagnostics(
soClient: SavedObjectsClientContract,
options: GetAgentsOptions & {
batchSize?: number;
+ additionalMetrics?: RequestDiagnosticsAdditionalMetrics[];
}
): Promise<{ actionId: string }> {
if ('agentIds' in options) {
const givenAgents = await getAgents(esClient, soClient, options);
- return await requestDiagnosticsBatch(esClient, givenAgents, {});
+ return await requestDiagnosticsBatch(esClient, givenAgents, {
+ additionalMetrics: options.additionalMetrics,
+ });
}
const batchSize = options.batchSize ?? SO_SEARCH_LIMIT;
@@ -54,7 +63,9 @@ export async function bulkRequestDiagnostics(
});
if (res.total <= batchSize) {
const givenAgents = await getAgents(esClient, soClient, options);
- return await requestDiagnosticsBatch(esClient, givenAgents, {});
+ return await requestDiagnosticsBatch(esClient, givenAgents, {
+ additionalMetrics: options.additionalMetrics,
+ });
} else {
return await new RequestDiagnosticsActionRunner(
esClient,
diff --git a/x-pack/plugins/fleet/server/services/agents/request_diagnostics_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/request_diagnostics_action_runner.ts
index 88cb2d5770688..a2d2d753eaa71 100644
--- a/x-pack/plugins/fleet/server/services/agents/request_diagnostics_action_runner.ts
+++ b/x-pack/plugins/fleet/server/services/agents/request_diagnostics_action_runner.ts
@@ -8,6 +8,8 @@
import { v4 as uuidv4 } from 'uuid';
import type { ElasticsearchClient } from '@kbn/core/server';
+import type { RequestDiagnosticsAdditionalMetrics } from '../../../common/types';
+
import { isAgentRequestDiagnosticsSupported } from '../../../common/services';
import type { Agent } from '../../types';
@@ -38,6 +40,7 @@ export async function requestDiagnosticsBatch(
options: {
actionId?: string;
total?: number;
+ additionalMetrics?: RequestDiagnosticsAdditionalMetrics[];
}
): Promise<{ actionId: string }> {
const errors: Record = {};
@@ -62,6 +65,9 @@ export async function requestDiagnosticsBatch(
created_at: now,
type: 'REQUEST_DIAGNOSTICS',
total,
+ data: {
+ additional_metrics: options.additionalMetrics,
+ },
});
await createErrorActionResults(
diff --git a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
index 456463561f0b2..7a92798aca29d 100644
--- a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
+++ b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
@@ -9,6 +9,8 @@ import { schema } from '@kbn/config-schema';
import moment from 'moment';
import semverIsValid from 'semver/functions/valid';
+import { RequestDiagnosticsAdditionalMetrics } from '../../../common/types';
+
import { SO_SEARCH_LIMIT, AGENTS_PREFIX, AGENT_MAPPINGS } from '../../constants';
import { NewAgentActionSchema } from '../models';
@@ -163,12 +165,20 @@ export const PostRequestDiagnosticsActionRequestSchema = {
params: schema.object({
agentId: schema.string(),
}),
+ body: schema.object({
+ additional_metrics: schema.maybe(
+ schema.arrayOf(schema.oneOf([schema.literal(RequestDiagnosticsAdditionalMetrics.CPU)]))
+ ),
+ }),
};
export const PostBulkRequestDiagnosticsActionRequestSchema = {
body: schema.object({
agents: schema.oneOf([schema.arrayOf(schema.string()), schema.string()]),
batchSize: schema.maybe(schema.number()),
+ additional_metrics: schema.maybe(
+ schema.arrayOf(schema.oneOf([schema.literal(RequestDiagnosticsAdditionalMetrics.CPU)]))
+ ),
}),
};
From e5d1e544954c40d6698dcbe296231bf415dd9c3d Mon Sep 17 00:00:00 2001
From: Julia Bardi
Date: Tue, 2 Apr 2024 15:52:30 +0200
Subject: [PATCH 2/4] updated openapi spec
---
.../plugins/fleet/common/openapi/bundled.json | 43 ++++++++++++++++++-
.../plugins/fleet/common/openapi/bundled.yaml | 25 ++++++++++-
.../fleet/common/openapi/entrypoint.yaml | 3 +-
.../agents@bulk_request_diagnostics.yaml | 7 +++
...agents@{agent_id}@request_diagnostics.yaml | 13 ++++++
...lates@{pkg_name}@{pkg_version}@inputs.yaml | 2 +
6 files changed, 87 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json
index f7c192db0fe5e..a526294d963fa 100644
--- a/x-pack/plugins/fleet/common/openapi/bundled.json
+++ b/x-pack/plugins/fleet/common/openapi/bundled.json
@@ -15,8 +15,7 @@
},
"servers": [
{
- "url": "http://localhost:5601/api/fleet",
- "description": "local"
+ "url": "http://KIBANA_HOST:5601/api/fleet"
}
],
"paths": {
@@ -1530,6 +1529,9 @@
"Elastic Package Manager (EPM)"
],
"responses": {
+ "200": {
+ "description": "OK"
+ },
"400": {
"$ref": "#/components/responses/error"
}
@@ -3076,6 +3078,30 @@
"tags": [
"Agents"
],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "additional_metrics": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "CPU"
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"responses": {
"200": {
"description": "OK",
@@ -3159,6 +3185,19 @@
"description": "list of agent IDs"
}
]
+ },
+ "additional_metrics": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string",
+ "enum": [
+ "CPU"
+ ]
+ }
+ ]
+ }
}
},
"required": [
diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml
index 406a2550d770d..f76e50c095aed 100644
--- a/x-pack/plugins/fleet/common/openapi/bundled.yaml
+++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml
@@ -10,8 +10,7 @@ info:
name: Elastic License 2.0
url: https://www.elastic.co/licensing/elastic-license
servers:
- - url: http://localhost:5601/api/fleet
- description: local
+ - url: http://KIBANA_HOST:5601/api/fleet
paths:
/health_check:
post:
@@ -966,6 +965,8 @@ paths:
tags:
- Elastic Package Manager (EPM)
responses:
+ '200':
+ description: OK
'400':
$ref: '#/components/responses/error'
operationId: get-inputs-template
@@ -1928,6 +1929,19 @@ paths:
summary: Request agent diagnostics
tags:
- Agents
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ additional_metrics:
+ type: array
+ items:
+ oneOf:
+ - type: string
+ enum:
+ - CPU
responses:
'200':
description: OK
@@ -1979,6 +1993,13 @@ paths:
items:
type: string
description: list of agent IDs
+ additional_metrics:
+ type: array
+ items:
+ oneOf:
+ - type: string
+ enum:
+ - CPU
required:
- agents
example:
diff --git a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml
index beb18d507079e..a4b3f2cbaaa18 100644
--- a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml
+++ b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml
@@ -10,8 +10,7 @@ info:
name: Elastic License 2.0
url: https://www.elastic.co/licensing/elastic-license
servers:
- - url: 'http://localhost:5601/api/fleet'
- description: local
+ - url: 'http://KIBANA_HOST:5601/api/fleet'
paths:
# Fleet internals
/health_check:
diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_request_diagnostics.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_request_diagnostics.yaml
index 3f0733ed8f258..2ef2d1c1ff5d5 100644
--- a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_request_diagnostics.yaml
+++ b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_request_diagnostics.yaml
@@ -33,6 +33,13 @@ post:
items:
type: string
description: list of agent IDs
+ additional_metrics:
+ type: array
+ items:
+ oneOf:
+ - type: string
+ enum:
+ - "CPU"
required:
- agents
example:
diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@request_diagnostics.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@request_diagnostics.yaml
index 37aed12d5f4f1..eba9a695d1cbc 100644
--- a/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@request_diagnostics.yaml
+++ b/x-pack/plugins/fleet/common/openapi/paths/agents@{agent_id}@request_diagnostics.yaml
@@ -8,6 +8,19 @@ post:
summary: Request agent diagnostics
tags:
- Agents
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ additional_metrics:
+ type: array
+ items:
+ oneOf:
+ - type: string
+ enum:
+ - "CPU"
responses:
'200':
description: OK
diff --git a/x-pack/plugins/fleet/common/openapi/paths/epm@templates@{pkg_name}@{pkg_version}@inputs.yaml b/x-pack/plugins/fleet/common/openapi/paths/epm@templates@{pkg_name}@{pkg_version}@inputs.yaml
index 5f7b3f28c8c7d..3a5c89f7c34e3 100644
--- a/x-pack/plugins/fleet/common/openapi/paths/epm@templates@{pkg_name}@{pkg_version}@inputs.yaml
+++ b/x-pack/plugins/fleet/common/openapi/paths/epm@templates@{pkg_name}@{pkg_version}@inputs.yaml
@@ -5,6 +5,8 @@ get:
responses:
'400':
$ref: ../components/responses/error.yaml
+ '200':
+ description: OK
operationId: get-inputs-template
security:
- basicAuth: []
From 27aab02e9ca9ec38d139cf9ec5d7db1974ff2b71 Mon Sep 17 00:00:00 2001
From: Julia Bardi
Date: Tue, 2 Apr 2024 16:38:44 +0200
Subject: [PATCH 3/4] fix tests
---
.../components/agent_diagnostics/index.tsx | 5 +--
.../agent/request_diagnostics_handler.test.ts | 9 ++++-
.../agent/request_diagnostics_handler.ts | 2 +-
.../fleet/server/types/rest_spec/agent.ts | 12 +++---
.../apis/agents/request_diagnostics.ts | 39 +++++++++++++++++++
5 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
index e1079fea1fd4a..1eaea92be9639 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_diagnostics/index.tsx
@@ -51,7 +51,6 @@ export const AgentDiagnosticsTab: React.FunctionComponent
const authz = useAuthz();
const { notifications } = useStartServices();
const { getAbsolutePath } = useLink();
- const [isSubmitting, setIsSubmitting] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [diagnosticsEntries, setDiagnosticEntries] = useState([]);
const [prevDiagnosticsEntries, setPrevDiagnosticEntries] = useState([]);
@@ -198,9 +197,7 @@ export const AgentDiagnosticsTab: React.FunctionComponent
onClick={() => {
setIsRequestDiagnosticsModalOpen(true);
}}
- disabled={
- isSubmitting || !isAgentRequestDiagnosticsSupported(agent) || !authz.fleet.readAgents
- }
+ disabled={!isAgentRequestDiagnosticsSupported(agent) || !authz.fleet.readAgents}
>
{
let mockSavedObjectsClient: jest.Mocked;
let mockElasticsearchClient: jest.Mocked;
let mockContext: RequestHandlerContext;
- let mockRequest: KibanaRequest<{ agentId: string }, undefined, undefined, any>;
+ let mockRequest: KibanaRequest<
+ { agentId: string },
+ undefined,
+ { additional_metrics: RequestDiagnosticsAdditionalMetrics[] },
+ any
+ >;
beforeEach(() => {
mockSavedObjectsClient = savedObjectsClientMock.create();
diff --git a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
index f82bc8fda927c..a87b21ab89352 100644
--- a/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
+++ b/x-pack/plugins/fleet/server/routes/agent/request_diagnostics_handler.ts
@@ -41,7 +41,7 @@ export const requestDiagnosticsHandler: RequestHandler<
const result = await AgentService.requestDiagnostics(
esClient,
request.params.agentId,
- request.body.additional_metrics
+ request.body?.additional_metrics
);
return response.ok({ body: { actionId: result.actionId } });
diff --git a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
index 7a92798aca29d..ad3e96d10d555 100644
--- a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
+++ b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts
@@ -165,11 +165,13 @@ export const PostRequestDiagnosticsActionRequestSchema = {
params: schema.object({
agentId: schema.string(),
}),
- body: schema.object({
- additional_metrics: schema.maybe(
- schema.arrayOf(schema.oneOf([schema.literal(RequestDiagnosticsAdditionalMetrics.CPU)]))
- ),
- }),
+ body: schema.nullable(
+ schema.object({
+ additional_metrics: schema.maybe(
+ schema.arrayOf(schema.oneOf([schema.literal(RequestDiagnosticsAdditionalMetrics.CPU)]))
+ ),
+ })
+ ),
};
export const PostBulkRequestDiagnosticsActionRequestSchema = {
diff --git a/x-pack/test/fleet_api_integration/apis/agents/request_diagnostics.ts b/x-pack/test/fleet_api_integration/apis/agents/request_diagnostics.ts
index 8bf70174780a7..70b1b2c20b1d1 100644
--- a/x-pack/test/fleet_api_integration/apis/agents/request_diagnostics.ts
+++ b/x-pack/test/fleet_api_integration/apis/agents/request_diagnostics.ts
@@ -17,6 +17,7 @@ export default function (providerContext: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const supertestWithoutAuth = getService('supertestWithoutAuth');
+ const es = getService('es');
describe('fleet_request_diagnostics', () => {
skipIfNoDockerRegistry(providerContext);
@@ -118,5 +119,43 @@ export default function (providerContext: FtrProviderContext) {
throw e;
});
});
+
+ it('should create action with additional_metrics when api contains CPU option', async () => {
+ await supertest
+ .post(`/api/fleet/agents/agent1/request_diagnostics`)
+ .set('kbn-xsrf', 'xxx')
+ .send({
+ additional_metrics: ['CPU'],
+ })
+ .expect(200);
+ const actionsRes = await es.search({
+ index: '.fleet-actions',
+ body: {
+ sort: [{ '@timestamp': { order: 'desc' } }],
+ },
+ });
+ const action: any = actionsRes.hits.hits[0]._source;
+ expect(action.data.additional_metrics).contain('CPU');
+ });
+
+ it('/agents/bulk_request_diagnostics should add CPU option to action doc', async () => {
+ await supertestWithoutAuth
+ .post(`/api/fleet/agents/bulk_request_diagnostics`)
+ .set('kbn-xsrf', 'xxx')
+ .auth(testUsers.fleet_agents_read_only.username, testUsers.fleet_agents_read_only.password)
+ .send({
+ agents: ['agent2', 'agent3'],
+ additional_metrics: ['CPU'],
+ });
+
+ const actionsRes = await es.search({
+ index: '.fleet-actions',
+ body: {
+ sort: [{ '@timestamp': { order: 'desc' } }],
+ },
+ });
+ const action: any = actionsRes.hits.hits[0]._source;
+ expect(action.data.additional_metrics).contain('CPU');
+ });
});
}
From bdfd7948b50a726e44060cc0fcea258b65aac1f4 Mon Sep 17 00:00:00 2001
From: Julia Bardi
Date: Wed, 3 Apr 2024 09:37:12 +0200
Subject: [PATCH 4/4] added unit test
---
.../index.test.tsx | 104 ++++++++++++++++++
.../agent_request_diagnostics_modal/index.tsx | 1 +
2 files changed, 105 insertions(+)
create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.test.tsx
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.test.tsx
new file mode 100644
index 0000000000000..b86e3cc29a67a
--- /dev/null
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.test.tsx
@@ -0,0 +1,104 @@
+/*
+ * 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 React from 'react';
+
+import { act, fireEvent } from '@testing-library/react';
+
+import { createFleetTestRendererMock } from '../../../../../../mock';
+
+import { sendPostRequestDiagnostics, sendPostBulkRequestDiagnostics } from '../../../../hooks';
+
+import { AgentRequestDiagnosticsModal } from '.';
+
+jest.mock('../../../../hooks', () => {
+ return {
+ ...jest.requireActual('../../../../hooks'),
+ sendPostRequestDiagnostics: jest.fn().mockResolvedValue({}),
+ sendPostBulkRequestDiagnostics: jest.fn().mockResolvedValue({}),
+ };
+});
+
+const mockSendPostRequestDiagnostics = sendPostRequestDiagnostics as jest.Mock;
+const mockSendPostBulkRequestDiagnostics = sendPostBulkRequestDiagnostics as jest.Mock;
+
+describe('AgentRequestDiagnosticsModal', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ function render(props: any = {}) {
+ const renderer = createFleetTestRendererMock();
+
+ const utils = renderer.render(
+
+ );
+
+ return { utils };
+ }
+
+ it('should include CPU option when checkbox is checked', async () => {
+ const { utils } = render();
+
+ act(() => {
+ fireEvent.click(utils.getByTestId('cpuMetricsCheckbox'));
+ });
+ act(() => {
+ fireEvent.click(utils.getByTestId('confirmModalConfirmButton'));
+ });
+
+ expect(mockSendPostRequestDiagnostics).toHaveBeenCalledWith('agent1', {
+ additional_metrics: ['CPU'],
+ });
+ });
+
+ it('should not include CPU option when checkbox is not checked', async () => {
+ const { utils } = render();
+
+ act(() => {
+ fireEvent.click(utils.getByTestId('confirmModalConfirmButton'));
+ });
+
+ expect(mockSendPostRequestDiagnostics).toHaveBeenCalledWith('agent1', {
+ additional_metrics: [],
+ });
+ });
+
+ it('should include CPU option when checkbox is checked when bulk action', async () => {
+ const { utils } = render({ agents: [{ id: 'agent1' }, { id: 'agent2' }], agentCount: 2 });
+
+ act(() => {
+ fireEvent.click(utils.getByTestId('cpuMetricsCheckbox'));
+ });
+ act(() => {
+ fireEvent.click(utils.getByTestId('confirmModalConfirmButton'));
+ });
+
+ expect(mockSendPostBulkRequestDiagnostics).toHaveBeenCalledWith({
+ additional_metrics: ['CPU'],
+ agents: ['agent1', 'agent2'],
+ });
+ });
+
+ it('should not include CPU option when checkbox is checked when bulk action', async () => {
+ const { utils } = render({ agents: [{ id: 'agent1' }, { id: 'agent2' }], agentCount: 2 });
+
+ act(() => {
+ fireEvent.click(utils.getByTestId('confirmModalConfirmButton'));
+ });
+
+ expect(mockSendPostBulkRequestDiagnostics).toHaveBeenCalledWith({
+ additional_metrics: [],
+ agents: ['agent1', 'agent2'],
+ });
+ });
+});
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
index 75b335076195c..82bf1f1b31874 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_request_diagnostics_modal/index.tsx
@@ -131,6 +131,7 @@ export const AgentRequestDiagnosticsModal: React.FunctionComponent = ({
setCPUMetricsEnabled(!cpuMetricsEnabled)}