added filters to tags query (#137089)

This commit is contained in:
Julia Bardi 2022-07-26 11:15:21 +02:00 committed by GitHub
parent a296e4cc97
commit b3d7d1288d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 98 additions and 13 deletions

View file

@ -250,7 +250,10 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
sendGetAgentStatus({
kuery: kuery && kuery !== '' ? kuery : undefined,
}),
sendGetAgentTags(),
sendGetAgentTags({
kuery: kuery && kuery !== '' ? kuery : undefined,
showInactive,
}),
]);
isLoadingVar.current = false;
// Return if a newer request has been triggered

View file

@ -97,10 +97,12 @@ export function sendGetAgentStatus(
});
}
export function sendGetAgentTags() {
export function sendGetAgentTags(query: GetAgentsRequest['query'], options?: RequestOptions) {
return sendRequest<GetAgentTagsResponse>({
method: 'get',
path: agentRouteService.getListTagsPath(),
query,
...options,
});
}

View file

@ -20,6 +20,7 @@ import type {
} from '../../../common/types';
import type {
GetAgentsRequestSchema,
GetTagsRequestSchema,
GetOneAgentRequestSchema,
UpdateAgentRequestSchema,
DeleteAgentRequestSchema,
@ -188,16 +189,18 @@ export const getAgentsHandler: RequestHandler<
}
};
export const getAgentTagsHandler: RequestHandler<undefined, undefined, undefined> = async (
context,
request,
response
) => {
export const getAgentTagsHandler: RequestHandler<
undefined,
TypeOf<typeof GetTagsRequestSchema.query>
> = async (context, request, response) => {
const coreContext = await context.core;
const esClient = coreContext.elasticsearch.client.asInternalUser;
try {
const tags = await AgentService.getAgentTags(esClient);
const tags = await AgentService.getAgentTags(esClient, {
showInactive: request.query.showInactive,
kuery: request.query.kuery,
});
const body: GetAgentTagsResponse = {
items: tags,

View file

@ -8,6 +8,7 @@
import { AGENT_API_ROUTES } from '../../constants';
import {
GetAgentsRequestSchema,
GetTagsRequestSchema,
GetOneAgentRequestSchema,
UpdateAgentRequestSchema,
DeleteAgentRequestSchema,
@ -111,7 +112,7 @@ export const registerAPIRoutes = (router: FleetAuthzRouter, config: FleetConfigT
router.get(
{
path: AGENT_API_ROUTES.LIST_TAGS_PATTERN,
validate: {},
validate: GetTagsRequestSchema,
fleetAuthz: {
fleet: { all: true },
},

View file

@ -48,9 +48,17 @@ describe('Agents CRUD test', () => {
},
});
const result = await getAgentTags(esClientMock);
const result = await getAgentTags(esClientMock, { showInactive: false });
expect(result).toEqual(['tag1', 'tag2']);
expect(searchMock).toHaveBeenCalledWith({
aggs: { tags: { terms: { field: 'tags', size: 10000 } } },
body: {
query: { bool: { minimum_should_match: 1, should: [{ match: { active: true } }] } },
},
index: '.fleet-agents',
size: 0,
});
});
it('should return empty list if no agent tags', async () => {
@ -60,7 +68,7 @@ describe('Agents CRUD test', () => {
},
});
const result = await getAgentTags(esClientMock);
const result = await getAgentTags(esClientMock, { showInactive: false });
expect(result).toEqual([]);
});
@ -68,10 +76,43 @@ describe('Agents CRUD test', () => {
it('should return empty list if no agent index', async () => {
searchMock.mockRejectedValueOnce(new errors.ResponseError({ statusCode: 404 } as any));
const result = await getAgentTags(esClientMock);
const result = await getAgentTags(esClientMock, { showInactive: false });
expect(result).toEqual([]);
});
it('should pass query when called with kuery', async () => {
searchMock.mockResolvedValueOnce({
aggregations: {
tags: { buckets: [{ key: 'tag1' }, { key: 'tag2' }] },
},
});
await getAgentTags(esClientMock, {
showInactive: true,
kuery: 'fleet-agents.policy_id: 123',
});
expect(searchMock).toHaveBeenCalledWith({
aggs: { tags: { terms: { field: 'tags', size: 10000 } } },
body: {
query: {
bool: {
minimum_should_match: 1,
should: [
{
match: {
policy_id: '123',
},
},
],
},
},
},
index: '.fleet-agents',
size: 0,
});
});
});
describe('getAgentsByKuery', () => {

View file

@ -115,11 +115,30 @@ export async function closePointInTime(esClient: ElasticsearchClient, pitId: str
}
}
export async function getAgentTags(esClient: ElasticsearchClient): Promise<string[]> {
export async function getAgentTags(
esClient: ElasticsearchClient,
options: ListWithKuery & {
showInactive: boolean;
}
): Promise<string[]> {
const { kuery, showInactive = false } = options;
const filters = [];
if (kuery && kuery !== '') {
filters.push(kuery);
}
if (showInactive === false) {
filters.push(ACTIVE_AGENT_CONDITION);
}
const kueryNode = _joinFilters(filters);
const body = kueryNode ? { query: toElasticsearchQuery(kueryNode) } : {};
try {
const result = await esClient.search<{}, { tags: { buckets: Array<{ key: string }> } }>({
index: AGENTS_INDEX,
size: 0,
body,
aggs: {
tags: {
terms: { field: 'tags', size: SO_SEARCH_LIMIT },

View file

@ -17,3 +17,4 @@ export * from './settings';
export * from './setup';
export * from './check_permissions';
export * from './download_sources';
export * from './tags';

View file

@ -0,0 +1,15 @@
/*
* 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 GetTagsRequestSchema = {
query: schema.object({
kuery: schema.maybe(schema.string()),
showInactive: schema.boolean({ defaultValue: false }),
}),
};