Skip to content

Commit

Permalink
Merge branch 'master' into pr/83808
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov committed Mar 24, 2021
2 parents b83b2d2 + 0551472 commit 80f730e
Show file tree
Hide file tree
Showing 39 changed files with 759 additions and 130 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@
"jest-cli": "^26.6.3",
"jest-diff": "^26.6.2",
"jest-environment-jsdom-thirteen": "^1.0.1",
"jest-environment-jsdom": "^26.6.2",
"jest-raw-loader": "^1.0.1",
"jest-silent-reporter": "^0.2.1",
"jest-snapshot": "^26.6.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-test/jest-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ module.exports = {
],

// The test environment that will be used for testing
testEnvironment: 'jest-environment-jsdom-thirteen',
testEnvironment: 'jest-environment-jsdom',

// The glob patterns Jest uses to detect test files
testMatch: ['**/*.test.{js,mjs,ts,tsx}'],
Expand Down
6 changes: 5 additions & 1 deletion test/functional/services/visualizations/elastic_chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ export function ElasticChartProvider({ getService }: FtrProviderContext) {
const browser = getService('browser');

class ElasticChart {
public async getCanvas() {
public async getCanvas(dataTestSubj?: string) {
if (dataTestSubj) {
const chart = await this.getChart(dataTestSubj);
return await chart.findByClassName('echCanvasRenderer');
}
return await find.byCssSelector('.echChart canvas:last-of-type');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,9 @@ describe('CredentialsLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('fetchCredentials', () => {
const meta = {
page: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ describe('DocumentCreationLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('onSubmitFile', () => {
describe('with a valid file', () => {
beforeAll(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ describe('DocumentDetailLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('getDocumentDetails', () => {
it('will call an API endpoint and then store the result', async () => {
const fields = [{ name: 'name', value: 'python', type: 'string' }];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ describe('EngineLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('initializeEngine', () => {
it('fetches and sets engine data', async () => {
mount({ engineName: 'some-engine' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ describe('EngineOverviewLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('pollForOverviewMetrics', () => {
it('fetches data and calls onPollingSuccess', async () => {
mount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ describe('LogRetentionLogic', () => {
});
});
});
});

describe('listeners', () => {
describe('saveLogRetention', () => {
beforeEach(() => {
mount();
Expand Down Expand Up @@ -264,6 +266,37 @@ describe('LogRetentionLogic', () => {
LogRetentionOptions.Analytics
);
});

it('will call saveLogRetention if NOT already enabled', () => {
mount({
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: false,
},
},
});
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');

LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.Analytics);

expect(LogRetentionLogic.actions.saveLogRetention).toHaveBeenCalledWith(
LogRetentionOptions.Analytics,
true
);
});

it('will do nothing if logRetention option is not yet set', () => {
mount({
logRetention: {},
});
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');
jest.spyOn(LogRetentionLogic.actions, 'setOpenedModal');

LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.API);

expect(LogRetentionLogic.actions.saveLogRetention).not.toHaveBeenCalled();
expect(LogRetentionLogic.actions.setOpenedModal).not.toHaveBeenCalled();
});
});

describe('fetchLogRetention', () => {
Expand Down Expand Up @@ -306,36 +339,5 @@ describe('LogRetentionLogic', () => {
expect(http.get).not.toHaveBeenCalled();
});
});

it('will call saveLogRetention if NOT already enabled', () => {
mount({
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: false,
},
},
});
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');

LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.Analytics);

expect(LogRetentionLogic.actions.saveLogRetention).toHaveBeenCalledWith(
LogRetentionOptions.Analytics,
true
);
});

it('will do nothing if logRetention option is not yet set', () => {
mount({
logRetention: {},
});
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');
jest.spyOn(LogRetentionLogic.actions, 'setOpenedModal');

LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.API);

expect(LogRetentionLogic.actions.saveLogRetention).not.toHaveBeenCalled();
expect(LogRetentionLogic.actions.setOpenedModal).not.toHaveBeenCalled();
});
});
});
11 changes: 6 additions & 5 deletions x-pack/plugins/fleet/common/types/rest_spec/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,13 @@ export interface PostBulkAgentReassignRequest {
};
}

export interface PostBulkAgentReassignResponse {
[key: string]: {
export type PostBulkAgentReassignResponse = Record<
Agent['id'],
{
success: boolean;
error?: Error;
};
}
error?: string;
}
>;

export interface GetOneAgentEventsRequest {
params: {
Expand Down
20 changes: 10 additions & 10 deletions x-pack/plugins/fleet/server/routes/agent/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,26 +308,26 @@ export const postBulkAgentsReassignHandler: RequestHandler<

const soClient = context.core.savedObjects.client;
const esClient = context.core.elasticsearch.client.asInternalUser;
const agentOptions = Array.isArray(request.body.agents)
? { agentIds: request.body.agents }
: { kuery: request.body.agents };

try {
const results = await AgentService.reassignAgents(
soClient,
esClient,
Array.isArray(request.body.agents)
? { agentIds: request.body.agents }
: { kuery: request.body.agents },
agentOptions,
request.body.policy_id
);

const body: PostBulkAgentReassignResponse = results.items.reduce((acc, so) => {
return {
...acc,
[so.id]: {
success: !so.error,
error: so.error || undefined,
},
const body = results.items.reduce<PostBulkAgentReassignResponse>((acc, so) => {
acc[so.id] = {
success: !so.error,
error: so.error?.message,
};
return acc;
}, {});

return response.ok({ body });
} catch (error) {
return defaultIngestErrorHandler({ error, response });
Expand Down
47 changes: 29 additions & 18 deletions x-pack/plugins/fleet/server/services/agents/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Boom from '@hapi/boom';
import type { estypes } from '@elastic/elasticsearch';
import type { SavedObjectsClientContract, ElasticsearchClient } from 'src/core/server';

import type { AgentSOAttributes, Agent, ListWithKuery } from '../../types';
import type { AgentSOAttributes, Agent, BulkActionResult, ListWithKuery } from '../../types';

import { appContextService, agentPolicyService } from '../../services';
import type { FleetServerAgent } from '../../../common';
import { isAgentUpgradeable, SO_SEARCH_LIMIT } from '../../../common';
Expand Down Expand Up @@ -68,22 +69,23 @@ export type GetAgentsOptions =
};

export async function getAgents(esClient: ElasticsearchClient, options: GetAgentsOptions) {
let initialResults = [];

let agents: Agent[] = [];
if ('agentIds' in options) {
initialResults = await getAgentsById(esClient, options.agentIds);
agents = await getAgentsById(esClient, options.agentIds);
} else if ('kuery' in options) {
initialResults = (
agents = (
await getAllAgentsByKuery(esClient, {
kuery: options.kuery,
showInactive: options.showInactive ?? false,
})
).agents;
} else {
throw new IngestManagerError('Cannot get agents');
throw new IngestManagerError(
'Either options.agentIds or options.kuery are required to get agents'
);
}

return initialResults;
return agents;
}

export async function getAgentsByKuery(
Expand Down Expand Up @@ -207,29 +209,37 @@ export async function getAgentById(esClient: ElasticsearchClient, agentId: strin
}
}

async function getAgentDocuments(
export function isAgentDocument(
maybeDocument: any
): maybeDocument is estypes.MultiGetHit<FleetServerAgent> {
return '_id' in maybeDocument && '_source' in maybeDocument;
}

export type ESAgentDocumentResult = estypes.MultiGetHit<FleetServerAgent>;
export async function getAgentDocuments(
esClient: ElasticsearchClient,
agentIds: string[]
): Promise<Array<estypes.GetResponse<FleetServerAgent>>> {
): Promise<ESAgentDocumentResult[]> {
const res = await esClient.mget<FleetServerAgent>({
index: AGENTS_INDEX,
body: { docs: agentIds.map((_id) => ({ _id })) },
});

// @ts-expect-error MultiGetHit is not assignable to Hit
return res.body.docs || [];
}

export async function getAgentsById(
esClient: ElasticsearchClient,
agentIds: string[],
options: { includeMissing?: boolean } = { includeMissing: false }
agentIds: string[]
): Promise<Agent[]> {
const allDocs = await getAgentDocuments(esClient, agentIds);
const agentDocs = options.includeMissing
? allDocs
: allDocs.filter((res) => res._id && res._source);
const agents = agentDocs.map((doc) => searchHitToAgent(doc));
const agents = allDocs.reduce<Agent[]>((results, doc) => {
if (isAgentDocument(doc)) {
results.push(searchHitToAgent(doc));
}

return results;
}, []);

return agents;
}
Expand Down Expand Up @@ -277,7 +287,7 @@ export async function bulkUpdateAgents(
agentId: string;
data: Partial<AgentSOAttributes>;
}>
) {
): Promise<{ items: BulkActionResult[] }> {
if (updateData.length === 0) {
return { items: [] };
}
Expand All @@ -303,7 +313,8 @@ export async function bulkUpdateAgents(
items: res.body.items.map((item: estypes.BulkResponseItemContainer) => ({
id: item.update!._id as string,
success: !item.update!.error,
error: item.update!.error,
// @ts-expect-error ErrorCause is not assignable to Error
error: item.update!.error as Error,
})),
};
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/server/services/agents/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { SearchHit } from '../../../../../../typings/elasticsearch';
import type { Agent, AgentSOAttributes, FleetServerAgent } from '../../types';

type FleetServerAgentESResponse =
| estypes.GetResponse<FleetServerAgent>
| estypes.MultiGetHit<FleetServerAgent>
| estypes.SearchResponse<FleetServerAgent>['hits']['hits'][0]
| SearchHit<FleetServerAgent>;

Expand Down
Loading

0 comments on commit 80f730e

Please sign in to comment.