Skip to content

Commit

Permalink
[Fleet] Move actions to their own saved objects (#62137)
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet authored Apr 6, 2020
1 parent 42d7bb0 commit 0da20fe
Show file tree
Hide file tree
Showing 22 changed files with 1,962 additions and 455 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/ingest_manager/common/constants/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/

export const AGENT_SAVED_OBJECT_TYPE = 'agents';

export const AGENT_EVENT_SAVED_OBJECT_TYPE = 'agent_events';
export const AGENT_ACTION_SAVED_OBJECT_TYPE = 'agent_actions';

export const AGENT_TYPE_PERMANENT = 'PERMANENT';
export const AGENT_TYPE_EPHEMERAL = 'EPHEMERAL';
Expand Down
9 changes: 7 additions & 2 deletions x-pack/plugins/ingest_manager/common/types/models/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ export type AgentStatus = 'offline' | 'error' | 'online' | 'inactive' | 'warning

export interface NewAgentAction {
type: 'CONFIG_CHANGE' | 'DATA_DUMP' | 'RESUME' | 'PAUSE';
data?: string;
data?: any;
sent_at?: string;
}

export type AgentAction = NewAgentAction & {
id: string;
agent_id: string;
created_at: string;
} & SavedObjectAttributes;

export interface AgentActionSOAttributes extends NewAgentAction, SavedObjectAttributes {
created_at: string;
agent_id: string;
}

export interface AgentEvent {
type: 'STATE' | 'ERROR' | 'ACTION_RESULT' | 'ACTION';
subtype: // State
Expand Down Expand Up @@ -62,7 +68,6 @@ interface AgentBase {
config_revision?: number;
config_newest_revision?: number;
last_checkin?: string;
actions: AgentAction[];
}

export interface Agent extends AgentBase {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/ingest_manager/server/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export {
INSTALL_SCRIPT_API_ROUTES,
SETUP_API_ROUTE,
// Saved object types
AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_ACTION_SAVED_OBJECT_TYPE,
AGENT_CONFIG_SAVED_OBJECT_TYPE,
DATASOURCE_SAVED_OBJECT_TYPE,
OUTPUT_SAVED_OBJECT_TYPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('test actions handlers', () => {
getAgent: jest.fn().mockReturnValueOnce({
id: 'agent',
}),
updateAgentActions: jest.fn().mockReturnValueOnce(agentAction),
createAgentAction: jest.fn().mockReturnValueOnce(agentAction),
} as jest.Mocked<ActionsService>;

const postNewAgentActionHandler = postNewAgentActionHandlerBuilder(actionsService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export const postNewAgentActionHandlerBuilder = function(

const newAgentAction = request.body.action as NewAgentAction;

const savedAgentAction = await actionsService.updateAgentActions(
soClient,
agent,
newAgentAction
);
const savedAgentAction = await actionsService.createAgentAction(soClient, {
created_at: new Date().toISOString(),
...newAgentAction,
agent_id: agent.id,
});

const body: PostNewAgentActionResponse = {
success: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,9 @@ export const postAgentCheckinHandler: RequestHandler<
action: 'checkin',
success: true,
actions: actions.map(a => ({
agent_id: agent.id,
type: a.type,
data: a.data ? JSON.parse(a.data) : a.data,
data: a.data,
id: a.id,
created_at: a.created_at,
})),
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/ingest_manager/server/routes/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const registerRoutes = (router: IRouter) => {
},
postNewAgentActionHandlerBuilder({
getAgent: AgentService.getAgent,
updateAgentActions: AgentService.updateAgentActions,
createAgentAction: AgentService.createAgentAction,
})
);

Expand Down
20 changes: 10 additions & 10 deletions x-pack/plugins/ingest_manager/server/saved_objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
PACKAGES_SAVED_OBJECT_TYPE,
AGENT_SAVED_OBJECT_TYPE,
AGENT_EVENT_SAVED_OBJECT_TYPE,
AGENT_ACTION_SAVED_OBJECT_TYPE,
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
} from './constants';

Expand Down Expand Up @@ -38,17 +39,16 @@ export const savedObjectMappings = {
default_api_key: { type: 'keyword' },
updated_at: { type: 'date' },
current_error_events: { type: 'text' },
},
},
[AGENT_ACTION_SAVED_OBJECT_TYPE]: {
properties: {
agent_id: { type: 'keyword' },
type: { type: 'keyword' },
// FIXME_INGEST https://github.com/elastic/kibana/issues/56554
actions: {
type: 'nested',
properties: {
id: { type: 'keyword' },
type: { type: 'keyword' },
data: { type: 'text' },
sent_at: { type: 'date' },
created_at: { type: 'date' },
},
},
data: { type: 'flattened' },
sent_at: { type: 'date' },
created_at: { type: 'date' },
},
},
[AGENT_EVENT_SAVED_OBJECT_TYPE]: {
Expand Down
96 changes: 65 additions & 31 deletions x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,46 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import Boom from 'boom';
import { SavedObjectsBulkResponse } from 'kibana/server';
import { savedObjectsClientMock } from '../../../../../../src/core/server/saved_objects/service/saved_objects_client.mock';
import { Agent, AgentAction, AgentEvent } from '../../../common/types/models';
import {
Agent,
AgentAction,
AgentActionSOAttributes,
AgentEvent,
} from '../../../common/types/models';
import { AGENT_TYPE_PERMANENT } from '../../../common/constants';
import { acknowledgeAgentActions } from './acks';
import { isBoom } from 'boom';

describe('test agent acks services', () => {
it('should succeed on valid and matched actions', async () => {
const mockSavedObjectsClient = savedObjectsClientMock.create();

mockSavedObjectsClient.bulkGet.mockReturnValue(
Promise.resolve({
saved_objects: [
{
id: 'action1',
references: [],
type: 'agent_actions',
attributes: {
type: 'CONFIG_CHANGE',
agent_id: 'id',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
},
},
],
} as SavedObjectsBulkResponse<AgentActionSOAttributes>)
);

const agentActions = await acknowledgeAgentActions(
mockSavedObjectsClient,
({
id: 'id',
type: AGENT_TYPE_PERMANENT,
actions: [
{
type: 'CONFIG_CHANGE',
id: 'action1',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
},
],
} as unknown) as Agent,
[
{
Expand All @@ -41,6 +58,7 @@ describe('test agent acks services', () => {
({
type: 'CONFIG_CHANGE',
id: 'action1',
agent_id: 'id',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
Expand All @@ -50,21 +68,26 @@ describe('test agent acks services', () => {

it('should fail for actions that cannot be found on agent actions list', async () => {
const mockSavedObjectsClient = savedObjectsClientMock.create();
mockSavedObjectsClient.bulkGet.mockReturnValue(
Promise.resolve({
saved_objects: [
{
id: 'action1',
error: {
message: 'Not found',
statusCode: 404,
},
},
],
} as SavedObjectsBulkResponse<AgentActionSOAttributes>)
);

try {
await acknowledgeAgentActions(
mockSavedObjectsClient,
({
id: 'id',
type: AGENT_TYPE_PERMANENT,
actions: [
{
type: 'CONFIG_CHANGE',
id: 'action1',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
},
],
} as unknown) as Agent,
[
({
Expand All @@ -78,27 +101,38 @@ describe('test agent acks services', () => {
);
expect(true).toBeFalsy();
} catch (e) {
expect(isBoom(e)).toBeTruthy();
expect(Boom.isBoom(e)).toBeTruthy();
}
});

it('should fail for events that have types not in the allowed acknowledgement type list', async () => {
const mockSavedObjectsClient = savedObjectsClientMock.create();

mockSavedObjectsClient.bulkGet.mockReturnValue(
Promise.resolve({
saved_objects: [
{
id: 'action1',
references: [],
type: 'agent_actions',
attributes: {
type: 'CONFIG_CHANGE',
agent_id: 'id',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
},
},
],
} as SavedObjectsBulkResponse<AgentActionSOAttributes>)
);

try {
await acknowledgeAgentActions(
mockSavedObjectsClient,
({
id: 'id',
type: AGENT_TYPE_PERMANENT,
actions: [
{
type: 'CONFIG_CHANGE',
id: 'action1',
sent_at: '2020-03-14T19:45:02.620Z',
timestamp: '2019-01-04T14:32:03.36764-05:00',
created_at: '2020-03-14T19:45:02.620Z',
},
],
} as unknown) as Agent,
[
({
Expand All @@ -112,7 +146,7 @@ describe('test agent acks services', () => {
);
expect(true).toBeFalsy();
} catch (e) {
expect(isBoom(e)).toBeTruthy();
expect(Boom.isBoom(e)).toBeTruthy();
}
});
});
Loading

0 comments on commit 0da20fe

Please sign in to comment.