Skip to content

Commit 99a5db6

Browse files
EMT-339: add policy response index and documents (#65004)
* EMT-339: add policy response index and documents * EMT-339: add routes, unit and integration tests * EMT-339: review comments, change types, url, update tests
1 parent 6c1f5ec commit 99a5db6

File tree

19 files changed

+1469
-115
lines changed

19 files changed

+1469
-115
lines changed

x-pack/plugins/endpoint/common/generate_data.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ describe('data generator', () => {
4545
expect(metadata.host).not.toBeNull();
4646
});
4747

48+
it('creates policy response documents', () => {
49+
const timestamp = new Date().getTime();
50+
const hostPolicyResponse = generator.generatePolicyResponse(timestamp);
51+
expect(hostPolicyResponse['@timestamp']).toEqual(timestamp);
52+
expect(hostPolicyResponse.event.created).toEqual(timestamp);
53+
expect(hostPolicyResponse.endpoint).not.toBeNull();
54+
expect(hostPolicyResponse.agent).not.toBeNull();
55+
expect(hostPolicyResponse.host).not.toBeNull();
56+
expect(hostPolicyResponse.endpoint.policy.applied).not.toBeNull();
57+
});
58+
4859
it('creates alert event documents', () => {
4960
const timestamp = new Date().getTime();
5061
const alert = generator.generateAlert(timestamp);

x-pack/plugins/endpoint/common/generate_data.ts

Lines changed: 152 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import {
1212
Host,
1313
HostMetadata,
1414
HostOS,
15-
PolicyData,
1615
HostPolicyResponse,
16+
HostPolicyResponseActions,
1717
HostPolicyResponseActionStatus,
18+
PolicyData,
1819
} from './types';
1920
import { factory as policyFactory } from './models/policy_config';
2021

@@ -136,6 +137,13 @@ export class EndpointDocGenerator {
136137
this.commonInfo.host.ip = this.randomArray(3, () => this.randomIP());
137138
}
138139

140+
/**
141+
* Creates new random policy id for the host to simulate new policy application
142+
*/
143+
public updatePolicyId() {
144+
this.commonInfo.endpoint.policy.id = this.randomChoice(POLICIES).id;
145+
}
146+
139147
private createHostData(): HostInfo {
140148
return {
141149
agent: {
@@ -498,106 +506,145 @@ export class EndpointDocGenerator {
498506
/**
499507
* Generates a Host Policy response message
500508
*/
501-
generatePolicyResponse(): HostPolicyResponse {
509+
public generatePolicyResponse(ts = new Date().getTime()): HostPolicyResponse {
510+
const policyVersion = this.seededUUIDv4();
502511
return {
503-
'@timestamp': new Date().toISOString(),
512+
'@timestamp': ts,
513+
agent: {
514+
id: this.commonInfo.agent.id,
515+
version: '1.0.0-local.20200416.0',
516+
},
504517
elastic: {
505518
agent: {
506-
id: 'c2a9093e-e289-4c0a-aa44-8c32a414fa7a',
519+
id: this.commonInfo.elastic.agent.id,
507520
},
508521
},
509522
ecs: {
510-
version: '1.0.0',
511-
},
512-
event: {
513-
created: '2015-01-01T12:10:30Z',
514-
kind: 'policy_response',
523+
version: '1.4.0',
515524
},
516-
agent: {
517-
version: '6.0.0-rc2',
518-
id: '8a4f500d',
525+
host: {
526+
id: this.commonInfo.host.id,
519527
},
520528
endpoint: {
521-
artifacts: {
522-
'global-manifest': {
523-
version: '1.2.3',
524-
sha256: 'abcdef',
525-
},
526-
'endpointpe-v4-windows': {
527-
version: '1.2.3',
528-
sha256: 'abcdef',
529-
},
530-
'user-whitelist-windows': {
531-
version: '1.2.3',
532-
sha256: 'abcdef',
533-
},
534-
'global-whitelist-windows': {
535-
version: '1.2.3',
536-
sha256: 'abcdef',
537-
},
538-
},
539529
policy: {
540530
applied: {
541-
version: '1.0.0',
542-
id: '17d4b81d-9940-4b64-9de5-3e03ef1fb5cf',
543-
status: HostPolicyResponseActionStatus.success,
531+
actions: {
532+
configure_elasticsearch_connection: {
533+
message: 'elasticsearch comms configured successfully',
534+
status: HostPolicyResponseActionStatus.success,
535+
},
536+
configure_kernel: {
537+
message: 'Failed to configure kernel',
538+
status: HostPolicyResponseActionStatus.failure,
539+
},
540+
configure_logging: {
541+
message: 'Successfully configured logging',
542+
status: HostPolicyResponseActionStatus.success,
543+
},
544+
configure_malware: {
545+
message: 'Unexpected error configuring malware',
546+
status: HostPolicyResponseActionStatus.failure,
547+
},
548+
connect_kernel: {
549+
message: 'Successfully initialized minifilter',
550+
status: HostPolicyResponseActionStatus.success,
551+
},
552+
detect_file_open_events: {
553+
message: 'Successfully stopped file open event reporting',
554+
status: HostPolicyResponseActionStatus.success,
555+
},
556+
detect_file_write_events: {
557+
message: 'Failed to stop file write event reporting',
558+
status: HostPolicyResponseActionStatus.success,
559+
},
560+
detect_image_load_events: {
561+
message: 'Successfuly started image load event reporting',
562+
status: HostPolicyResponseActionStatus.success,
563+
},
564+
detect_process_events: {
565+
message: 'Successfully started process event reporting',
566+
status: HostPolicyResponseActionStatus.success,
567+
},
568+
download_global_artifacts: {
569+
message: 'Failed to download EXE model',
570+
status: HostPolicyResponseActionStatus.success,
571+
},
572+
load_config: {
573+
message: 'successfully parsed configuration',
574+
status: HostPolicyResponseActionStatus.success,
575+
},
576+
load_malware_model: {
577+
message: 'Error deserializing EXE model; no valid malware model installed',
578+
status: HostPolicyResponseActionStatus.success,
579+
},
580+
read_elasticsearch_config: {
581+
message: 'Successfully read Elasticsearch configuration',
582+
status: HostPolicyResponseActionStatus.success,
583+
},
584+
read_events_config: {
585+
message: 'Successfully read events configuration',
586+
status: HostPolicyResponseActionStatus.success,
587+
},
588+
read_kernel_config: {
589+
message: 'Succesfully read kernel configuration',
590+
status: HostPolicyResponseActionStatus.success,
591+
},
592+
read_logging_config: {
593+
message: 'field (logging.debugview) not found in config',
594+
status: HostPolicyResponseActionStatus.success,
595+
},
596+
read_malware_config: {
597+
message: 'Successfully read malware detect configuration',
598+
status: HostPolicyResponseActionStatus.success,
599+
},
600+
workflow: {
601+
message: 'Failed to apply a portion of the configuration (kernel)',
602+
status: HostPolicyResponseActionStatus.success,
603+
},
604+
download_model: {
605+
message: 'Failed to apply a portion of the configuration (kernel)',
606+
status: HostPolicyResponseActionStatus.success,
607+
},
608+
ingest_events_config: {
609+
message: 'Failed to apply a portion of the configuration (kernel)',
610+
status: HostPolicyResponseActionStatus.success,
611+
},
612+
},
613+
id: this.commonInfo.endpoint.policy.id,
614+
policy: {
615+
id: this.commonInfo.endpoint.policy.id,
616+
version: policyVersion,
617+
},
544618
response: {
545619
configurations: {
546-
malware: {
547-
status: HostPolicyResponseActionStatus.success,
548-
concerned_actions: ['download_model', 'workflow', 'a_custom_future_action'],
549-
},
550620
events: {
551-
status: HostPolicyResponseActionStatus.success,
552-
concerned_actions: ['ingest_events_config', 'workflow'],
621+
concerned_actions: this.randomHostPolicyResponseActions(),
622+
status: this.randomHostPolicyResponseActionStatus(),
553623
},
554624
logging: {
555-
status: HostPolicyResponseActionStatus.success,
556-
concerned_actions: ['configure_elasticsearch_connection'],
557-
},
558-
streaming: {
559-
status: HostPolicyResponseActionStatus.success,
560-
concerned_actions: [
561-
'detect_file_open_events',
562-
'download_global_artifacts',
563-
'a_custom_future_action',
564-
],
565-
},
566-
},
567-
actions: {
568-
download_model: {
569-
status: HostPolicyResponseActionStatus.success,
570-
message: 'model downloaded',
625+
concerned_actions: this.randomHostPolicyResponseActions(),
626+
status: this.randomHostPolicyResponseActionStatus(),
571627
},
572-
ingest_events_config: {
573-
status: HostPolicyResponseActionStatus.success,
574-
message: 'no action taken',
575-
},
576-
workflow: {
577-
status: HostPolicyResponseActionStatus.success,
578-
message: 'the flow worked well',
579-
},
580-
a_custom_future_action: {
581-
status: HostPolicyResponseActionStatus.success,
582-
message: 'future message',
583-
},
584-
configure_elasticsearch_connection: {
585-
status: HostPolicyResponseActionStatus.success,
586-
message: 'some message',
587-
},
588-
detect_file_open_events: {
589-
status: HostPolicyResponseActionStatus.success,
590-
message: 'some message',
628+
malware: {
629+
concerned_actions: this.randomHostPolicyResponseActions(),
630+
status: this.randomHostPolicyResponseActionStatus(),
591631
},
592-
download_global_artifacts: {
593-
status: HostPolicyResponseActionStatus.success,
594-
message: 'some message',
632+
streaming: {
633+
concerned_actions: this.randomHostPolicyResponseActions(),
634+
status: this.randomHostPolicyResponseActionStatus(),
595635
},
596636
},
597637
},
638+
status: this.randomHostPolicyResponseActionStatus(),
639+
version: policyVersion,
598640
},
599641
},
600642
},
643+
event: {
644+
created: ts,
645+
id: this.seededUUIDv4(),
646+
kind: 'policy_response',
647+
},
601648
};
602649
}
603650

@@ -644,6 +691,34 @@ export class EndpointDocGenerator {
644691
private seededUUIDv4(): string {
645692
return uuid.v4({ random: [...this.randomNGenerator(255, 16)] });
646693
}
694+
695+
private randomHostPolicyResponseActions(): Array<keyof HostPolicyResponseActions> {
696+
return this.randomArray(this.randomN(8), () =>
697+
this.randomChoice([
698+
'load_config',
699+
'workflow',
700+
'download_global_artifacts',
701+
'configure_malware',
702+
'read_malware_config',
703+
'load_malware_model',
704+
'read_kernel_config',
705+
'configure_kernel',
706+
'detect_process_events',
707+
'detect_file_write_events',
708+
'detect_file_open_events',
709+
'detect_image_load_events',
710+
'connect_kernel',
711+
])
712+
);
713+
}
714+
715+
private randomHostPolicyResponseActionStatus(): HostPolicyResponseActionStatus {
716+
return this.randomChoice([
717+
HostPolicyResponseActionStatus.failure,
718+
HostPolicyResponseActionStatus.success,
719+
HostPolicyResponseActionStatus.warning,
720+
]);
721+
}
647722
}
648723

649724
const fakeProcessNames = [
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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 { schema } from '@kbn/config-schema';
7+
8+
export const GetPolicyResponseSchema = {
9+
query: schema.object({
10+
hostId: schema.string(),
11+
}),
12+
};

x-pack/plugins/endpoint/common/types.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -613,15 +613,15 @@ export enum HostPolicyResponseActionStatus {
613613
/**
614614
* The details of a given action
615615
*/
616-
interface HostPolicyResponseActionDetails {
616+
export interface HostPolicyResponseActionDetails {
617617
status: HostPolicyResponseActionStatus;
618618
message: string;
619619
}
620620

621621
/**
622622
* A known list of possible Endpoint actions
623623
*/
624-
interface HostPolicyResponseActions {
624+
export interface HostPolicyResponseActions {
625625
download_model: HostPolicyResponseActionDetails;
626626
ingest_events_config: HostPolicyResponseActionDetails;
627627
workflow: HostPolicyResponseActionDetails;
@@ -642,9 +642,6 @@ interface HostPolicyResponseActions {
642642
read_kernel_config: HostPolicyResponseActionDetails;
643643
read_logging_config: HostPolicyResponseActionDetails;
644644
read_malware_config: HostPolicyResponseActionDetails;
645-
// The list of possible Actions will change rapidly, so the below entry will allow
646-
// them without us defining them here statically
647-
[key: string]: HostPolicyResponseActionDetails;
648645
}
649646

650647
interface HostPolicyResponseConfigurationStatus {
@@ -656,7 +653,7 @@ interface HostPolicyResponseConfigurationStatus {
656653
* Information about the applying of a policy to a given host
657654
*/
658655
export interface HostPolicyResponse {
659-
'@timestamp': string;
656+
'@timestamp': number;
660657
elastic: {
661658
agent: {
662659
id: string;
@@ -665,29 +662,36 @@ export interface HostPolicyResponse {
665662
ecs: {
666663
version: string;
667664
};
665+
host: {
666+
id: string;
667+
};
668668
event: {
669-
created: string;
669+
created: number;
670670
kind: string;
671+
id: string;
671672
};
672673
agent: {
673674
version: string;
674675
id: string;
675676
};
676677
endpoint: {
677-
artifacts: {};
678678
policy: {
679679
applied: {
680680
version: string;
681681
id: string;
682682
status: HostPolicyResponseActionStatus;
683+
actions: Partial<HostPolicyResponseActions>;
684+
policy: {
685+
id: string;
686+
version: string;
687+
};
683688
response: {
684689
configurations: {
685690
malware: HostPolicyResponseConfigurationStatus;
686691
events: HostPolicyResponseConfigurationStatus;
687692
logging: HostPolicyResponseConfigurationStatus;
688693
streaming: HostPolicyResponseConfigurationStatus;
689694
};
690-
actions: Partial<HostPolicyResponseActions>;
691695
};
692696
};
693697
};

0 commit comments

Comments
 (0)