Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EMT-339: add new policy response schema #66264

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 76 additions & 32 deletions x-pack/plugins/endpoint/common/generate_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
HostMetadata,
HostOS,
HostPolicyResponse,
HostPolicyResponseActions,
HostPolicyResponseActionStatus,
PolicyData,
} from './types';
Expand Down Expand Up @@ -564,88 +563,108 @@ export class EndpointDocGenerator {
endpoint: {
policy: {
applied: {
actions: {
configure_elasticsearch_connection: {
message: 'elasticsearch communications configured successfully',
actions: [
{
name: 'configure_elasticsearch_connection',
message: 'elasticsearch comes configured successfully',
status: HostPolicyResponseActionStatus.success,
},
configure_kernel: {
{
name: 'configure_kernel',
message: 'Failed to configure kernel',
status: HostPolicyResponseActionStatus.failure,
},
configure_logging: {
{
name: 'configure_logging',
message: 'Successfully configured logging',
status: HostPolicyResponseActionStatus.success,
},
configure_malware: {
{
name: 'configure_malware',
message: 'Unexpected error configuring malware',
status: HostPolicyResponseActionStatus.failure,
},
connect_kernel: {
{
name: 'connect_kernel',
message: 'Successfully initialized minifilter',
status: HostPolicyResponseActionStatus.success,
},
detect_file_open_events: {
{
name: 'detect_file_open_events',
message: 'Successfully stopped file open event reporting',
status: HostPolicyResponseActionStatus.success,
},
detect_file_write_events: {
{
name: 'detect_file_write_events',
message: 'Failed to stop file write event reporting',
status: HostPolicyResponseActionStatus.success,
},
detect_image_load_events: {
{
name: 'detect_image_load_events',
message: 'Successfully started image load event reporting',
status: HostPolicyResponseActionStatus.success,
},
detect_process_events: {
{
name: 'detect_process_events',
message: 'Successfully started process event reporting',
status: HostPolicyResponseActionStatus.success,
},
download_global_artifacts: {
message: 'Succesfully downloaded global artifacts',
{
name: 'download_global_artifacts',
message: 'Failed to download EXE model',
status: HostPolicyResponseActionStatus.success,
},
load_config: {
{
name: 'load_config',
message: 'Successfully parsed configuration',
status: HostPolicyResponseActionStatus.success,
},
load_malware_model: {
message: 'Successfully loaded malware model',
{
name: 'load_malware_mode',
message: 'Error deserializing EXE model; no valid malware model installed',
status: HostPolicyResponseActionStatus.success,
},
read_elasticsearch_config: {
{
name: 'read_elasticsearch_config',
message: 'Successfully read Elasticsearch configuration',
status: HostPolicyResponseActionStatus.success,
},
read_events_config: {
{
name: 'read_events_config',
message: 'Successfully read events configuration',
status: HostPolicyResponseActionStatus.success,
},
read_kernel_config: {
{
name: 'read_kernel_config',
message: 'Succesfully read kernel configuration',
status: HostPolicyResponseActionStatus.success,
},
read_logging_config: {
message: 'field (logging.debugview) not found in config',
{
name: 'read_logging_config',
message: 'Field (logging.debugview) not found in config',
status: HostPolicyResponseActionStatus.success,
},
read_malware_config: {
{
name: 'read_malware_config',
message: 'Successfully read malware detect configuration',
status: HostPolicyResponseActionStatus.success,
},
workflow: {
{
name: 'workflow',
message: 'Failed to apply a portion of the configuration (kernel)',
status: HostPolicyResponseActionStatus.success,
},
download_model: {
{
name: 'download_model',
message: 'Failed to apply a portion of the configuration (kernel)',
status: HostPolicyResponseActionStatus.success,
},
ingest_events_config: {
{
name: 'ingest_events_config',
message: 'Failed to apply a portion of the configuration (kernel)',
status: HostPolicyResponseActionStatus.success,
},
},
],
id: this.commonInfo.endpoint.policy.id,
policy: {
id: this.commonInfo.endpoint.policy.id,
Expand All @@ -658,19 +677,39 @@ export class EndpointDocGenerator {
status: status(),
},
logging: {
concerned_actions: this.randomHostPolicyResponseActions(),
concerned_actions: this.randomHostPolicyResponseActionNames(),
status: status(),
},
malware: {
concerned_actions: this.randomHostPolicyResponseActions(),
concerned_actions: this.randomHostPolicyResponseActionNames(),
status: status(),
},
streaming: {
concerned_actions: this.randomHostPolicyResponseActions(),
concerned_actions: this.randomHostPolicyResponseActionNames(),
status: status(),
},
},
},
artifacts: {
global: {
version: '1.4.0',
identifiers: [
{
name: 'endpointpe-model',
sha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
},
],
},
user: {
version: '1.4.0',
identifiers: [
{
name: 'user-model',
sha256: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
},
],
},
},
status: this.randomHostPolicyResponseActionStatus(),
version: policyVersion,
},
Expand All @@ -679,7 +718,12 @@ export class EndpointDocGenerator {
event: {
created: ts,
id: this.seededUUIDv4(),
kind: 'policy_response',
kind: 'state',
category: 'host',
type: 'change',
module: 'endpoint',
action: 'endpoint_policy_response',
dataset: 'endpoint.policy',
},
};
}
Expand Down Expand Up @@ -728,7 +772,7 @@ export class EndpointDocGenerator {
return uuid.v4({ random: [...this.randomNGenerator(255, 16)] });
}

private randomHostPolicyResponseActions(): Array<keyof HostPolicyResponseActions> {
private randomHostPolicyResponseActionNames(): string[] {
return this.randomArray(this.randomN(8), () =>
this.randomChoice([
'load_config',
Expand Down
85 changes: 53 additions & 32 deletions x-pack/plugins/endpoint/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,47 +611,53 @@ export enum HostPolicyResponseActionStatus {
}

/**
* The details of a given action
* The name of actions that can be applied during the processing of a policy
*/
export interface HostPolicyResponseActionDetails {
status: HostPolicyResponseActionStatus;
message: string;
}
type HostPolicyActionName =
| 'download_model'
| 'ingest_events_config'
| 'workflow'
| 'configure_elasticsearch_connection'
| 'configure_kernel'
| 'configure_logging'
| 'configure_malware'
| 'connect_kernel'
| 'detect_file_open_events'
| 'detect_file_write_events'
| 'detect_image_load_events'
| 'detect_process_events'
| 'download_global_artifacts'
| 'load_config'
| 'load_malware_model'
| 'read_elasticsearch_config'
| 'read_events_config'
| 'read_kernel_config'
| 'read_logging_config'
| 'read_malware_config'
| string;

/**
* A known list of possible Endpoint actions
* Host Policy Response Applied Action
*/
export interface HostPolicyResponseActions {
download_model: HostPolicyResponseActionDetails;
ingest_events_config: HostPolicyResponseActionDetails;
workflow: HostPolicyResponseActionDetails;
configure_elasticsearch_connection: HostPolicyResponseActionDetails;
configure_kernel: HostPolicyResponseActionDetails;
configure_logging: HostPolicyResponseActionDetails;
configure_malware: HostPolicyResponseActionDetails;
connect_kernel: HostPolicyResponseActionDetails;
detect_file_open_events: HostPolicyResponseActionDetails;
detect_file_write_events: HostPolicyResponseActionDetails;
detect_image_load_events: HostPolicyResponseActionDetails;
detect_process_events: HostPolicyResponseActionDetails;
download_global_artifacts: HostPolicyResponseActionDetails;
load_config: HostPolicyResponseActionDetails;
load_malware_model: HostPolicyResponseActionDetails;
read_elasticsearch_config: HostPolicyResponseActionDetails;
read_events_config: HostPolicyResponseActionDetails;
read_kernel_config: HostPolicyResponseActionDetails;
read_logging_config: HostPolicyResponseActionDetails;
read_malware_config: HostPolicyResponseActionDetails;
export interface HostPolicyResponseAppliedAction {
name: HostPolicyActionName;
status: HostPolicyResponseActionStatus;
message: string;
}

/**
* policy configurations returned by the endpoint in response to a user applying a policy
*/
export type HostPolicyResponseConfiguration = HostPolicyResponse['endpoint']['policy']['applied']['response']['configurations'];

interface HostPolicyResponseConfigurationStatus {
status: HostPolicyResponseActionStatus;
concerned_actions: Array<keyof HostPolicyResponseActions>;
concerned_actions: HostPolicyActionName[];
}

/**
* Host Policy Response Applied Artifact
*/
interface HostPolicyResponseAppliedArtifact {
name: string;
sha256: string;
}

/**
Expand All @@ -674,6 +680,11 @@ export interface HostPolicyResponse {
created: number;
kind: string;
id: string;
category: string;
type: string;
module: string;
action: string;
dataset: string;
};
agent: {
version: string;
Expand All @@ -685,7 +696,7 @@ export interface HostPolicyResponse {
version: string;
id: string;
status: HostPolicyResponseActionStatus;
actions: Partial<HostPolicyResponseActions>;
actions: HostPolicyResponseAppliedAction[];
policy: {
id: string;
version: string;
Expand All @@ -698,6 +709,16 @@ export interface HostPolicyResponse {
streaming: HostPolicyResponseConfigurationStatus;
};
};
artifacts: {
global: {
version: string;
identifiers: HostPolicyResponseAppliedArtifact[];
};
user: {
version: string;
identifiers: HostPolicyResponseAppliedArtifact[];
};
};
};
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import querystring from 'querystring';
import { createSelector } from 'reselect';
import {
Immutable,
HostPolicyResponseActions,
HostPolicyResponseAppliedAction,
HostPolicyResponseConfiguration,
HostPolicyResponseActionStatus,
} from '../../../../../common/types';
Expand Down Expand Up @@ -62,7 +62,8 @@ export const policyResponseFailedOrWarningActionCount: (
Object.entries(applied.response.configurations).map(([key, val]) => {
let count = 0;
for (const action of val.concerned_actions) {
const actionStatus = applied.actions[action]?.status;
const actionStatus = applied.actions.find(policyActions => policyActions.name === action)
?.status;
if (
actionStatus === HostPolicyResponseActionStatus.failure ||
actionStatus === HostPolicyResponseActionStatus.warning
Expand All @@ -81,7 +82,7 @@ export const policyResponseFailedOrWarningActionCount: (
*/
export const policyResponseActions: (
state: Immutable<HostState>
) => undefined | Partial<HostPolicyResponseActions> = createSelector(
) => undefined | Immutable<HostPolicyResponseAppliedAction[]> = createSelector(
detailsPolicyAppliedResponse,
applied => {
return applied?.actions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const PolicyResponseFlyoutPanel = memo<{
}>(({ hostMeta }) => {
const { show, ...queryParams } = useHostSelector(uiQueryParams);
const responseConfig = useHostSelector(policyResponseConfigurations);
const responseActionStatus = useHostSelector(policyResponseActions);
const responseActions = useHostSelector(policyResponseActions);
const responseAttentionCount = useHostSelector(policyResponseFailedOrWarningActionCount);
const loading = useHostSelector(policyResponseLoading);
const error = useHostSelector(policyResponseError);
Expand Down Expand Up @@ -158,11 +158,10 @@ const PolicyResponseFlyoutPanel = memo<{
/>
)}
{loading && <EuiLoadingContent lines={3} />}

{responseConfig !== undefined && responseActionStatus !== undefined && (
{responseConfig !== undefined && responseActions !== undefined && (
<PolicyResponse
responseConfig={responseConfig}
responseActionStatus={responseActionStatus}
responseActions={responseActions}
responseAttentionCount={responseAttentionCount}
/>
)}
Expand Down
Loading