Skip to content

Commit

Permalink
[Security Solution][Endpoint] Update Fleet Trusted Apps and Host Isol…
Browse files Browse the repository at this point in the history
…ation Exception cards to use exception list summary API (#123900)

* don't use deprecated class

ref /pull/123476

* update TA card to use summary api with filter

ref #123476 (review)

* update fleet hie card to use summary api

ref  #123476 (review)

* update param types

review changes

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
ashokaditya and kibanamachine authored Jan 28, 2022
1 parent edf8f20 commit f697ffe
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,12 @@ export async function updateOneHostIsolationExceptionItem(
});
}
export async function getHostIsolationExceptionSummary(
http: HttpStart
http: HttpStart,
filter?: string
): Promise<ExceptionListSummarySchema> {
return http.get<ExceptionListSummarySchema>(`${EXCEPTION_LIST_URL}/summary`, {
query: {
filter,
list_id: ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID,
namespace_type: 'agnostic',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { parsePoliciesToKQL } from '../../../../../../common/utils';
import { ExceptionItemsSummary } from './exception_items_summary';
import { LinkWithIcon } from './link_with_icon';
import { StyledEuiFlexItem } from './styled_components';
import { EventFiltersHttpService } from '../../../../../event_filters/service';
import { getSummary } from '../../../../../event_filters/service/service_actions';

export const FleetIntegrationEventFiltersCard = memo<{
policyId: string;
Expand All @@ -32,7 +32,6 @@ export const FleetIntegrationEventFiltersCard = memo<{
const isMounted = useRef<boolean>();
const { getAppUrl } = useAppUrl();

const eventFiltersApi = useMemo(() => new EventFiltersHttpService(http), [http]);
const policyEventFiltersPath = getPolicyEventFiltersPath(policyId);

const policyEventFiltersRouteState = useMemo<PolicyDetailsRouteState>(() => {
Expand Down Expand Up @@ -86,7 +85,7 @@ export const FleetIntegrationEventFiltersCard = memo<{
isMounted.current = true;
const fetchStats = async () => {
try {
const summary = await eventFiltersApi.getSummary(parsePoliciesToKQL([policyId, 'all']));
const summary = await getSummary({ http, filter: parsePoliciesToKQL([policyId, 'all']) });
if (isMounted.current) {
setStats(summary);
}
Expand All @@ -108,7 +107,7 @@ export const FleetIntegrationEventFiltersCard = memo<{
return () => {
isMounted.current = false;
};
}, [eventFiltersApi, policyId, toasts]);
}, [http, policyId, toasts]);

return (
<EuiPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import React from 'react';
import uuid from 'uuid';
import { createAppRootMockRenderer } from '../../../../../../../common/mock/endpoint';
import { useUserPrivileges } from '../../../../../../../common/components/user_privileges';
import { getHostIsolationExceptionItems } from '../../../../../host_isolation_exceptions/service';
import { getHostIsolationExceptionSummary } from '../../../../../host_isolation_exceptions/service';
import { FleetIntegrationHostIsolationExceptionsCard } from './fleet_integration_host_isolation_exceptions_card';

jest.mock('../../../../../host_isolation_exceptions/service');
jest.mock('../../../../../../../common/components/user_privileges');

const getHostIsolationExceptionItemsMock = getHostIsolationExceptionItems as jest.Mock;
const getHostIsolationExceptionSummaryMock = getHostIsolationExceptionSummary as jest.Mock;

const useUserPrivilegesMock = useUserPrivileges as jest.Mock;

Expand All @@ -29,7 +29,7 @@ describe('Fleet host isolation exceptions card filters card', () => {
);
};
afterEach(() => {
getHostIsolationExceptionItemsMock.mockReset();
getHostIsolationExceptionSummaryMock.mockReset();
});
describe('With canIsolateHost privileges', () => {
beforeEach(() => {
Expand All @@ -41,18 +41,19 @@ describe('Fleet host isolation exceptions card filters card', () => {
});

it('should call the API and render the card correctly', async () => {
getHostIsolationExceptionItemsMock.mockResolvedValue({
getHostIsolationExceptionSummaryMock.mockResolvedValue({
linux: 5,
macos: 5,
total: 5,
windows: 5,
});
const renderResult = renderComponent();

await waitFor(() => {
expect(getHostIsolationExceptionItemsMock).toHaveBeenCalledWith({
http: mockedContext.coreStart.http,
filter: `(exception-list-agnostic.attributes.tags:"policy:${policyId}" OR exception-list-agnostic.attributes.tags:"policy:all")`,
page: 1,
perPage: 1,
});
expect(getHostIsolationExceptionSummaryMock).toHaveBeenCalledWith(
mockedContext.coreStart.http,
`(exception-list-agnostic.attributes.tags:"policy:${policyId}" OR exception-list-agnostic.attributes.tags:"policy:all")`
);
});

expect(
Expand All @@ -71,13 +72,16 @@ describe('Fleet host isolation exceptions card filters card', () => {
});

it('should not render the card if there are no exceptions associated', async () => {
getHostIsolationExceptionItemsMock.mockResolvedValue({
getHostIsolationExceptionSummaryMock.mockResolvedValue({
linux: 0,
macos: 0,
total: 0,
windows: 0,
});
const renderResult = renderComponent();

await waitFor(() => {
expect(getHostIsolationExceptionItemsMock).toHaveBeenCalled();
expect(getHostIsolationExceptionSummaryMock).toHaveBeenCalled();
});

expect(
Expand All @@ -86,13 +90,16 @@ describe('Fleet host isolation exceptions card filters card', () => {
});

it('should render the card if there are exceptions associated', async () => {
getHostIsolationExceptionItemsMock.mockResolvedValue({
getHostIsolationExceptionSummaryMock.mockResolvedValue({
linux: 1,
macos: 1,
total: 1,
windows: 1,
});
const renderResult = renderComponent();

await waitFor(() => {
expect(getHostIsolationExceptionItemsMock).toHaveBeenCalled();
expect(getHostIsolationExceptionSummaryMock).toHaveBeenCalled();
});

expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
import { useAppUrl, useHttp, useToasts } from '../../../../../../../common/lib/kibana';
import { getPolicyHostIsolationExceptionsPath } from '../../../../../../common/routing';
import { parsePoliciesToKQL } from '../../../../../../common/utils';
import { getHostIsolationExceptionItems } from '../../../../../host_isolation_exceptions/service';
import { getHostIsolationExceptionSummary } from '../../../../../host_isolation_exceptions/service';
import { ExceptionItemsSummary } from './exception_items_summary';
import { LinkWithIcon } from './link_with_icon';
import { StyledEuiFlexItem } from './styled_components';
Expand Down Expand Up @@ -86,20 +86,12 @@ export const FleetIntegrationHostIsolationExceptionsCard = memo<{
isMounted.current = true;
const fetchStats = async () => {
try {
const summary = await getHostIsolationExceptionItems({
const summary = await getHostIsolationExceptionSummary(
http,
perPage: 1,
page: 1,
filter: parsePoliciesToKQL([policyId, 'all']),
});
parsePoliciesToKQL([policyId, 'all'])
);
if (isMounted.current) {
setStats({
total: summary.total,
// the following properties are not relevant for this specific card
windows: 0,
linux: 0,
macos: 0,
});
setStats(summary);
}
} catch (error) {
if (isMounted.current) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('Fleet trusted apps card', () => {
it('should render correctly with policyId', async () => {
TrustedAppsHttpServiceMock.mockImplementationOnce(() => {
return {
getTrustedAppsList: () => () => promise,
getTrustedAppsSummary: () => () => promise,
};
});
const component = await renderComponent({ policyId: 'policy-1' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { GetExceptionSummaryResponse } from '../../../../../../../../common/endp

import { useKibana, useToasts } from '../../../../../../../common/lib/kibana';
import { ExceptionItemsSummary } from './exception_items_summary';
import { parsePoliciesToKQL } from '../../../../../../common/utils';
import { TrustedAppsHttpService } from '../../../../../trusted_apps/service';
import {
StyledEuiFlexGridGroup,
Expand Down Expand Up @@ -40,30 +41,11 @@ export const FleetTrustedAppsCard = memo<FleetTrustedAppsCardProps>(
isMounted.current = true;
const fetchStats = async () => {
try {
let response;
if (policyId) {
response = await trustedAppsApi.getTrustedAppsList({
per_page: 1,
kuery: `(exception-list-agnostic.attributes.tags:"policy:${policyId}" OR exception-list-agnostic.attributes.tags:"policy:all")`,
});
if (isMounted.current) {
setStats({
total: response.total,
windows: 0,
macos: 0,
linux: 0,
});
}
} else {
response = await trustedAppsApi.getTrustedAppsSummary();
if (isMounted.current) {
setStats({
total: response.total,
windows: response.windows,
macos: response.macos,
linux: response.linux,
});
}
const response = await trustedAppsApi.getTrustedAppsSummary(
policyId ? parsePoliciesToKQL([policyId, 'all']) : undefined
);
if (isMounted.current) {
setStats(response);
}
} catch (error) {
if (isMounted.current) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,12 @@ export class TrustedAppsHttpService implements TrustedAppsService {
};
}

async getTrustedAppsSummary() {
async getTrustedAppsSummary(filter?: string) {
return (await this.getHttpService()).get<ExceptionListSummarySchema>(
`${EXCEPTION_LIST_URL}/summary`,
{
query: {
filter,
list_id: ENDPOINT_TRUSTED_APPS_LIST_ID,
namespace_type: 'agnostic',
},
Expand Down

0 comments on commit f697ffe

Please sign in to comment.