[Fleet] Fix performance issue in agent status endpoint (#90066)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nicolas Chaulet 2021-02-02 20:23:56 -05:00 committed by GitHub
parent 75d9e0a071
commit 20654388a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 18 deletions

View file

@ -12,18 +12,35 @@ import { AgentSOAttributes, Agent, ListWithKuery } from '../../types';
import { escapeSearchQueryPhrase, normalizeKuery, findAllSOs } from '../saved_object';
import { savedObjectToAgent } from './saved_objects';
import { appContextService } from '../../services';
import { esKuery, KueryNode } from '../../../../../../src/plugins/data/server';
const ACTIVE_AGENT_CONDITION = `${AGENT_SAVED_OBJECT_TYPE}.attributes.active:true`;
const INACTIVE_AGENT_CONDITION = `NOT (${ACTIVE_AGENT_CONDITION})`;
function _joinFilters(filters: string[], operator = 'AND') {
return filters.reduce((acc: string | undefined, filter) => {
if (acc) {
return `${acc} ${operator} (${filter})`;
}
function _joinFilters(filters: Array<string | undefined | KueryNode>) {
return filters
.filter((filter) => filter !== undefined)
.reduce((acc: KueryNode | undefined, kuery: string | KueryNode | undefined):
| KueryNode
| undefined => {
if (kuery === undefined) {
return acc;
}
const kueryNode: KueryNode =
typeof kuery === 'string'
? esKuery.fromKueryExpression(normalizeKuery(AGENT_SAVED_OBJECT_TYPE, kuery))
: kuery;
return `(${filter})`;
}, undefined);
if (!acc) {
return kueryNode;
}
return {
type: 'function',
function: 'and',
arguments: [acc, kueryNode],
};
}, undefined as KueryNode | undefined);
}
export async function listAgents(
@ -46,19 +63,18 @@ export async function listAgents(
showInactive = false,
showUpgradeable,
} = options;
const filters = [];
const filters: Array<string | KueryNode | undefined> = [];
if (kuery && kuery !== '') {
filters.push(normalizeKuery(AGENT_SAVED_OBJECT_TYPE, kuery));
filters.push(kuery);
}
if (showInactive === false) {
filters.push(ACTIVE_AGENT_CONDITION);
}
let { saved_objects: agentSOs, total } = await soClient.find<AgentSOAttributes>({
type: AGENT_SAVED_OBJECT_TYPE,
filter: _joinFilters(filters),
filter: _joinFilters(filters) || '',
sortField,
sortOrder,
page,
@ -94,7 +110,7 @@ export async function listAllAgents(
const filters = [];
if (kuery && kuery !== '') {
filters.push(normalizeKuery(AGENT_SAVED_OBJECT_TYPE, kuery));
filters.push(kuery);
}
if (showInactive === false) {

View file

@ -11,6 +11,8 @@ import { AGENT_EVENT_SAVED_OBJECT_TYPE, AGENT_SAVED_OBJECT_TYPE } from '../../co
import { AgentStatus } from '../../types';
import { AgentStatusKueryHelper } from '../../../common/services';
import { esKuery, KueryNode } from '../../../../../../src/plugins/data/server';
import { normalizeKuery } from '../saved_object';
export async function getAgentStatusById(
soClient: SavedObjectsClientContract,
@ -26,13 +28,24 @@ export const getAgentStatus = AgentStatusKueryHelper.getAgentStatus;
function joinKuerys(...kuerys: Array<string | undefined>) {
return kuerys
.filter((kuery) => kuery !== undefined)
.reduce((acc, kuery) => {
if (acc === '') {
return `(${kuery})`;
.reduce((acc: KueryNode | undefined, kuery: string | undefined): KueryNode | undefined => {
if (kuery === undefined) {
return acc;
}
const normalizedKuery: KueryNode = esKuery.fromKueryExpression(
normalizeKuery(AGENT_SAVED_OBJECT_TYPE, kuery || '')
);
if (!acc) {
return normalizedKuery;
}
return `${acc} and (${kuery})`;
}, '');
return {
type: 'function',
function: 'and',
arguments: [acc, normalizedKuery],
};
}, undefined as KueryNode | undefined);
}
export async function getAgentStatusForAgentPolicy(
@ -58,6 +71,7 @@ export async function getAgentStatusForAgentPolicy(
...[
kuery,
filterKuery,
`${AGENT_SAVED_OBJECT_TYPE}.attributes.active:true`,
agentPolicyId ? `${AGENT_SAVED_OBJECT_TYPE}.policy_id:"${agentPolicyId}"` : undefined,
]
),

View file

@ -11,7 +11,12 @@ export const ListWithKuerySchema = schema.object({
sortField: schema.maybe(schema.string()),
sortOrder: schema.maybe(schema.oneOf([schema.literal('desc'), schema.literal('asc')])),
showUpgradeable: schema.maybe(schema.boolean()),
kuery: schema.maybe(schema.string()),
kuery: schema.maybe(
schema.oneOf([
schema.string(),
schema.any(), // KueryNode
])
),
});
export type ListWithKuery = TypeOf<typeof ListWithKuerySchema>;