Skip to content

Commit 9c849fa

Browse files
committed
Make policy change action BWC with agent <= 7.9
1 parent 4a4e634 commit 9c849fa

7 files changed

Lines changed: 213 additions & 19 deletions

File tree

x-pack/plugins/ingest_manager/common/types/models/agent.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* or more contributor license agreements. Licensed under the Elastic License;
44
* you may not use this file except in compliance with the Elastic License.
55
*/
6-
6+
import { FullAgentPolicy } from './agent_policy';
77
import { AGENT_TYPE_EPHEMERAL, AGENT_TYPE_PERMANENT, AGENT_TYPE_TEMPORARY } from '../../constants';
88

99
export type AgentType =
@@ -21,7 +21,7 @@ export type AgentStatus =
2121
| 'unenrolling'
2222
| 'degraded';
2323

24-
export type AgentActionType = 'POLICY_CHANGE' | 'CONFIG_CHANGE' | 'UNENROLL';
24+
export type AgentActionType = 'POLICY_CHANGE' | 'UNENROLL';
2525

2626
export interface NewAgentAction {
2727
type: AgentActionType;
@@ -42,13 +42,24 @@ export interface AgentAction extends NewAgentAction {
4242
export interface AgentPolicyAction extends NewAgentAction {
4343
id: string;
4444
type: AgentActionType;
45-
data?: any;
45+
data: {
46+
policy: FullAgentPolicy;
47+
};
4648
policy_id: string;
4749
policy_revision: number;
4850
created_at: string;
4951
ack_data?: any;
5052
}
5153

54+
// Make policy change action renaming BWC with agent version <= 7.9
55+
// eslint-disable-next-line @typescript-eslint/naming-convention
56+
export type AgentPolicyActionV7_9 = Omit<AgentPolicyAction, 'type' | 'data'> & {
57+
type: 'CONFIG_CHANGE';
58+
data: {
59+
config: FullAgentPolicy;
60+
};
61+
};
62+
5263
interface CommonAgentActionSOAttributes {
5364
type: AgentActionType;
5465
sent_at?: string;

x-pack/plugins/ingest_manager/server/services/agent_policy.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,8 @@ class AgentPolicyService {
404404
}, []);
405405

406406
await createAgentPolicyAction(soClient, {
407-
// This is problematic...
408407
type: 'POLICY_CHANGE',
409-
data: { config: policy, policy } as any,
408+
data: { policy },
410409
ack_data: { packages },
411410
created_at: new Date().toISOString(),
412411
policy_id: policy.id,

x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ describe('test agent acks services', () => {
120120
const mockSavedObjectsClient = savedObjectsClientMock.create();
121121

122122
const actionAttributes = {
123-
type: 'CONFIG_CHANGE',
123+
type: 'POLICY_CHANGE',
124124
policy_id: 'policy1',
125125
policy_revision: 4,
126126
sent_at: '2020-03-14T19:45:02.620Z',
@@ -180,7 +180,7 @@ describe('test agent acks services', () => {
180180
const mockSavedObjectsClient = savedObjectsClientMock.create();
181181

182182
const actionAttributes = {
183-
type: 'CONFIG_CHANGE',
183+
type: 'POLICY_CHANGE',
184184
policy_id: 'policy1',
185185
policy_revision: 4,
186186
sent_at: '2020-03-14T19:45:02.620Z',

x-pack/plugins/ingest_manager/server/services/agents/acks.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
Agent,
1717
AgentAction,
1818
AgentPolicyAction,
19+
AgentPolicyActionV7_9,
1920
AgentEvent,
2021
AgentEventSOAttributes,
2122
AgentSOAttributes,
@@ -126,15 +127,17 @@ async function fetchActionsUsingCache(
126127
return [...freshActions, ...actions];
127128
}
128129

129-
function isAgentPolicyAction(action: AgentAction | AgentPolicyAction): action is AgentPolicyAction {
130+
function isAgentPolicyAction(
131+
action: AgentAction | AgentPolicyAction | AgentPolicyActionV7_9
132+
): action is AgentPolicyAction | AgentPolicyActionV7_9 {
130133
return (action as AgentPolicyAction).policy_id !== undefined;
131134
}
132135

133136
function getLatestConfigChangePolicyActionIfUpdated(
134137
agent: Agent,
135-
actions: Array<AgentAction | AgentPolicyAction>
136-
): AgentPolicyAction | null {
137-
return actions.reduce<null | AgentPolicyAction>((acc, action) => {
138+
actions: Array<AgentAction | AgentPolicyAction | AgentPolicyActionV7_9>
139+
): AgentPolicyAction | AgentPolicyActionV7_9 | null {
140+
return actions.reduce<null | AgentPolicyAction | AgentPolicyActionV7_9>((acc, action) => {
138141
if (
139142
!isAgentPolicyAction(action) ||
140143
(action.type !== 'POLICY_CHANGE' && action.type !== 'CONFIG_CHANGE') ||
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import { savedObjectsClientMock } from 'src/core/server/mocks';
7+
import { createAgentActionFromPolicyAction } from './state_new_actions';
8+
import { OutputType, Agent, AgentPolicyAction } from '../../../types';
9+
10+
jest.mock('../../app_context', () => ({
11+
appContextService: {
12+
getEncryptedSavedObjects: () => ({
13+
getDecryptedAsInternalUser: () => ({
14+
attributes: {
15+
default_api_key: 'MOCK_API_KEY',
16+
},
17+
}),
18+
}),
19+
},
20+
}));
21+
22+
describe('test agent checkin new action services', () => {
23+
describe('createAgentActionFromPolicyAction()', () => {
24+
const mockSavedObjectsClient = savedObjectsClientMock.create();
25+
const mockAgent: Agent = {
26+
id: 'agent1',
27+
active: true,
28+
type: 'PERMANENT',
29+
local_metadata: { elastic: { agent: { version: '7.10.0' } } },
30+
user_provided_metadata: {},
31+
current_error_events: [],
32+
packages: [],
33+
enrolled_at: '2020-03-14T19:45:02.620Z',
34+
};
35+
const mockPolicyAction: AgentPolicyAction = {
36+
id: 'action1',
37+
type: 'POLICY_CHANGE',
38+
policy_id: 'policy1',
39+
policy_revision: 1,
40+
sent_at: '2020-03-14T19:45:02.620Z',
41+
created_at: '2020-03-14T19:45:02.620Z',
42+
data: {
43+
policy: {
44+
id: 'policy1',
45+
outputs: {
46+
default: {
47+
type: OutputType.Elasticsearch,
48+
hosts: [],
49+
ca_sha256: undefined,
50+
api_key: undefined,
51+
},
52+
},
53+
inputs: [],
54+
},
55+
},
56+
};
57+
58+
it('should return POLICY_CHANGE and data.policy for agent version >= 7.10', async () => {
59+
const expectedResult = [
60+
{
61+
agent_id: 'agent1',
62+
created_at: '2020-03-14T19:45:02.620Z',
63+
data: {
64+
policy: {
65+
id: 'policy1',
66+
inputs: [],
67+
outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } },
68+
},
69+
},
70+
id: 'action1',
71+
sent_at: '2020-03-14T19:45:02.620Z',
72+
type: 'POLICY_CHANGE',
73+
},
74+
];
75+
76+
expect(
77+
await createAgentActionFromPolicyAction(mockSavedObjectsClient, mockAgent, mockPolicyAction)
78+
).toEqual(expectedResult);
79+
80+
expect(
81+
await createAgentActionFromPolicyAction(
82+
mockSavedObjectsClient,
83+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '7.10.1-SNAPSHOT' } } } },
84+
mockPolicyAction
85+
)
86+
).toEqual(expectedResult);
87+
88+
expect(
89+
await createAgentActionFromPolicyAction(
90+
mockSavedObjectsClient,
91+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0' } } } },
92+
mockPolicyAction
93+
)
94+
).toEqual(expectedResult);
95+
96+
expect(
97+
await createAgentActionFromPolicyAction(
98+
mockSavedObjectsClient,
99+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0-SNAPSHOT' } } } },
100+
mockPolicyAction
101+
)
102+
).toEqual(expectedResult);
103+
});
104+
105+
it('should return CONNFIG_CHANGE and data.config for agent version <= 7.9', async () => {
106+
const expectedResult = [
107+
{
108+
agent_id: 'agent1',
109+
created_at: '2020-03-14T19:45:02.620Z',
110+
data: {
111+
config: {
112+
id: 'policy1',
113+
inputs: [],
114+
outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } },
115+
},
116+
},
117+
id: 'action1',
118+
sent_at: '2020-03-14T19:45:02.620Z',
119+
type: 'CONFIG_CHANGE',
120+
},
121+
];
122+
123+
expect(
124+
await createAgentActionFromPolicyAction(
125+
mockSavedObjectsClient,
126+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.0' } } } },
127+
mockPolicyAction
128+
)
129+
).toEqual(expectedResult);
130+
131+
expect(
132+
await createAgentActionFromPolicyAction(
133+
mockSavedObjectsClient,
134+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.1-SNAPSHOT' } } } },
135+
mockPolicyAction
136+
)
137+
).toEqual(expectedResult);
138+
139+
expect(
140+
await createAgentActionFromPolicyAction(
141+
mockSavedObjectsClient,
142+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.3' } } } },
143+
mockPolicyAction
144+
)
145+
).toEqual(expectedResult);
146+
147+
expect(
148+
await createAgentActionFromPolicyAction(
149+
mockSavedObjectsClient,
150+
{ ...mockAgent, local_metadata: { elastic: { agent: { version: '7.8.2' } } } },
151+
mockPolicyAction
152+
)
153+
).toEqual(expectedResult);
154+
});
155+
});
156+
});

x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* or more contributor license agreements. Licensed under the Elastic License;
44
* you may not use this file except in compliance with the Elastic License.
55
*/
6-
6+
import semver from 'semver';
77
import { timer, from, Observable, TimeoutError } from 'rxjs';
88
import { omit } from 'lodash';
99
import {
@@ -17,7 +17,13 @@ import {
1717
take,
1818
} from 'rxjs/operators';
1919
import { SavedObjectsClientContract, KibanaRequest } from 'src/core/server';
20-
import { Agent, AgentAction, AgentPolicyAction, AgentSOAttributes } from '../../../types';
20+
import {
21+
Agent,
22+
AgentAction,
23+
AgentPolicyAction,
24+
AgentPolicyActionV7_9,
25+
AgentSOAttributes,
26+
} from '../../../types';
2127
import * as APIKeysService from '../../api_keys';
2228
import {
2329
AGENT_SAVED_OBJECT_TYPE,
@@ -104,15 +110,29 @@ async function getOrCreateAgentDefaultOutputAPIKey(
104110
return outputAPIKey.key;
105111
}
106112

107-
async function createAgentActionFromPolicyAction(
113+
export async function createAgentActionFromPolicyAction(
108114
soClient: SavedObjectsClientContract,
109115
agent: Agent,
110116
policyAction: AgentPolicyAction
111117
) {
118+
// Transform the policy action for agent version <= 7.9 for BWC
119+
const agentVersion = semver.parse((agent.local_metadata?.elastic as any)?.agent?.version);
120+
const agentPolicyAction: AgentPolicyAction | AgentPolicyActionV7_9 =
121+
agentVersion && semver.lt(agentVersion, '7.10.0')
122+
? {
123+
...policyAction,
124+
type: 'CONFIG_CHANGE',
125+
data: {
126+
config: policyAction.data.policy,
127+
},
128+
}
129+
: policyAction;
130+
131+
// Create agent action
112132
const newAgentAction: AgentAction = Object.assign(
113133
omit(
114134
// Faster than clone
115-
JSON.parse(JSON.stringify(policyAction)) as AgentPolicyAction,
135+
JSON.parse(JSON.stringify(agentPolicyAction)) as AgentPolicyAction,
116136
'policy_id',
117137
'policy_revision'
118138
),
@@ -122,10 +142,14 @@ async function createAgentActionFromPolicyAction(
122142
);
123143

124144
// Mutate the policy to set the api token for this agent
125-
newAgentAction.data.config.outputs.default.api_key = await getOrCreateAgentDefaultOutputAPIKey(
126-
soClient,
127-
agent
128-
);
145+
const apiKey = await getOrCreateAgentDefaultOutputAPIKey(soClient, agent);
146+
if (newAgentAction.data.policy) {
147+
newAgentAction.data.policy.outputs.default.api_key = apiKey;
148+
}
149+
// BWC for agent <= 7.9
150+
else if (newAgentAction.data.config) {
151+
newAgentAction.data.config.outputs.default.api_key = apiKey;
152+
}
129153

130154
return [newAgentAction];
131155
}

x-pack/plugins/ingest_manager/server/types/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export {
1717
AgentEventSOAttributes,
1818
AgentAction,
1919
AgentPolicyAction,
20+
AgentPolicyActionV7_9,
2021
BaseAgentActionSOAttributes,
2122
AgentActionSOAttributes,
2223
AgentPolicyActionSOAttributes,

0 commit comments

Comments
 (0)