Skip to content

Commit dbb6b1a

Browse files
authored
Adding post create package callback
1 parent f814e0f commit dbb6b1a

File tree

8 files changed

+214
-7
lines changed

8 files changed

+214
-7
lines changed

x-pack/plugins/fleet/server/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export type {
3939
PostPackagePolicyDeleteCallback,
4040
PostPackagePolicyCreateCallback,
4141
FleetRequestHandlerContext,
42+
PostPackagePolicyPostCreateCallback,
4243
} from './types';
4344
export { AgentNotFoundError, FleetUnauthorizedError } from './errors';
4445

x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,38 @@ describe('When calling package policy', () => {
263263
});
264264
});
265265
});
266+
267+
describe('postCreate callback registration', () => {
268+
it('should call to packagePolicyCreate and packagePolicyPostCreate call backs', async () => {
269+
const request = getCreateKibanaRequest();
270+
await routeHandler(context, request, response);
271+
272+
expect(response.ok).toHaveBeenCalled();
273+
expect(packagePolicyService.runExternalCallbacks).toBeCalledTimes(2);
274+
275+
const firstCB = packagePolicyServiceMock.runExternalCallbacks.mock.calls[0][0];
276+
const secondCB = packagePolicyServiceMock.runExternalCallbacks.mock.calls[1][0];
277+
278+
expect(firstCB).toEqual('packagePolicyCreate');
279+
expect(secondCB).toEqual('packagePolicyPostCreate');
280+
});
281+
282+
it('should not call packagePolicyPostCreate call back in case of packagePolicy create failed', async () => {
283+
const request = getCreateKibanaRequest();
284+
285+
packagePolicyServiceMock.create.mockImplementationOnce(
286+
async (soClient, esClient, newData) => {
287+
throw new Error('foo');
288+
}
289+
);
290+
291+
await routeHandler(context, request, response);
292+
const firstCB = packagePolicyServiceMock.runExternalCallbacks.mock.calls[0][0];
293+
294+
expect(firstCB).toEqual('packagePolicyCreate');
295+
expect(packagePolicyService.runExternalCallbacks).toBeCalledTimes(1);
296+
});
297+
});
266298
});
267299

268300
describe('update api handler', () => {

x-pack/plugins/fleet/server/routes/package_policy/handlers.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,16 @@ export const createPackagePolicyHandler: FleetRequestHandler<
110110
force,
111111
spaceId,
112112
});
113-
const body: CreatePackagePolicyResponse = { item: packagePolicy };
113+
114+
const enrichedPackagePolicy = await packagePolicyService.runExternalCallbacks(
115+
'packagePolicyPostCreate',
116+
packagePolicy,
117+
context,
118+
request
119+
);
120+
121+
const body: CreatePackagePolicyResponse = { item: enrichedPackagePolicy };
122+
114123
return response.ok({
115124
body,
116125
});

x-pack/plugins/fleet/server/services/app_context.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import type {
2929
ExternalCallbacksStorage,
3030
PostPackagePolicyCreateCallback,
3131
PostPackagePolicyDeleteCallback,
32+
PostPackagePolicyPostCreateCallback,
3233
PutPackagePolicyUpdateCallback,
3334
} from '../types';
3435
import type { FleetAppContext } from '../plugin';
@@ -183,6 +184,8 @@ class AppContextService {
183184
? PostPackagePolicyCreateCallback
184185
: T extends 'postPackagePolicyDelete'
185186
? PostPackagePolicyDeleteCallback
187+
: T extends 'packagePolicyPostCreate'
188+
? PostPackagePolicyPostCreateCallback
186189
: PutPackagePolicyUpdateCallback
187190
>
188191
| undefined {
@@ -192,6 +195,8 @@ class AppContextService {
192195
? PostPackagePolicyCreateCallback
193196
: T extends 'postPackagePolicyDelete'
194197
? PostPackagePolicyDeleteCallback
198+
: T extends 'packagePolicyPostCreate'
199+
? PostPackagePolicyPostCreateCallback
195200
: PutPackagePolicyUpdateCallback
196201
>;
197202
}

x-pack/plugins/fleet/server/services/package_policy.test.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {
2626
RegistryDataStream,
2727
PackagePolicyInputStream,
2828
PackagePolicy,
29+
PostPackagePolicyPostCreateCallback,
2930
} from '../types';
3031
import { createPackagePolicyMock } from '../../common/mocks';
3132

@@ -1356,6 +1357,100 @@ describe('Package policy service', () => {
13561357
});
13571358
});
13581359

1360+
describe('runPostPackagePolicyPostCreateCallback', () => {
1361+
let context: ReturnType<typeof xpackMocks.createRequestHandlerContext>;
1362+
let request: KibanaRequest;
1363+
const packagePolicy = {
1364+
id: '93ac25fe-0467-4fcc-a3c5-57a26a8496e2',
1365+
version: 'WzYyMzcsMV0=',
1366+
name: 'my-cis_kubernetes_benchmark',
1367+
namespace: 'default',
1368+
description: '',
1369+
package: {
1370+
name: 'cis_kubernetes_benchmark',
1371+
title: 'CIS Kubernetes Benchmark',
1372+
version: '0.0.3',
1373+
},
1374+
enabled: true,
1375+
policy_id: '1e6d0690-b995-11ec-a355-d35391e25881',
1376+
output_id: '',
1377+
inputs: [
1378+
{
1379+
type: 'cloudbeat',
1380+
policy_template: 'findings',
1381+
enabled: true,
1382+
streams: [
1383+
{
1384+
enabled: true,
1385+
data_stream: {
1386+
type: 'logs',
1387+
dataset: 'cis_kubernetes_benchmark.findings',
1388+
},
1389+
id: 'cloudbeat-cis_kubernetes_benchmark.findings-66b402b3-f24a-4018-b3d0-b88582a836ab',
1390+
compiled_stream: {
1391+
processors: [
1392+
{
1393+
add_cluster_id: null,
1394+
},
1395+
],
1396+
},
1397+
},
1398+
],
1399+
},
1400+
],
1401+
vars: {
1402+
dataYaml: {
1403+
type: 'yaml',
1404+
},
1405+
},
1406+
elasticsearch: undefined,
1407+
revision: 1,
1408+
created_at: '2022-04-11T12:44:43.385Z',
1409+
created_by: 'elastic',
1410+
updated_at: '2022-04-11T12:44:43.385Z',
1411+
updated_by: 'elastic',
1412+
};
1413+
const callbackCallingOrder: string[] = [];
1414+
1415+
beforeEach(() => {
1416+
context = xpackMocks.createRequestHandlerContext();
1417+
request = httpServerMock.createKibanaRequest();
1418+
appContextService.start(createAppContextStartContractMock());
1419+
});
1420+
1421+
afterEach(() => {
1422+
appContextService.stop();
1423+
jest.clearAllMocks();
1424+
callbackCallingOrder.length = 0;
1425+
});
1426+
1427+
it('should execute PostPackagePolicyPostCreateCallback external callbacks', async () => {
1428+
const callbackA: PostPackagePolicyPostCreateCallback = jest.fn(async (ds) => {
1429+
callbackCallingOrder.push('a');
1430+
return ds;
1431+
});
1432+
1433+
const callbackB: PostPackagePolicyPostCreateCallback = jest.fn(async (ds) => {
1434+
callbackCallingOrder.push('b');
1435+
return ds;
1436+
});
1437+
1438+
appContextService.addExternalCallback('packagePolicyPostCreate', callbackA);
1439+
appContextService.addExternalCallback('packagePolicyPostCreate', callbackB);
1440+
1441+
await packagePolicyService.runExternalCallbacks(
1442+
'packagePolicyPostCreate',
1443+
packagePolicy,
1444+
context,
1445+
request
1446+
);
1447+
1448+
expect(callbackA).toHaveBeenCalledWith(packagePolicy, context, request);
1449+
expect(callbackB).toHaveBeenCalledWith(packagePolicy, context, request);
1450+
expect(callbackCallingOrder).toEqual(['a', 'b']);
1451+
});
1452+
});
1453+
13591454
describe('preconfigurePackageInputs', () => {
13601455
describe('when variable is already defined', () => {
13611456
it('override original variable value', () => {

x-pack/plugins/fleet/server/services/package_policy.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ import {
5353
PackagePolicyIneligibleForUpgradeError,
5454
PackagePolicyValidationError,
5555
} from '../errors';
56-
import { NewPackagePolicySchema, UpdatePackagePolicySchema } from '../types';
56+
import { NewPackagePolicySchema, PackagePolicySchema, UpdatePackagePolicySchema } from '../types';
5757
import type {
5858
NewPackagePolicy,
5959
UpdatePackagePolicy,
6060
PackagePolicy,
6161
PackagePolicySOAttributes,
6262
DryRunPackagePolicy,
63+
PostPackagePolicyCreateCallback,
64+
PostPackagePolicyPostCreateCallback,
6365
} from '../types';
6466
import type { ExternalCallback } from '..';
6567

@@ -869,16 +871,24 @@ class PackagePolicyService implements PackagePolicyServiceInterface {
869871
externalCallbackType: A,
870872
packagePolicy: A extends 'postPackagePolicyDelete'
871873
? DeletePackagePoliciesResponse
874+
: A extends 'packagePolicyPostCreate'
875+
? PackagePolicy
872876
: NewPackagePolicy,
873877
context: RequestHandlerContext,
874878
request: KibanaRequest
875-
): Promise<A extends 'postPackagePolicyDelete' ? void : NewPackagePolicy>;
879+
): Promise<
880+
A extends 'postPackagePolicyDelete'
881+
? void
882+
: A extends 'packagePolicyPostCreate'
883+
? PackagePolicy
884+
: NewPackagePolicy
885+
>;
876886
public async runExternalCallbacks(
877887
externalCallbackType: ExternalCallback[0],
878-
packagePolicy: NewPackagePolicy | DeletePackagePoliciesResponse,
888+
packagePolicy: PackagePolicy | NewPackagePolicy | DeletePackagePoliciesResponse,
879889
context: RequestHandlerContext,
880890
request: KibanaRequest
881-
): Promise<NewPackagePolicy | void> {
891+
): Promise<PackagePolicy | NewPackagePolicy | void> {
882892
if (externalCallbackType === 'postPackagePolicyDelete') {
883893
return await this.runDeleteExternalCallbacks(packagePolicy as DeletePackagePoliciesResponse);
884894
} else {
@@ -888,7 +898,21 @@ class PackagePolicyService implements PackagePolicyServiceInterface {
888898
if (externalCallbacks && externalCallbacks.size > 0) {
889899
let updatedNewData = newData;
890900
for (const callback of externalCallbacks) {
891-
const result = await callback(updatedNewData, context, request);
901+
let result;
902+
if (externalCallbackType === 'packagePolicyPostCreate') {
903+
result = await (callback as PostPackagePolicyPostCreateCallback)(
904+
updatedNewData as PackagePolicy,
905+
context,
906+
request
907+
);
908+
updatedNewData = PackagePolicySchema.validate(result);
909+
} else {
910+
result = await (callback as PostPackagePolicyCreateCallback)(
911+
updatedNewData as NewPackagePolicy,
912+
context,
913+
request
914+
);
915+
}
892916
if (externalCallbackType === 'packagePolicyCreate') {
893917
updatedNewData = NewPackagePolicySchema.validate(result);
894918
} else if (externalCallbackType === 'packagePolicyUpdate') {
@@ -1276,10 +1300,18 @@ export interface PackagePolicyServiceInterface {
12761300
externalCallbackType: A,
12771301
packagePolicy: A extends 'postPackagePolicyDelete'
12781302
? DeletePackagePoliciesResponse
1303+
: A extends 'packagePolicyPostCreate'
1304+
? PackagePolicy
12791305
: NewPackagePolicy,
12801306
context: RequestHandlerContext,
12811307
request: KibanaRequest
1282-
): Promise<A extends 'postPackagePolicyDelete' ? void : NewPackagePolicy>;
1308+
): Promise<
1309+
A extends 'postPackagePolicyDelete'
1310+
? void
1311+
: A extends 'packagePolicyPostCreate'
1312+
? PackagePolicy
1313+
: NewPackagePolicy
1314+
>;
12831315

12841316
runDeleteExternalCallbacks(deletedPackagePolicies: DeletePackagePoliciesResponse): Promise<void>;
12851317

x-pack/plugins/fleet/server/types/extensions.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
DeletePackagePoliciesResponse,
1414
NewPackagePolicy,
1515
UpdatePackagePolicy,
16+
PackagePolicy,
1617
} from '../../common';
1718

1819
export type PostPackagePolicyDeleteCallback = (
@@ -25,13 +26,23 @@ export type PostPackagePolicyCreateCallback = (
2526
request: KibanaRequest
2627
) => Promise<NewPackagePolicy>;
2728

29+
export type PostPackagePolicyPostCreateCallback = (
30+
packagePolicy: PackagePolicy,
31+
context: RequestHandlerContext,
32+
request: KibanaRequest
33+
) => Promise<PackagePolicy>;
34+
2835
export type PutPackagePolicyUpdateCallback = (
2936
updatePackagePolicy: UpdatePackagePolicy,
3037
context: RequestHandlerContext,
3138
request: KibanaRequest
3239
) => Promise<UpdatePackagePolicy>;
3340

3441
export type ExternalCallbackCreate = ['packagePolicyCreate', PostPackagePolicyCreateCallback];
42+
export type ExternalCallbackPostCreate = [
43+
'packagePolicyPostCreate',
44+
PostPackagePolicyPostCreateCallback
45+
];
3546
export type ExternalCallbackDelete = ['postPackagePolicyDelete', PostPackagePolicyDeleteCallback];
3647
export type ExternalCallbackUpdate = ['packagePolicyUpdate', PutPackagePolicyUpdateCallback];
3748

@@ -40,6 +51,7 @@ export type ExternalCallbackUpdate = ['packagePolicyUpdate', PutPackagePolicyUpd
4051
*/
4152
export type ExternalCallback =
4253
| ExternalCallbackCreate
54+
| ExternalCallbackPostCreate
4355
| ExternalCallbackDelete
4456
| ExternalCallbackUpdate;
4557

x-pack/plugins/fleet/server/types/models/package_policy.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const PackagePolicyStreamsSchema = {
5555
})
5656
)
5757
),
58+
compiled_stream: schema.maybe(schema.any()),
5859
};
5960

6061
const PackagePolicyInputsSchema = {
@@ -150,4 +151,24 @@ export const PackagePolicySchema = schema.object({
150151
...PackagePolicyBaseSchema,
151152
id: schema.string(),
152153
version: schema.maybe(schema.string()),
154+
revision: schema.number(),
155+
updated_at: schema.string(),
156+
updated_by: schema.string(),
157+
created_at: schema.string(),
158+
created_by: schema.string(),
159+
elasticsearch: schema.maybe(
160+
schema.object({
161+
privileges: schema.maybe(
162+
schema.object({
163+
cluster: schema.maybe(schema.arrayOf(schema.string())),
164+
})
165+
),
166+
})
167+
),
168+
inputs: schema.arrayOf(
169+
schema.object({
170+
...PackagePolicyInputsSchema,
171+
compiled_input: schema.maybe(schema.any()),
172+
})
173+
),
153174
});

0 commit comments

Comments
 (0)