[SIEM] Fixes pushing down the host and network details correctly so that currated columns can be removed (#45031)

## Summary

This fixes an unreleased bug where the tabs was not pushing down the page type of details and we were rendering columns that have duplicate information when on details pages such as host information.

* https://github.com/elastic/kibana/issues/45017

This adds the enhancement of uncommon process table by removing two of its columns when on the details page which are the columns of:

* hosts
* number of hosts

Before for uncommon process when on a details page:
<img width="2007" alt="Screen Shot 2019-09-06 at 11 59 20 AM" src="https://user-images.githubusercontent.com/1151048/64450684-e614a180-d09f-11e9-9c07-47f4e87f307b.png">

After for  uncommon process when on a details page:
<img width="2018" alt="Screen Shot 2019-09-06 at 11 56 24 AM" src="https://user-images.githubusercontent.com/1151048/64450698-ec0a8280-d09f-11e9-86e9-2f4e0811400e.png">

### Checklist

Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR.

- [x] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)
- [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)
- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials
- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)

### For maintainers

- [x] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
- [x] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
This commit is contained in:
Frank Hassanabad 2019-09-06 13:39:52 -06:00 committed by GitHub
parent ef4a73a491
commit 426ebf0caa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 16 deletions

View file

@ -7,12 +7,13 @@
import { RisonValue, encode } from 'rison-node';
import { decodeRison, isRisonObject } from './rison_helpers';
import { CONSTANTS } from '../../url_state/constants';
import { HostsType } from '../../../store/hosts/model';
export const replaceKqlQueryLocationForHostPage = (kqlQuery: string): string => {
const value: RisonValue = decodeRison(kqlQuery);
if (isRisonObject(value)) {
value.queryLocation = CONSTANTS.hostsPage;
value.type = 'page';
value.type = HostsType.page;
return encode(value);
} else {
return kqlQuery;

View file

@ -7,12 +7,13 @@
import { RisonValue, encode } from 'rison-node';
import { decodeRison, isRisonObject } from './rison_helpers';
import { CONSTANTS } from '../../url_state/constants';
import { NetworkType } from '../../../store/network/model';
export const replaceKqlQueryLocationForNetworkPage = (kqlQuery: string): string => {
const value: RisonValue = decodeRison(kqlQuery);
if (isRisonObject(value)) {
value.queryLocation = CONSTANTS.networkPage;
value.type = 'page';
value.type = NetworkType.page;
return encode(value);
} else {
return kqlQuery;

View file

@ -5,6 +5,8 @@
*/
import { decodeRison, isRisonObject, isRegularString } from './rison_helpers';
import { HostsType } from '../../../store/hosts/model';
import { CONSTANTS } from '../../url_state/constants';
describe('rison_helpers', () => {
// Suppress warnings about invalid RISON as this is what we are testing
@ -29,8 +31,8 @@ describe('rison_helpers', () => {
);
expect(expected).toEqual({
filterQuery: { expression: 'process.name: "process-name-1"', kind: 'kuery' },
queryLocation: 'hosts.details',
type: 'details',
queryLocation: CONSTANTS.hostsDetails,
type: HostsType.details,
});
});
});

View file

@ -144,7 +144,7 @@ export const getAnomaliesHostTableColumnsCurated = (
const columns = getAnomaliesHostTableColumns(startDate, endDate, interval, narrowDateRange);
// Columns to exclude from host details pages
if (pageType === 'details') {
if (pageType === HostsType.details) {
return columns.filter(column => column.name !== i18n.HOST_NAME);
} else {
return columns;

View file

@ -138,7 +138,7 @@ export const getAnomaliesNetworkTableColumnsCurated = (
const columns = getAnomaliesNetworkTableColumns(startDate, endDate, interval, narrowDateRange);
// Columns to exclude from ip details pages
if (pageType === 'details') {
if (pageType === NetworkType.details) {
return columns.filter(column => column.name !== i18n.NETWORK_NAME);
} else {
return columns;

View file

@ -328,11 +328,13 @@ const getAuthenticationColumns = (): AuthTableColumns => [
},
];
export const getAuthenticationColumnsCurated = (pageType: hostsModel.HostsType) => {
export const getAuthenticationColumnsCurated = (
pageType: hostsModel.HostsType
): AuthTableColumns => {
const columns = getAuthenticationColumns();
// Columns to exclude from host details pages
if (pageType === 'details') {
if (pageType === hostsModel.HostsType.details) {
return [i18n.LAST_FAILED_DESTINATION, i18n.LAST_SUCCESSFUL_DESTINATION].reduce((acc, name) => {
acc.splice(acc.findIndex(column => column.name === name), 1);
return acc;

View file

@ -272,7 +272,7 @@ export const getEventsColumnsCurated = (pageType: hostsModel.HostsType) => {
const columns = getEventsColumns(pageType);
// Columns to exclude from host details pages
if (pageType === 'details') {
if (pageType === hostsModel.HostsType.details) {
return [i18n.HOST_NAME].reduce((acc, name) => {
acc.splice(acc.findIndex(column => column.name === name), 1);
return acc;

View file

@ -13,8 +13,10 @@ import { TestProviders } from '../../../../mock';
import { hostsModel } from '../../../../store';
import { getEmptyValue } from '../../../empty_value';
import { getArgs, UncommonProcessTable } from '.';
import { getArgs, UncommonProcessTable, getUncommonColumnsCurated } from '.';
import { mockData } from './mock';
import { HostsType } from '../../../../store/hosts/model';
import * as i18n from './translations';
describe('Uncommon Process Table Component', () => {
const loadPage = jest.fn();
@ -299,4 +301,35 @@ describe('Uncommon Process Table Component', () => {
expect(getArgs(undefined)).toEqual(null);
});
});
describe('#getUncommonColumnsCurated', () => {
test('on hosts page, we expect to get all columns', () => {
expect(getUncommonColumnsCurated(HostsType.page).length).toEqual(6);
});
test('on host details page, we expect to remove two columns', () => {
const columns = getUncommonColumnsCurated(HostsType.details);
expect(columns.length).toEqual(4);
});
test('on host page, we should have hosts', () => {
const columns = getUncommonColumnsCurated(HostsType.page);
expect(columns.some(col => col.name === i18n.HOSTS)).toEqual(true);
});
test('on host page, we should have number of hosts', () => {
const columns = getUncommonColumnsCurated(HostsType.page);
expect(columns.some(col => col.name === i18n.NUMBER_OF_HOSTS)).toEqual(true);
});
test('on host details page, we should not have hosts', () => {
const columns = getUncommonColumnsCurated(HostsType.details);
expect(columns.some(col => col.name === i18n.HOSTS)).toEqual(false);
});
test('on host details page, we should not have number of hosts', () => {
const columns = getUncommonColumnsCurated(HostsType.details);
expect(columns.some(col => col.name === i18n.NUMBER_OF_HOSTS)).toEqual(false);
});
});
});

View file

@ -18,6 +18,7 @@ import { Columns, ItemsPerRow, PaginatedTable } from '../../../paginated_table';
import * as i18n from './translations';
import { getRowItemDraggables } from '../../../tables/helpers';
import { HostsType } from '../../../../store/hosts/model';
const tableType = hostsModel.HostsTableType.uncommonProcesses;
interface OwnProps {
data: UncommonProcessesEdges[];
@ -94,7 +95,7 @@ const UncommonProcessTableComponent = pure<UncommonProcessTableProps>(
type,
}) => (
<PaginatedTable
columns={getUncommonColumns()}
columns={getUncommonColumnsCurated(type)}
headerCount={totalCount}
headerTitle={i18n.UNCOMMON_PROCESSES}
headerUnit={i18n.UNIT(totalCount)}
@ -213,3 +214,15 @@ export const getHostNames = (node: UncommonProcessItem): string[] => {
return [];
}
};
export const getUncommonColumnsCurated = (pageType: HostsType): UncommonProcessTableColumns => {
const columns: UncommonProcessTableColumns = getUncommonColumns();
if (pageType === HostsType.details) {
return [i18n.HOSTS, i18n.NUMBER_OF_HOSTS].reduce((acc, name) => {
acc.splice(acc.findIndex(column => column.name === name), 1);
return acc;
}, columns);
} else {
return columns;
}
};

View file

@ -6,6 +6,7 @@
import { navTabs, SiemPageName } from '../../pages/home/home_navigations';
import { isKqlForRoute, getTitle } from './helpers';
import { CONSTANTS } from './constants';
import { HostsType } from '../../store/hosts/model';
describe('Helpers Url_State', () => {
describe('isKqlForRoute', () => {
@ -60,8 +61,8 @@ describe('Helpers Url_State', () => {
expect(result).toEqual('Timelines');
});
test('details page name', () => {
const result = getTitle('hosts', 'details', navTabs);
expect(result).toEqual('details');
const result = getTitle('hosts', HostsType.details, navTabs);
expect(result).toEqual(HostsType.details);
});
test('Not existing', () => {
const result = getTitle('IamHereButNotReally', undefined, navTabs);

View file

@ -183,7 +183,7 @@ export const HostsQueryTabBody = ({
setQuery={setQuery}
showMorePagesIndicator={getOr(false, 'showMorePagesIndicator', pageInfo)}
totalCount={totalCount}
type={hostsModel.HostsType.page}
type={type}
/>
)}
</HostsQuery>
@ -219,7 +219,7 @@ export const AuthenticationsQueryTabBody = ({
showMorePagesIndicator={getOr(false, 'showMorePagesIndicator', pageInfo)}
setQuery={setQuery}
totalCount={totalCount}
type={hostsModel.HostsType.page}
type={type}
/>
)}
</AuthenticationsQuery>
@ -255,7 +255,7 @@ export const UncommonProcessTabBody = ({
setQuery={setQuery}
showMorePagesIndicator={getOr(false, 'showMorePagesIndicator', pageInfo)}
totalCount={totalCount}
type={hostsModel.HostsType.page}
type={type}
/>
)}
</UncommonProcessesQuery>