[SIEM] Fix IP Overview query to query for most recent Host (#37723) (#38008)

## Summary

As outlined in https://github.com/elastic/ingest-dev/issues/453, this PR fixes the `IP Overview` query to query for the most recent Host.

Now the Host Data shown will be the most recent host for the given IP regardless of whether `Source` or `Destination` is selected in the FlowTargetSelect.

![image](https://user-images.githubusercontent.com/2946766/58731558-46fb5200-83ac-11e9-97d5-7db5dd8ac84e.png)


### Checklist

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

- [ ] ~This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)~
- [ ] ~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

- [ ] ~This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~
- [ ] ~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:
Garrett Spong 2019-06-04 15:44:53 -06:00 committed by GitHub
parent 6a67efe6af
commit 1f4edc5301
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 212 additions and 283 deletions

View file

@ -114,9 +114,7 @@ describe('Field Renderers', () => {
};
test('it renders correctly against snapshot', () => {
const wrapper = shallow(
<TestProviders>
{hostNameRenderer(mockData.complete.source!.host!, '10.10.10.10')}
</TestProviders>
<TestProviders>{hostNameRenderer(mockData.complete.host, '10.10.10.10')}</TestProviders>
);
expect(toJson(wrapper)).toMatchSnapshot();
@ -124,9 +122,7 @@ describe('Field Renderers', () => {
test('it renders emptyTagValue when non-matching IP is provided', () => {
const wrapper = mount(
<TestProviders>
{hostNameRenderer(mockData.complete.source!.host!, '10.10.10.11')}
</TestProviders>
<TestProviders>{hostNameRenderer(mockData.complete.host, '10.10.10.11')}</TestProviders>
);
expect(wrapper.text()).toEqual(getEmptyValue());
});
@ -163,9 +159,7 @@ describe('Field Renderers', () => {
};
test('it renders correctly against snapshot', () => {
const wrapper = shallow(
<TestProviders>
{hostNameRenderer(mockData.complete.source!.host!, '10.10.10.10')}
</TestProviders>
<TestProviders>{hostNameRenderer(mockData.complete.host, '10.10.10.10')}</TestProviders>
);
expect(toJson(wrapper)).toMatchSnapshot();
@ -173,9 +167,7 @@ describe('Field Renderers', () => {
test('it renders emptyTagValue when non-matching IP is provided', () => {
const wrapper = mount(
<TestProviders>
{hostNameRenderer(mockData.complete.source!.host!, '10.10.10.11')}
</TestProviders>
<TestProviders>{hostNameRenderer(mockData.complete.host, '10.10.10.11')}</TestProviders>
);
expect(wrapper.text()).toEqual(getEmptyValue());
});

View file

@ -73,11 +73,11 @@ export const IpOverview = pure<IpOverviewProps>(({ ip, data, loading, flowTarget
[
{
title: i18n.HOST_ID,
description: typeData ? hostIdRenderer(typeData.host, ip) : getEmptyTagValue(),
description: typeData ? hostIdRenderer(data.host, ip) : getEmptyTagValue(),
},
{
title: i18n.HOST_NAME,
description: typeData ? hostNameRenderer(typeData.host, ip) : getEmptyTagValue(),
description: typeData ? hostNameRenderer(data.host, ip) : getEmptyTagValue(),
},
],
[

View file

@ -24,19 +24,6 @@ export const mockData: Readonly<Record<string, IpOverviewData>> = {
region_iso_code: ['US-NY'],
region_name: ['New York'],
},
host: {
os: {
kernel: ['4.14.50-v7+'],
name: ['Raspbian GNU/Linux'],
family: [''],
version: ['9 (stretch)'],
platform: ['raspbian'],
},
name: ['raspberrypi'],
id: ['b19a781f683541a7a25ee345133aa399'],
ip: ['10.10.10.10'],
architecture: ['armv7l'],
},
},
destination: {
firstSeen: '2019-02-07T17:19:41.648Z',
@ -54,19 +41,19 @@ export const mockData: Readonly<Record<string, IpOverviewData>> = {
region_iso_code: ['US-NY'],
region_name: ['New York'],
},
host: {
os: {
kernel: ['4.14.50-v7+'],
name: ['Raspbian GNU/Linux'],
family: [''],
version: ['9 (stretch)'],
platform: ['raspbian'],
},
name: ['raspberrypi'],
id: ['b19a781f683541a7a25ee345133aa399'],
ip: ['10.10.10.10'],
architecture: ['armv7l'],
},
host: {
os: {
kernel: ['4.14.50-v7+'],
name: ['Raspbian GNU/Linux'],
family: [''],
version: ['9 (stretch)'],
platform: ['raspbian'],
},
name: ['raspberrypi'],
id: ['b19a781f683541a7a25ee345133aa399'],
ip: ['10.10.10.10'],
architecture: ['armv7l'],
},
},
};

View file

@ -36,20 +36,6 @@ export const ipOverviewQuery = gql`
region_iso_code
region_name
}
host {
architecture
id
ip
mac
name
os {
family
name
platform
version
}
type
}
}
destination {
firstSeen
@ -71,20 +57,20 @@ export const ipOverviewQuery = gql`
region_iso_code
region_name
}
host {
architecture
id
ip
mac
}
host {
architecture
id
ip
mac
name
os {
family
name
os {
family
name
platform
version
}
type
platform
version
}
type
}
}
}

View file

@ -44,7 +44,7 @@ export const IpOverviewQuery = pure<IpOverviewProps>(
}}
>
{({ data, loading }) => {
const init: IpOverviewData = {};
const init: IpOverviewData = { host: {} };
const ipOverviewData: IpOverviewData = getOr(init, 'source.IpOverview', data);
return children({
id,

View file

@ -5810,6 +5810,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "host",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "OBJECT", "name": "HostEcsFields", "ofType": null }
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "server",
"description": "",
@ -5865,18 +5877,6 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "host",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "OBJECT", "name": "HostEcsFields", "ofType": null }
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "geo",
"description": "",

View file

@ -904,6 +904,8 @@ export interface IpOverviewData {
destination?: Overview | null;
host: HostEcsFields;
server?: Overview | null;
source?: Overview | null;
@ -916,8 +918,6 @@ export interface Overview {
autonomousSystem: AutonomousSystem;
host: HostEcsFields;
geo: GeoEcsFields;
}
@ -2763,6 +2763,8 @@ export namespace GetIpOverviewQuery {
source?: _Source | null;
destination?: Destination | null;
host: Host;
};
export type _Source = {
@ -2775,8 +2777,6 @@ export namespace GetIpOverviewQuery {
autonomousSystem: AutonomousSystem;
geo: Geo;
host: Host;
};
export type AutonomousSystem = {
@ -2815,36 +2815,6 @@ export namespace GetIpOverviewQuery {
lon?: ToNumberArray | null;
};
export type Host = {
__typename?: 'HostEcsFields';
architecture?: ToStringArray | null;
id?: ToStringArray | null;
ip?: ToStringArray | null;
mac?: ToStringArray | null;
name?: ToStringArray | null;
os?: Os | null;
type?: ToStringArray | null;
};
export type Os = {
__typename?: 'OsEcsFields';
family?: ToStringArray | null;
name?: ToStringArray | null;
platform?: ToStringArray | null;
version?: ToStringArray | null;
};
export type Destination = {
__typename?: 'Overview';
@ -2855,8 +2825,6 @@ export namespace GetIpOverviewQuery {
autonomousSystem: _AutonomousSystem;
geo: _Geo;
host: _Host;
};
export type _AutonomousSystem = {
@ -2895,7 +2863,7 @@ export namespace GetIpOverviewQuery {
lon?: ToNumberArray | null;
};
export type _Host = {
export type Host = {
__typename?: 'HostEcsFields';
architecture?: ToStringArray | null;
@ -2908,12 +2876,12 @@ export namespace GetIpOverviewQuery {
name?: ToStringArray | null;
os?: _Os | null;
os?: Os | null;
type?: ToStringArray | null;
};
export type _Os = {
export type Os = {
__typename?: 'OsEcsFields';
family?: ToStringArray | null;

View file

@ -17,13 +17,13 @@ const ipOverviewSchema = gql`
firstSeen: Date
lastSeen: Date
autonomousSystem: AutonomousSystem!
host: HostEcsFields!
geo: GeoEcsFields!
}
type IpOverviewData {
client: Overview
destination: Overview
host: HostEcsFields!
server: Overview
source: Overview
}

View file

@ -933,6 +933,8 @@ export interface IpOverviewData {
destination?: Overview | null;
host: HostEcsFields;
server?: Overview | null;
source?: Overview | null;
@ -945,8 +947,6 @@ export interface Overview {
autonomousSystem: AutonomousSystem;
host: HostEcsFields;
geo: GeoEcsFields;
}
@ -5296,6 +5296,8 @@ export namespace IpOverviewDataResolvers {
destination?: DestinationResolver<Overview | null, TypeParent, Context>;
host?: HostResolver<HostEcsFields, TypeParent, Context>;
server?: ServerResolver<Overview | null, TypeParent, Context>;
source?: SourceResolver<Overview | null, TypeParent, Context>;
@ -5311,6 +5313,11 @@ export namespace IpOverviewDataResolvers {
Parent = IpOverviewData,
Context = SiemContext
> = Resolver<R, Parent, Context>;
export type HostResolver<
R = HostEcsFields,
Parent = IpOverviewData,
Context = SiemContext
> = Resolver<R, Parent, Context>;
export type ServerResolver<
R = Overview | null,
Parent = IpOverviewData,
@ -5331,8 +5338,6 @@ export namespace OverviewResolvers {
autonomousSystem?: AutonomousSystemResolver<AutonomousSystem, TypeParent, Context>;
host?: HostResolver<HostEcsFields, TypeParent, Context>;
geo?: GeoResolver<GeoEcsFields, TypeParent, Context>;
}
@ -5351,11 +5356,6 @@ export namespace OverviewResolvers {
Parent = Overview,
Context = SiemContext
> = Resolver<R, Parent, Context>;
export type HostResolver<R = HostEcsFields, Parent = Overview, Context = SiemContext> = Resolver<
R,
Parent,
Context
>;
export type GeoResolver<R = GeoEcsFields, Parent = Overview, Context = SiemContext> = Resolver<
R,
Parent,

View file

@ -5,11 +5,17 @@
*/
import { FlowTarget } from '../../graphql/types';
import { formatDomainsEdges, getIpOverviewAgg, getUsersEdges } from './elasticsearch_adapter';
import {
formatDomainsEdges,
getIpOverviewAgg,
getIpOverviewHostAgg,
getUsersEdges,
} from './elasticsearch_adapter';
import {
formattedDestination,
formattedEmptySource,
formattedHost,
formattedSource,
mockDomainsResponseBuckets,
mockFormattedDestination,
@ -30,20 +36,25 @@ describe('elasticsearch_adapter', () => {
});
test('will return a source correctly', () => {
const destination = getIpOverviewAgg(FlowTarget.source, responseAggs.aggregations.source!);
expect(destination).toEqual(formattedSource);
const source = getIpOverviewAgg(FlowTarget.source, responseAggs.aggregations.source!);
expect(source).toEqual(formattedSource);
});
test('will return a host correctly', () => {
const host = getIpOverviewHostAgg(responseAggs.aggregations.host);
expect(host).toEqual(formattedHost);
});
test('will return an empty source correctly', () => {
const destination = getIpOverviewAgg(FlowTarget.source, {});
expect(destination).toEqual(formattedEmptySource);
const source = getIpOverviewAgg(FlowTarget.source, {});
expect(source).toEqual(formattedEmptySource);
});
});
describe('#getDomains', () => {
test('will return a source correctly', () => {
const destination = formatDomainsEdges(mockDomainsResponseBuckets, FlowTarget.source);
expect(destination).toEqual(mockFormattedSource);
const source = formatDomainsEdges(mockDomainsResponseBuckets, FlowTarget.source);
expect(source).toEqual(mockFormattedSource);
});
test('will return a destination correctly', () => {

View file

@ -39,6 +39,7 @@ import {
IpDetailsAdapter,
IpOverviewHit,
OverviewHit,
OverviewHostHit,
TlsBuckets,
UsersBucketsItem,
} from './types';
@ -62,6 +63,7 @@ export class ElasticsearchIpOverviewAdapter implements IpDetailsAdapter {
return {
...getIpOverviewAgg('source', getOr({}, 'aggregations.source', response)),
...getIpOverviewAgg('destination', getOr({}, 'aggregations.destination', response)),
...getIpOverviewHostAgg(getOr({}, 'aggregations.host', response)),
};
}
@ -184,11 +186,6 @@ export const getIpOverviewAgg = (type: string, overviewHit: OverviewHit | {}) =>
`geo.results.hits.hits[0]._source.${type}.geo`,
overviewHit
);
const hostFields: HostEcsFields | null = getOr(
null,
`host.results.hits.hits[0]._source.host`,
overviewHit
);
return {
[type]: {
@ -197,9 +194,6 @@ export const getIpOverviewAgg = (type: string, overviewHit: OverviewHit | {}) =>
autonomousSystem: {
...autonomousSystem,
},
host: {
...hostFields,
},
geo: {
...geoFields,
},
@ -207,6 +201,20 @@ export const getIpOverviewAgg = (type: string, overviewHit: OverviewHit | {}) =>
};
};
export const getIpOverviewHostAgg = (overviewHostHit: OverviewHostHit | {}) => {
const hostFields: HostEcsFields | null = getOr(
null,
`host.results.hits.hits[0]._source.host`,
overviewHostHit
);
return {
host: {
...hostFields,
},
};
};
const getDomainsEdges = (
response: DatabaseSearchResponse<DomainsData, TermAggregation>,
options: DomainsRequestOptions

View file

@ -52,46 +52,6 @@ export const responseAggs: IpOverviewHit = {
value: 1551388820000,
value_as_string: '2019-02-28T21:20:20.000Z',
},
host: {
doc_count: 882307,
results: {
hits: {
total: {
value: 882307,
relation: 'eq',
},
max_score: null,
hits: [
{
_index: 'packetbeat-8.0.0-2019.02.19-000001',
_type: '_doc',
_id: 'vX5Py2kBCQofM5eX2OEu',
_score: null,
_source: {
host: {
hostname: 'suricata-bangalore',
os: {
kernel: '4.15.0-45-generic',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
containerized: false,
ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'],
name: 'suricata-bangalore',
id: '0a63559c1acf4c419d979c4b4d8b83ff',
mac: ['ee:0b:1b:29:80:bd'],
architecture: 'x86_64',
},
},
sort: [1553894200003],
},
],
},
},
},
autonomous_system: {
doc_count: 0,
results: {
@ -152,46 +112,6 @@ export const responseAggs: IpOverviewHit = {
value: 1551388804322,
value_as_string: '2019-02-28T21:20:04.322Z',
},
host: {
doc_count: 1002234,
results: {
hits: {
total: {
value: 1002234,
relation: 'eq',
},
max_score: null,
hits: [
{
_index: 'packetbeat-8.0.0-2019.02.19-000001',
_type: '_doc',
_id: 'vn5Py2kBCQofM5eX2OEu',
_score: null,
_source: {
host: {
hostname: 'suricata-bangalore',
os: {
kernel: '4.15.0-45-generic',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'],
containerized: false,
name: 'suricata-bangalore',
id: '0a63559c1acf4c419d979c4b4d8b83ff',
mac: ['ee:0b:1b:29:80:bd'],
architecture: 'x86_64',
},
},
sort: [1553894200003],
},
],
},
},
},
autonomous_system: {
doc_count: 0,
results: {
@ -206,6 +126,49 @@ export const responseAggs: IpOverviewHit = {
},
},
},
host: {
doc_count: 1588091,
host: {
doc_count: 1588091,
results: {
hits: {
total: {
value: 1588091,
relation: 'eq',
},
max_score: null,
hits: [
{
_index: 'filebeat-8.0.0-2019.05.20-000004',
_type: '_doc',
_id: 'NU9dD2sB9v5HJNSHMMRc',
_score: null,
_source: {
host: {
hostname: 'suricata-iowa',
os: {
kernel: '4.15.0-1032-gcp',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
ip: ['10.128.0.4', 'fe80::4001:aff:fe80:4'],
containerized: false,
name: 'suricata-iowa',
id: 'be1f3d767896212736b880e846876dcb',
mac: ['42:01:0a:80:00:04'],
architecture: 'x86_64',
},
},
sort: [1559330892000],
},
],
},
},
},
},
},
_shards: {
total: 42,
@ -230,23 +193,6 @@ export const formattedDestination = {
firstSeen: '2019-02-28T21:20:20.000Z',
lastSeen: '2019-03-29T22:56:20.003Z',
autonomousSystem: {},
host: {
hostname: 'suricata-bangalore',
os: {
kernel: '4.15.0-45-generic',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
containerized: false,
ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'],
name: 'suricata-bangalore',
id: '0a63559c1acf4c419d979c4b4d8b83ff',
mac: ['ee:0b:1b:29:80:bd'],
architecture: 'x86_64',
},
geo: {
continent_name: 'Asia',
region_iso_code: 'IN-KA',
@ -266,23 +212,6 @@ export const formattedSource = {
firstSeen: '2019-02-28T21:20:04.322Z',
lastSeen: '2019-03-29T22:56:20.003Z',
autonomousSystem: {},
host: {
hostname: 'suricata-bangalore',
os: {
kernel: '4.15.0-45-generic',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
containerized: false,
ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'],
name: 'suricata-bangalore',
id: '0a63559c1acf4c419d979c4b4d8b83ff',
mac: ['ee:0b:1b:29:80:bd'],
architecture: 'x86_64',
},
geo: {
continent_name: 'Asia',
region_iso_code: 'IN-KA',
@ -297,12 +226,31 @@ export const formattedSource = {
},
};
export const formattedHost = {
host: {
hostname: 'suricata-iowa',
os: {
kernel: '4.15.0-1032-gcp',
codename: 'bionic',
name: 'Ubuntu',
family: 'debian',
version: '18.04.2 LTS (Bionic Beaver)',
platform: 'ubuntu',
},
ip: ['10.128.0.4', 'fe80::4001:aff:fe80:4'],
containerized: false,
name: 'suricata-iowa',
id: 'be1f3d767896212736b880e846876dcb',
mac: ['42:01:0a:80:00:04'],
architecture: 'x86_64',
},
};
export const formattedEmptySource = {
source: {
firstSeen: null,
lastSeen: null,
autonomousSystem: {},
host: {},
geo: {},
},
};

View file

@ -45,26 +45,6 @@ const getAggs = (type: string, ip: string) => {
},
},
},
host: {
filter: {
exists: {
field: 'host',
},
},
aggs: {
results: {
top_hits: {
size: 1,
_source: ['host'],
sort: [
{
'@timestamp': 'desc',
},
],
},
},
},
},
geo: {
filter: {
exists: {
@ -90,6 +70,40 @@ const getAggs = (type: string, ip: string) => {
};
};
const getHostAggs = (ip: string) => {
return {
host: {
filter: {
term: {
'host.ip': ip,
},
},
aggs: {
host: {
filter: {
exists: {
field: 'host',
},
},
aggs: {
results: {
top_hits: {
size: 1,
_source: ['host'],
sort: [
{
'@timestamp': 'desc',
},
],
},
},
},
},
},
},
};
};
export const buildOverviewQuery = ({ defaultIndex, ip }: IpOverviewRequestOptions) => {
const dslQuery = {
allowNoIndices: true,
@ -99,6 +113,7 @@ export const buildOverviewQuery = ({ defaultIndex, ip }: IpOverviewRequestOption
aggs: {
...getAggs('source', ip),
...getAggs('destination', ip),
...getHostAggs(ip),
},
query: {
bool: {

View file

@ -57,7 +57,6 @@ export interface OverviewHit {
};
doc_count: number;
geo: ResultHit<object>;
host: ResultHit<object>;
autonomous_system: ResultHit<object>;
firstSeen: {
value: number;
@ -69,10 +68,25 @@ export interface OverviewHit {
};
}
export interface OverviewHostHit {
took?: number;
timed_out?: boolean;
_scroll_id?: string;
_shards?: ShardsResponse;
timeout?: number;
hits?: {
total: number;
hits: Hit[];
};
doc_count: number;
host: ResultHit<object>;
}
export interface IpOverviewHit {
aggregations: {
destination?: OverviewHit;
source?: OverviewHit;
host: OverviewHostHit;
};
_shards: {
total: number;

View file

@ -31,10 +31,10 @@ const ipOverviewTests: KbnTestProvider = ({ getService }) => {
const ipOverview = resp.data.source.IpOverview;
expect(ipOverview!.source!.geo!.continent_name).to.be('North America');
expect(ipOverview!.source!.geo!.location!.lat!).to.be(37.751);
expect(ipOverview!.source!.host!.os!.platform!).to.be('raspbian');
expect(ipOverview!.host.os!.platform!).to.be('raspbian');
expect(ipOverview!.destination!.geo!.continent_name).to.be('North America');
expect(ipOverview!.destination!.geo!.location!.lat!).to.be(37.751);
expect(ipOverview!.destination!.host!.os!.platform!).to.be('raspbian');
expect(ipOverview!.host.os!.platform!).to.be('raspbian');
});
});
});
@ -55,9 +55,9 @@ const ipOverviewTests: KbnTestProvider = ({ getService }) => {
})
.then(resp => {
const ipOverview = resp.data.source.IpOverview;
expect(ipOverview!.destination!.host!.id!).to.be('2ce8b1e7d69e4a1d9c6bcddc473da9d9');
expect(ipOverview!.destination!.host!.name!).to.be('zeek-sensor-amsterdam');
expect(ipOverview!.destination!.host!.os!.platform!).to.be('ubuntu');
expect(ipOverview!.host.id!).to.be('2ce8b1e7d69e4a1d9c6bcddc473da9d9');
expect(ipOverview!.host.name!).to.be('zeek-sensor-amsterdam');
expect(ipOverview!.host.os!.platform!).to.be('ubuntu');
});
});
});