Skip to content

Commit 45790d0

Browse files
authored
[endpoint] connect policy response ui to api (#66093)
[Endpoint] Connect policy response UI to API
1 parent 0124977 commit 45790d0

File tree

12 files changed

+148
-65
lines changed

12 files changed

+148
-65
lines changed

x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,15 @@ interface ServerReturnedHostPolicyResponse {
3232
payload: GetHostPolicyResponse;
3333
}
3434

35+
interface ServerFailedToReturnHostPolicyResponse {
36+
type: 'serverFailedToReturnHostPolicyResponse';
37+
payload: ServerApiError;
38+
}
39+
3540
export type HostAction =
3641
| ServerReturnedHostList
3742
| ServerFailedToReturnHostList
3843
| ServerReturnedHostDetails
3944
| ServerFailedToReturnHostDetails
40-
| ServerReturnedHostPolicyResponse;
45+
| ServerReturnedHostPolicyResponse
46+
| ServerFailedToReturnHostPolicyResponse;

x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ describe('HostList store concerns', () => {
4141
details: undefined,
4242
detailsLoading: false,
4343
detailsError: undefined,
44+
policyResponse: undefined,
45+
policyResponseLoading: false,
46+
policyResponseError: undefined,
4447
location: undefined,
4548
});
4649
});

x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { HostResultList, HostPolicyResponseActionStatus } from '../../../../../common/types';
7+
import { HostResultList } from '../../../../../common/types';
88
import { isOnHostPage, hasSelectedHost, uiQueryParams, listData } from './selectors';
99
import { HostState } from '../../types';
1010
import { ImmutableMiddlewareFactory } from '../../types';
11-
import { HostPolicyResponse } from '../../../../../common/types';
1211

1312
export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = coreStart => {
1413
return ({ getState, dispatch }) => next => async action => {
@@ -70,47 +69,25 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = core
7069
type: 'serverReturnedHostDetails',
7170
payload: response,
7271
});
72+
} catch (error) {
73+
dispatch({
74+
type: 'serverFailedToReturnHostDetails',
75+
payload: error,
76+
});
77+
}
78+
79+
// call the policy response api
80+
try {
81+
const policyResponse = await coreStart.http.get(`/api/endpoint/policy_response`, {
82+
query: { hostId: selectedHost },
83+
});
7384
dispatch({
7485
type: 'serverReturnedHostPolicyResponse',
75-
payload: {
76-
policy_response: ({
77-
endpoint: {
78-
policy: {
79-
applied: {
80-
version: '1.0.0',
81-
status: HostPolicyResponseActionStatus.success,
82-
id: '17d4b81d-9940-4b64-9de5-3e03ef1fb5cf',
83-
actions: {
84-
download_model: {
85-
status: 'success',
86-
message: 'Model downloaded',
87-
},
88-
ingest_events_config: {
89-
status: 'failure',
90-
message: 'No action taken',
91-
},
92-
},
93-
response: {
94-
configurations: {
95-
malware: {
96-
status: 'success',
97-
concerned_actions: ['download_model'],
98-
},
99-
events: {
100-
status: 'failure',
101-
concerned_actions: ['ingest_events_config'],
102-
},
103-
},
104-
},
105-
},
106-
},
107-
},
108-
} as unknown) as HostPolicyResponse, // Temporary until we get API
109-
},
86+
payload: policyResponse,
11087
});
11188
} catch (error) {
11289
dispatch({
113-
type: 'serverFailedToReturnHostDetails',
90+
type: 'serverFailedToReturnHostPolicyResponse',
11491
payload: error,
11592
});
11693
}

x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const initialState = (): HostState => {
2121
detailsLoading: false,
2222
detailsError: undefined,
2323
policyResponse: undefined,
24+
policyResponseLoading: false,
25+
policyResponseError: undefined,
2426
location: undefined,
2527
};
2628
};
@@ -68,6 +70,14 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
6870
return {
6971
...state,
7072
policyResponse: action.payload.policy_response,
73+
policyResponseLoading: false,
74+
policyResponseError: undefined,
75+
};
76+
} else if (action.type === 'serverFailedToReturnHostPolicyResponse') {
77+
return {
78+
...state,
79+
policyResponseError: action.payload,
80+
policyResponseLoading: false,
7181
};
7282
} else if (action.type === 'userChangedUrl') {
7383
const newState: Immutable<HostState> = {
@@ -97,8 +107,10 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
97107
...state,
98108
location: action.payload,
99109
detailsLoading: true,
110+
policyResponseLoading: true,
100111
error: undefined,
101112
detailsError: undefined,
113+
policyResponseError: undefined,
102114
};
103115
} else {
104116
// if previous page was not host list or host details, load both list and details
@@ -107,8 +119,10 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
107119
location: action.payload,
108120
loading: true,
109121
detailsLoading: true,
122+
policyResponseLoading: true,
110123
error: undefined,
111124
detailsError: undefined,
125+
policyResponseError: undefined,
112126
};
113127
}
114128
}
@@ -118,6 +132,7 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
118132
location: action.payload,
119133
error: undefined,
120134
detailsError: undefined,
135+
policyResponseError: undefined,
121136
};
122137
}
123138
return state;

x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ export const policyResponseActions: (
8888
}
8989
);
9090

91+
export const policyResponseLoading = (state: Immutable<HostState>): boolean =>
92+
state.policyResponseLoading;
93+
94+
export const policyResponseError = (state: Immutable<HostState>) => state.policyResponseError;
95+
9196
export const isOnHostPage = (state: Immutable<HostState>) =>
9297
state.location ? state.location.pathname === '/hosts' : false;
9398

x-pack/plugins/endpoint/public/applications/endpoint/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ export interface HostState {
110110
detailsError?: ServerApiError;
111111
/** Holds the Policy Response for the Host currently being displayed in the details */
112112
policyResponse?: HostPolicyResponse;
113+
/** policyResponse is being retrieved */
114+
policyResponseLoading: boolean;
115+
/** api error from retrieving the policy response */
116+
policyResponseError?: ServerApiError;
113117
/** current location info */
114118
location?: Immutable<EndpointAppLocation>;
115119
}

x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/host_details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { useHostSelector, useHostLogsUrl } from '../hooks';
2323
import { urlFromQueryParams } from '../url_from_query_params';
2424
import { policyResponseStatus, uiQueryParams } from '../../../store/hosts/selectors';
2525
import { useNavigateByRouterEventHandler } from '../../hooks/use_navigate_by_router_event_handler';
26-
import { POLICY_STATUS_TO_HEALTH_COLOR } from './host_constants';
26+
import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants';
2727

2828
const HostIds = styled(EuiListGroupItem)`
2929
margin-top: 0;

x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/index.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
EuiTitle,
1414
EuiText,
1515
EuiSpacer,
16+
EuiEmptyPrompt,
1617
} from '@elastic/eui';
1718
import { useHistory } from 'react-router-dom';
1819
import { FormattedMessage } from '@kbn/i18n/react';
@@ -29,6 +30,8 @@ import {
2930
policyResponseConfigurations,
3031
policyResponseActions,
3132
policyResponseFailedOrWarningActionCount,
33+
policyResponseError,
34+
policyResponseLoading,
3235
} from '../../../store/hosts/selectors';
3336
import { HostDetails } from './host_details';
3437
import { PolicyResponse } from './policy_response';
@@ -108,6 +111,8 @@ const PolicyResponseFlyoutPanel = memo<{
108111
const responseConfig = useHostSelector(policyResponseConfigurations);
109112
const responseActionStatus = useHostSelector(policyResponseActions);
110113
const responseAttentionCount = useHostSelector(policyResponseFailedOrWarningActionCount);
114+
const loading = useHostSelector(policyResponseLoading);
115+
const error = useHostSelector(policyResponseError);
111116
const detailsUri = useMemo(
112117
() =>
113118
urlFromQueryParams({
@@ -142,17 +147,24 @@ const PolicyResponseFlyoutPanel = memo<{
142147
/>
143148
</h4>
144149
</EuiText>
145-
{responseConfig !== undefined && responseActionStatus !== undefined ? (
150+
{error && (
151+
<EuiEmptyPrompt
152+
title={
153+
<FormattedMessage
154+
id="xpack.endpoint.hostDetails.noPolicyResponse"
155+
defaultMessage="No policy response available"
156+
/>
157+
}
158+
/>
159+
)}
160+
{loading && <EuiLoadingContent lines={3} />}
161+
162+
{responseConfig !== undefined && responseActionStatus !== undefined && (
146163
<PolicyResponse
147164
responseConfig={responseConfig}
148165
responseActionStatus={responseActionStatus}
149166
responseAttentionCount={responseAttentionCount}
150167
/>
151-
) : (
152-
<FormattedMessage
153-
id="xpack.endpoint.hostDetails.noPolicyResponse"
154-
defaultMessage="No Policy Response Available"
155-
/>
156168
)}
157169
</EuiFlyoutBody>
158170
</>

x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Immutable,
1515
} from '../../../../../../common/types';
1616
import { formatResponse } from './policy_response_friendly_names';
17-
import { POLICY_STATUS_TO_HEALTH_COLOR } from './host_constants';
17+
import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants';
1818

1919
/**
2020
* Nested accordion in the policy response detailing any concerned
@@ -43,6 +43,17 @@ const PolicyResponseConfigAccordion = styled(EuiAccordion)`
4343
:hover:not(.euiAccordion-isOpen) {
4444
background-color: ${props => props.theme.eui.euiColorLightestShade};
4545
}
46+
47+
.policyResponseActionsAccordion {
48+
svg {
49+
height: ${props => props.theme.eui.euiIconSizes.small};
50+
width: ${props => props.theme.eui.euiIconSizes.small};
51+
}
52+
}
53+
54+
.policyResponseStatusHealth {
55+
width: 100px;
56+
}
4657
`;
4758

4859
const ResponseActions = memo(
@@ -65,8 +76,13 @@ const ResponseActions = memo(
6576
id={action + index}
6677
key={action + index}
6778
data-test-subj="hostDetailsPolicyResponseActionsAccordion"
79+
className="policyResponseActionsAccordion"
6880
buttonContent={
69-
<EuiText size="xs" data-test-subj="policyResponseAction">
81+
<EuiText
82+
size="xs"
83+
className="eui-textTruncate"
84+
data-test-subj="policyResponseAction"
85+
>
7086
<h4>{formatResponse(action)}</h4>
7187
</EuiText>
7288
}
@@ -75,6 +91,7 @@ const ResponseActions = memo(
7591
<EuiHealth
7692
color={POLICY_STATUS_TO_HEALTH_COLOR[statuses.status]}
7793
data-test-subj="policyResponseStatusHealth"
94+
className="policyResponseStatusHealth"
7895
>
7996
<EuiText size="xs">
8097
<p>{formatResponse(statuses.status)}</p>

x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details/policy_response_friendly_names.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ responseMap.set(
2525
defaultMessage: 'Failed',
2626
})
2727
);
28+
responseMap.set(
29+
'logging',
30+
i18n.translate('xpack.endpoint.hostDetails.policyResponse.logging', {
31+
defaultMessage: 'Logging',
32+
})
33+
);
34+
responseMap.set(
35+
'streaming',
36+
i18n.translate('xpack.endpoint.hostDetails.policyResponse.streaming', {
37+
defaultMessage: 'Streaming',
38+
})
39+
);
2840
responseMap.set(
2941
'malware',
3042
i18n.translate('xpack.endpoint.hostDetails.policyResponse.malware', {

0 commit comments

Comments
 (0)