From 8e738de5aed2a3a5f90aa70f5e1f77af859d6544 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Fri, 18 Sep 2020 12:23:28 -0700 Subject: [PATCH 1/4] Initial pass at config->policy change action --- .../plugins/ingest_manager/common/openapi/spec_oas3.json | 4 ++-- .../plugins/ingest_manager/common/types/models/agent.ts | 2 +- .../server/routes/agent/acks_handlers.test.ts | 2 +- .../server/routes/agent/actions_handlers.test.ts | 6 +++--- .../ingest_manager/server/services/agent_policy.ts | 5 +++-- .../ingest_manager/server/services/agents/acks.test.ts | 8 ++++---- .../plugins/ingest_manager/server/services/agents/acks.ts | 2 +- .../ingest_manager/server/services/agents/actions.test.ts | 4 ++-- .../plugins/ingest_manager/server/types/models/agent.ts | 2 +- x-pack/test/functional/es_archives/fleet/agents/data.json | 4 ++-- .../apis/fleet/agents/actions.ts | 6 +++--- .../apis/fleet/agents/complete_flow.ts | 2 +- 12 files changed, 24 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index b7856e6d57402..28a88aa2be605 100644 --- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json +++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json @@ -2757,7 +2757,7 @@ "data": "{\"config\":{\"id\":\"ae556400-5e39-11ea-8b49-f9747e466f7b\",\"outputs\":{\"default\":{\"type\":\"elasticsearch\",\"hosts\":[\"http://localhost:9200\"],\"api_key\":\"\",\"api_token\":\"6ckkp3ABz7e_XRqr3LM8:gQuDfUNSRgmY0iziYqP9Hw\"}},\"packagePolicies\":[]}}", "created_at": "2020-03-04T20:02:56.149Z", "id": "6a95c00a-d76d-4931-97c3-0bf935272d7d", - "type": "CONFIG_CHANGE" + "type": "POLICY_CHANGE" } ], "access_api_key_id": "6Mkkp3ABz7e_XRqrzLNJ", @@ -2920,7 +2920,7 @@ "actions": [ { "agent_id": "a6f14bd2-1a2a-481c-9212-9494d064ffdf", - "type": "CONFIG_CHANGE", + "type": "POLICY_CHANGE", "data": { "config": { "id": "2fe89350-a5e0-11ea-a587-5f886c8a849f", diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent.ts b/x-pack/plugins/ingest_manager/common/types/models/agent.ts index a204373fe2e56..32987c7949c26 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent.ts @@ -21,7 +21,7 @@ export type AgentStatus = | 'unenrolling' | 'degraded'; -export type AgentActionType = 'CONFIG_CHANGE' | 'UNENROLL'; +export type AgentActionType = 'POLICY_CHANGE' | 'CONFIG_CHANGE' | 'UNENROLL'; export interface NewAgentAction { type: AgentActionType; diff --git a/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts b/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts index 33b9dc617075b..3d7f5c4a17adb 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts @@ -73,7 +73,7 @@ describe('test acks handlers', () => { const ackService: AcksService = { acknowledgeAgentActions: jest.fn().mockReturnValueOnce([ { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', id: 'action1', }, ]), diff --git a/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts b/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts index 5445a46fbe2b4..4574bcc64d4ce 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts @@ -23,7 +23,7 @@ describe('test actions handlers schema', () => { it('validate that new agent actions schema is valid', async () => { expect( NewAgentActionSchema.validate({ - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: 'data', sent_at: '2020-03-14T19:45:02.620Z', }) @@ -53,7 +53,7 @@ describe('test actions handlers', () => { const postNewAgentActionRequest: PostNewAgentActionRequest = { body: { action: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: 'data', sent_at: '2020-03-14T19:45:02.620Z', }, @@ -66,7 +66,7 @@ describe('test actions handlers', () => { const mockRequest = httpServerMock.createKibanaRequest(postNewAgentActionRequest); const agentAction = ({ - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', id: 'action1', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 938cfb4351630..c21d6eaa5fc56 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -404,8 +404,9 @@ class AgentPolicyService { }, []); await createAgentPolicyAction(soClient, { - type: 'CONFIG_CHANGE', - data: { config: policy } as any, + // This is problematic... + type: 'POLICY_CHANGE', + data: { config: policy, policy } as any, ack_data: { packages }, created_at: new Date().toISOString(), policy_id: policy.id, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts index 866aa587b8a56..87ae5a990f9b6 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts @@ -28,7 +28,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', agent_id: 'id', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', @@ -61,7 +61,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', @@ -127,7 +127,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', 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', @@ -211,7 +211,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', agent_id: 'id', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts index d29dfcec7ef30..5ef20b0f359bd 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts @@ -137,7 +137,7 @@ function getLatestConfigChangePolicyActionIfUpdated( return actions.reduce((acc, action) => { if ( !isAgentPolicyAction(action) || - action.type !== 'CONFIG_CHANGE' || + (action.type !== 'POLICY_CHANGE' && action.type !== 'CONFIG_CHANGE') || action.policy_id !== agent.policy_id || (acc?.policy_revision ?? 0) < (agent.policy_revision || 0) ) { diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts index bcb3fc7fdc7bd..8fde684aa38bf 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts @@ -15,7 +15,7 @@ describe('test agent actions services', () => { const newAgentAction: Omit = { agent_id: 'agentid', - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: { content: 'data' }, sent_at: '2020-03-14T19:45:02.620Z', created_at: '2020-03-14T19:45:02.620Z', @@ -24,7 +24,7 @@ describe('test agent actions services', () => { Promise.resolve({ attributes: { agent_id: 'agentid', - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: JSON.stringify({ content: 'data' }), sent_at: '2020-03-14T19:45:02.620Z', created_at: '2020-03-14T19:45:02.620Z', diff --git a/x-pack/plugins/ingest_manager/server/types/models/agent.ts b/x-pack/plugins/ingest_manager/server/types/models/agent.ts index b249705fe6c2f..f8da8e4a8e571 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/agent.ts @@ -62,7 +62,7 @@ export const AgentEventSchema = schema.object({ }); export const NewAgentActionSchema = schema.object({ - type: schema.oneOf([schema.literal('CONFIG_CHANGE'), schema.literal('UNENROLL')]), + type: schema.oneOf([schema.literal('POLICY_CHANGE'), schema.literal('UNENROLL')]), data: schema.maybe(schema.any()), sent_at: schema.maybe(schema.string()), }); diff --git a/x-pack/test/functional/es_archives/fleet/agents/data.json b/x-pack/test/functional/es_archives/fleet/agents/data.json index 12d646de85ec3..3ff16fec9138b 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/data.json +++ b/x-pack/test/functional/es_archives/fleet/agents/data.json @@ -193,7 +193,7 @@ "type": "fleet-agent-actions", "fleet-agent-actions": { "agent_id": "agent1", - "type": "CONFIG_CHANGE", + "type": "POLICY_CHANGE", "created_at": "2020-03-15T03:47:15.129Z", "sent_at": "2020-03-04T15:03:07+0000" } @@ -210,7 +210,7 @@ "type": "fleet-agent-actions", "fleet-agent-actions": { "agent_id": "agent1", - "type": "CONFIG_CHANGE", + "type": "POLICY_CHANGE", "created_at": "2020-03-15T03:47:15.129Z", "sent_at": "2020-03-04T15:03:07+0000" } diff --git a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts index 68e02933f5650..f5a647593ef52 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts @@ -26,13 +26,13 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xx') .send({ action: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: { data: 'action_data' }, }, }) .expect(200); - expect(apiResponse.item.type).to.eql('CONFIG_CHANGE'); + expect(apiResponse.item.type).to.eql('POLICY_CHANGE'); expect(apiResponse.item.data).to.eql({ data: 'action_data' }); }); @@ -58,7 +58,7 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xx') .send({ action: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: { data: 'action_data' }, sent_at: '2020-03-18T19:45:02.620Z', }, diff --git a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts index 1d5b682d71c7a..d4804c6040f57 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts @@ -76,7 +76,7 @@ export default function (providerContext: FtrProviderContext) { .expect(200); expect(checkinApiResponse.actions).length(1); - expect(checkinApiResponse.actions[0].type).be('CONFIG_CHANGE'); + expect(checkinApiResponse.actions[0].type).be('POLICY_CHANGE'); const policyChangeAction = checkinApiResponse.actions[0]; const defaultOutputApiKey = policyChangeAction.data.config.outputs.default.api_key; From 9c849fa4e1f7f9612ee7e5d64618ccb1aa7fda33 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Tue, 22 Sep 2020 14:22:06 -0700 Subject: [PATCH 2/4] Make policy change action BWC with agent <= 7.9 --- .../common/types/models/agent.ts | 17 +- .../server/services/agent_policy.ts | 3 +- .../server/services/agents/acks.test.ts | 4 +- .../server/services/agents/acks.ts | 11 +- .../agents/checkin/state_new_actions.test.ts | 156 ++++++++++++++++++ .../agents/checkin/state_new_actions.ts | 40 ++++- .../ingest_manager/server/types/index.tsx | 1 + 7 files changed, 213 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent.ts b/x-pack/plugins/ingest_manager/common/types/models/agent.ts index 32987c7949c26..a460fd647e49d 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { FullAgentPolicy } from './agent_policy'; import { AGENT_TYPE_EPHEMERAL, AGENT_TYPE_PERMANENT, AGENT_TYPE_TEMPORARY } from '../../constants'; export type AgentType = @@ -21,7 +21,7 @@ export type AgentStatus = | 'unenrolling' | 'degraded'; -export type AgentActionType = 'POLICY_CHANGE' | 'CONFIG_CHANGE' | 'UNENROLL'; +export type AgentActionType = 'POLICY_CHANGE' | 'UNENROLL'; export interface NewAgentAction { type: AgentActionType; @@ -42,13 +42,24 @@ export interface AgentAction extends NewAgentAction { export interface AgentPolicyAction extends NewAgentAction { id: string; type: AgentActionType; - data?: any; + data: { + policy: FullAgentPolicy; + }; policy_id: string; policy_revision: number; created_at: string; ack_data?: any; } +// Make policy change action renaming BWC with agent version <= 7.9 +// eslint-disable-next-line @typescript-eslint/naming-convention +export type AgentPolicyActionV7_9 = Omit & { + type: 'CONFIG_CHANGE'; + data: { + config: FullAgentPolicy; + }; +}; + interface CommonAgentActionSOAttributes { type: AgentActionType; sent_at?: string; diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index c21d6eaa5fc56..bcbfed07ebca4 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -404,9 +404,8 @@ class AgentPolicyService { }, []); await createAgentPolicyAction(soClient, { - // This is problematic... type: 'POLICY_CHANGE', - data: { config: policy, policy } as any, + data: { policy }, ack_data: { packages }, created_at: new Date().toISOString(), policy_id: policy.id, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts index 3468a27d50529..8bcf275fce6ac 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts @@ -120,7 +120,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', @@ -180,7 +180,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts index ea440551227a9..5055b6f57c8f2 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts @@ -16,6 +16,7 @@ import { Agent, AgentAction, AgentPolicyAction, + AgentPolicyActionV7_9, AgentEvent, AgentEventSOAttributes, AgentSOAttributes, @@ -126,15 +127,17 @@ async function fetchActionsUsingCache( return [...freshActions, ...actions]; } -function isAgentPolicyAction(action: AgentAction | AgentPolicyAction): action is AgentPolicyAction { +function isAgentPolicyAction( + action: AgentAction | AgentPolicyAction | AgentPolicyActionV7_9 +): action is AgentPolicyAction | AgentPolicyActionV7_9 { return (action as AgentPolicyAction).policy_id !== undefined; } function getLatestConfigChangePolicyActionIfUpdated( agent: Agent, - actions: Array -): AgentPolicyAction | null { - return actions.reduce((acc, action) => { + actions: Array +): AgentPolicyAction | AgentPolicyActionV7_9 | null { + return actions.reduce((acc, action) => { if ( !isAgentPolicyAction(action) || (action.type !== 'POLICY_CHANGE' && action.type !== 'CONFIG_CHANGE') || diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts new file mode 100644 index 0000000000000..dd00ba87fded5 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { savedObjectsClientMock } from 'src/core/server/mocks'; +import { createAgentActionFromPolicyAction } from './state_new_actions'; +import { OutputType, Agent, AgentPolicyAction } from '../../../types'; + +jest.mock('../../app_context', () => ({ + appContextService: { + getEncryptedSavedObjects: () => ({ + getDecryptedAsInternalUser: () => ({ + attributes: { + default_api_key: 'MOCK_API_KEY', + }, + }), + }), + }, +})); + +describe('test agent checkin new action services', () => { + describe('createAgentActionFromPolicyAction()', () => { + const mockSavedObjectsClient = savedObjectsClientMock.create(); + const mockAgent: Agent = { + id: 'agent1', + active: true, + type: 'PERMANENT', + local_metadata: { elastic: { agent: { version: '7.10.0' } } }, + user_provided_metadata: {}, + current_error_events: [], + packages: [], + enrolled_at: '2020-03-14T19:45:02.620Z', + }; + const mockPolicyAction: AgentPolicyAction = { + id: 'action1', + type: 'POLICY_CHANGE', + policy_id: 'policy1', + policy_revision: 1, + sent_at: '2020-03-14T19:45:02.620Z', + created_at: '2020-03-14T19:45:02.620Z', + data: { + policy: { + id: 'policy1', + outputs: { + default: { + type: OutputType.Elasticsearch, + hosts: [], + ca_sha256: undefined, + api_key: undefined, + }, + }, + inputs: [], + }, + }, + }; + + it('should return POLICY_CHANGE and data.policy for agent version >= 7.10', async () => { + const expectedResult = [ + { + agent_id: 'agent1', + created_at: '2020-03-14T19:45:02.620Z', + data: { + policy: { + id: 'policy1', + inputs: [], + outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } }, + }, + }, + id: 'action1', + sent_at: '2020-03-14T19:45:02.620Z', + type: 'POLICY_CHANGE', + }, + ]; + + expect( + await createAgentActionFromPolicyAction(mockSavedObjectsClient, mockAgent, mockPolicyAction) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.10.1-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + }); + + it('should return CONNFIG_CHANGE and data.config for agent version <= 7.9', async () => { + const expectedResult = [ + { + agent_id: 'agent1', + created_at: '2020-03-14T19:45:02.620Z', + data: { + config: { + id: 'policy1', + inputs: [], + outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } }, + }, + }, + id: 'action1', + sent_at: '2020-03-14T19:45:02.620Z', + type: 'CONFIG_CHANGE', + }, + ]; + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.0' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.1-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.3' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.8.2' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + }); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts index 4122677a615ca..5185d0d8bde69 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import semver from 'semver'; import { timer, from, Observable, TimeoutError } from 'rxjs'; import { omit } from 'lodash'; import { @@ -17,7 +17,13 @@ import { take, } from 'rxjs/operators'; import { SavedObjectsClientContract, KibanaRequest } from 'src/core/server'; -import { Agent, AgentAction, AgentPolicyAction, AgentSOAttributes } from '../../../types'; +import { + Agent, + AgentAction, + AgentPolicyAction, + AgentPolicyActionV7_9, + AgentSOAttributes, +} from '../../../types'; import * as APIKeysService from '../../api_keys'; import { AGENT_SAVED_OBJECT_TYPE, @@ -104,15 +110,29 @@ async function getOrCreateAgentDefaultOutputAPIKey( return outputAPIKey.key; } -async function createAgentActionFromPolicyAction( +export async function createAgentActionFromPolicyAction( soClient: SavedObjectsClientContract, agent: Agent, policyAction: AgentPolicyAction ) { + // Transform the policy action for agent version <= 7.9 for BWC + const agentVersion = semver.parse((agent.local_metadata?.elastic as any)?.agent?.version); + const agentPolicyAction: AgentPolicyAction | AgentPolicyActionV7_9 = + agentVersion && semver.lt(agentVersion, '7.10.0') + ? { + ...policyAction, + type: 'CONFIG_CHANGE', + data: { + config: policyAction.data.policy, + }, + } + : policyAction; + + // Create agent action const newAgentAction: AgentAction = Object.assign( omit( // Faster than clone - JSON.parse(JSON.stringify(policyAction)) as AgentPolicyAction, + JSON.parse(JSON.stringify(agentPolicyAction)) as AgentPolicyAction, 'policy_id', 'policy_revision' ), @@ -122,10 +142,14 @@ async function createAgentActionFromPolicyAction( ); // Mutate the policy to set the api token for this agent - newAgentAction.data.config.outputs.default.api_key = await getOrCreateAgentDefaultOutputAPIKey( - soClient, - agent - ); + const apiKey = await getOrCreateAgentDefaultOutputAPIKey(soClient, agent); + if (newAgentAction.data.policy) { + newAgentAction.data.policy.outputs.default.api_key = apiKey; + } + // BWC for agent <= 7.9 + else if (newAgentAction.data.config) { + newAgentAction.data.config.outputs.default.api_key = apiKey; + } return [newAgentAction]; } diff --git a/x-pack/plugins/ingest_manager/server/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx index d00491afef72b..b43d6355c479a 100644 --- a/x-pack/plugins/ingest_manager/server/types/index.tsx +++ b/x-pack/plugins/ingest_manager/server/types/index.tsx @@ -17,6 +17,7 @@ export { AgentEventSOAttributes, AgentAction, AgentPolicyAction, + AgentPolicyActionV7_9, BaseAgentActionSOAttributes, AgentActionSOAttributes, AgentPolicyActionSOAttributes, From 2f9ef88daeedd4001bd8e7b1e79804b85398ef2b Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 23 Sep 2020 09:26:54 -0700 Subject: [PATCH 3/4] Fix test --- .../apis/fleet/agents/complete_flow.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts index d4804c6040f57..a59b3ff0890f7 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts @@ -78,7 +78,7 @@ export default function (providerContext: FtrProviderContext) { expect(checkinApiResponse.actions).length(1); expect(checkinApiResponse.actions[0].type).be('POLICY_CHANGE'); const policyChangeAction = checkinApiResponse.actions[0]; - const defaultOutputApiKey = policyChangeAction.data.config.outputs.default.api_key; + const defaultOutputApiKey = policyChangeAction.data.policy.outputs.default.api_key; // Ack actions await supertestWithoutAuth From 894c61e071b75aecaa5f3d54a519a3ad3ada7d7e Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 23 Sep 2020 11:46:15 -0700 Subject: [PATCH 4/4] Add agent action SO migration for policy change actions --- .../ingest_manager/server/saved_objects/index.ts | 4 ++++ .../saved_objects/migrations/to_v7_10_0.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts index e86f7b24e2c78..1074434ced9ad 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts @@ -24,6 +24,7 @@ import { migrateEnrollmentApiKeysToV7100, migratePackagePolicyToV7100, migrateSettingsToV7100, + migrateAgentActionToV7100, } from './migrations/to_v7_10_0'; /* @@ -107,6 +108,9 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { created_at: { type: 'date' }, }, }, + migrations: { + '7.10.0': migrateAgentActionToV7100, + }, }, [AGENT_EVENT_SAVED_OBJECT_TYPE]: { name: AGENT_EVENT_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts index 5e36ce46c099b..53af5ae42e410 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts @@ -12,6 +12,7 @@ import { PackagePolicy, EnrollmentAPIKey, Settings, + AgentAction, } from '../../types'; export const migrateAgentToV7100: SavedObjectMigrationFn< @@ -92,3 +93,18 @@ export const migrateSettingsToV7100: SavedObjectMigrationFn< return settingsDoc; }; + +export const migrateAgentActionToV7100: SavedObjectMigrationFn = ( + agentActionDoc +) => { + // @ts-expect-error + if (agentActionDoc.attributes.type === 'CONFIG_CHANGE') { + agentActionDoc.attributes.type = 'POLICY_CHANGE'; + if (agentActionDoc.attributes.data?.config) { + agentActionDoc.attributes.data.policy = agentActionDoc.attributes.data.config; + delete agentActionDoc.attributes.data.config; + } + } + + return agentActionDoc; +};