mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[EDR Workflows] Fix agent count for single agent policies (#194294)
https://github.com/user-attachments/assets/2b64c1e0-0e6d-4ef5-952d-e4364b4403c4 The PR #193705 introduced an issue when counting active agents for integration policies with only one agent policy assigned. In such cases, `query.policyIds` was treated as a single string instead of an array of strings (as expected with multiple agent policy ids like `/?policyIds=x&policyIds=y`). This PR resolves the issue by ensuring consistent handling of policyIds, regardless of the number of associated agent policies.
This commit is contained in:
parent
878ba134e9
commit
847285ba71
5 changed files with 69 additions and 14 deletions
|
@ -7,7 +7,9 @@
|
|||
|
||||
import { coreMock, httpServerMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import { getAvailableVersionsHandler } from './handlers';
|
||||
import { getAgentStatusForAgentPolicy } from '../../services/agents/status';
|
||||
|
||||
import { getAgentStatusForAgentPolicyHandler, getAvailableVersionsHandler } from './handlers';
|
||||
|
||||
jest.mock('../../services/agents/versions', () => {
|
||||
return {
|
||||
|
@ -24,16 +26,60 @@ jest.mock('../../services/app_context', () => {
|
|||
};
|
||||
});
|
||||
|
||||
describe('getAvailableVersionsHandler', () => {
|
||||
it('should return the value from getAvailableVersions', async () => {
|
||||
const ctx = coreMock.createCustomRequestHandlerContext(coreMock.createRequestHandlerContext());
|
||||
const response = httpServerMock.createResponseFactory();
|
||||
jest.mock('../../services/agents/status', () => ({
|
||||
getAgentStatusForAgentPolicy: jest.fn(),
|
||||
}));
|
||||
|
||||
await getAvailableVersionsHandler(ctx, httpServerMock.createKibanaRequest(), response);
|
||||
describe('Handlers', () => {
|
||||
describe('getAgentStatusForAgentPolicyHandler', () => {
|
||||
it.each([
|
||||
{ requested: 'policy-id-1', called: ['policy-id-1'] },
|
||||
{ requested: ['policy-id-2'], called: ['policy-id-2'] },
|
||||
{ requested: ['policy-id-3', 'policy-id-4'], called: ['policy-id-3', 'policy-id-4'] },
|
||||
...[undefined, '', []].map((requested) => ({ requested, called: undefined })),
|
||||
])('calls getAgentStatusForAgentPolicy with correct parameters', async (item) => {
|
||||
const request = {
|
||||
query: {
|
||||
policyId: 'policy-id',
|
||||
kuery: 'kuery',
|
||||
policyIds: item.requested,
|
||||
},
|
||||
};
|
||||
const response = httpServerMock.createResponseFactory();
|
||||
|
||||
expect(response.ok).toBeCalled();
|
||||
expect(response.ok.mock.calls[0][0]?.body).toEqual({
|
||||
items: ['8.1.0', '8.0.0', '7.17.0'],
|
||||
await getAgentStatusForAgentPolicyHandler(
|
||||
{
|
||||
core: coreMock.createRequestHandlerContext(),
|
||||
fleet: { internalSoClient: {} },
|
||||
} as any,
|
||||
request as any,
|
||||
response
|
||||
);
|
||||
|
||||
expect(getAgentStatusForAgentPolicy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
'policy-id',
|
||||
'kuery',
|
||||
undefined,
|
||||
item.called
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAvailableVersionsHandler', () => {
|
||||
it('should return the value from getAvailableVersions', async () => {
|
||||
const ctx = coreMock.createCustomRequestHandlerContext(
|
||||
coreMock.createRequestHandlerContext()
|
||||
);
|
||||
const response = httpServerMock.createResponseFactory();
|
||||
|
||||
await getAvailableVersionsHandler(ctx, httpServerMock.createKibanaRequest(), response);
|
||||
|
||||
expect(response.ok).toBeCalled();
|
||||
expect(response.ok.mock.calls[0][0]?.body).toEqual({
|
||||
items: ['8.1.0', '8.0.0', '7.17.0'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -323,13 +323,22 @@ export const getAgentStatusForAgentPolicyHandler: FleetRequestHandler<
|
|||
const [coreContext, fleetContext] = await Promise.all([context.core, context.fleet]);
|
||||
const esClient = coreContext.elasticsearch.client.asInternalUser;
|
||||
const soClient = fleetContext.internalSoClient;
|
||||
|
||||
const parsePolicyIds = (policyIds: string | string[] | undefined): string[] | undefined => {
|
||||
if (!policyIds || !policyIds.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return Array.isArray(policyIds) ? policyIds : [policyIds];
|
||||
};
|
||||
|
||||
const results = await getAgentStatusForAgentPolicy(
|
||||
esClient,
|
||||
soClient,
|
||||
request.query.policyId,
|
||||
request.query.kuery,
|
||||
coreContext.savedObjects.client.getCurrentNamespace(),
|
||||
request.query.policyIds
|
||||
parsePolicyIds(request.query.policyIds)
|
||||
);
|
||||
|
||||
const body: GetAgentStatusResponse = { results };
|
||||
|
|
|
@ -241,7 +241,7 @@ export const PostBulkUpdateAgentTagsRequestSchema = {
|
|||
export const GetAgentStatusRequestSchema = {
|
||||
query: schema.object({
|
||||
policyId: schema.maybe(schema.string()),
|
||||
policyIds: schema.maybe(schema.arrayOf(schema.string())),
|
||||
policyIds: schema.maybe(schema.oneOf([schema.arrayOf(schema.string()), schema.string()])),
|
||||
kuery: schema.maybe(
|
||||
schema.string({
|
||||
validate: (value: string) => {
|
||||
|
|
|
@ -96,7 +96,7 @@ export const policySettingsMiddlewareRunner: MiddlewareRunner = async (
|
|||
|
||||
// Agent summary is secondary data, so its ok for it to come after the details
|
||||
// page is populated with the main content
|
||||
if (policyItem.policy_id) {
|
||||
if (policyItem.policy_ids?.length) {
|
||||
const { results } = await sendGetFleetAgentStatusForPolicy(http, policyItem.policy_ids);
|
||||
dispatch({
|
||||
type: 'serverReturnedPolicyDetailsAgentSummaryData',
|
||||
|
|
|
@ -83,7 +83,7 @@ export const sendPutPackagePolicy = (
|
|||
};
|
||||
|
||||
/**
|
||||
* Get a status summary for all Agents that are currently assigned to a given agent policy
|
||||
* Get a status summary for all Agents that are currently assigned to a given agent policies
|
||||
*
|
||||
* @param http
|
||||
* @param policyIds
|
||||
|
@ -91,7 +91,7 @@ export const sendPutPackagePolicy = (
|
|||
*/
|
||||
export const sendGetFleetAgentStatusForPolicy = (
|
||||
http: HttpStart,
|
||||
/** the Agent (fleet) policy id */
|
||||
/** the Agent (fleet) policy ids */
|
||||
policyIds: string[],
|
||||
options: Exclude<HttpFetchOptions, 'query'> = {}
|
||||
): Promise<GetAgentStatusResponse> => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue