mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Allow error to show in the application * Allow unauthorized user to use timeline api with redux storage * add callout to timeline to show + fix event details * Build fixes * fix pinned event * review I * fix details timeline test on api integration
This commit is contained in:
parent
91915690b6
commit
ffd4de9b9f
39 changed files with 1016 additions and 1599 deletions
|
@ -43,8 +43,8 @@
|
|||
# the username and password that the Kibana server uses to perform maintenance on the Kibana
|
||||
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
|
||||
# is proxied through the Kibana server.
|
||||
#elasticsearch.username: "user"
|
||||
#elasticsearch.password: "pass"
|
||||
elasticsearch.username: "elastic"
|
||||
elasticsearch.password: "yDaYCXL6KYgNligMpSwd"
|
||||
|
||||
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
|
||||
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
|
||||
|
|
|
@ -391,221 +391,141 @@ exports[`EventDetails rendering should match snapshot 1`] = `
|
|||
data={
|
||||
Array [
|
||||
Object {
|
||||
"category": "_id",
|
||||
"description": "Each document has an _id that uniquely identifies it",
|
||||
"example": "Y-6TfmcB0WOhS6qyMv3s",
|
||||
"field": "_id",
|
||||
"originalValue": "pEMaMmkBUV60JmNWmWVi",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"pEMaMmkBUV60JmNWmWVi",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_index",
|
||||
"description": "An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.",
|
||||
"example": "auditbeat-8.0.0-2019.02.19-000001",
|
||||
"field": "_index",
|
||||
"originalValue": "filebeat-8.0.0-2019.02.19-000001",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"filebeat-8.0.0-2019.02.19-000001",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_type",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "_type",
|
||||
"originalValue": "_doc",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"_doc",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_score",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "_score",
|
||||
"originalValue": 1,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"1",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "@timestamp",
|
||||
"description": "Date/time when the event originated.For log events this is the date/time when the event was generated, and not when it was read.Required field for all events.",
|
||||
"example": "2016-05-23T08:05:34.853Z",
|
||||
"field": "@timestamp",
|
||||
"originalValue": "2019-02-28T16:50:54.621Z",
|
||||
"type": "date",
|
||||
"values": Array [
|
||||
"2019-02-28T16:50:54.621Z",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Ephemeral identifier of this agent (if one exists).This id normally changes across restarts, but \`agent.id\` does not.",
|
||||
"example": "8a4f500f",
|
||||
"field": "agent.ephemeral_id",
|
||||
"originalValue": "9d391ef2-a734-4787-8891-67031178c641",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"9d391ef2-a734-4787-8891-67031178c641",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "agent.hostname",
|
||||
"originalValue": "siem-kibana",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"siem-kibana",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Unique identifier of this agent (if one exists).Example: For Beats this would be beat.id.",
|
||||
"example": "8a4f500d",
|
||||
"field": "agent.id",
|
||||
"originalValue": "5de03d5f-52f3-482e-91d4-853c7de073c3",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"5de03d5f-52f3-482e-91d4-853c7de073c3",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Type of the agent.The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.",
|
||||
"example": "filebeat",
|
||||
"field": "agent.type",
|
||||
"originalValue": "filebeat",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"filebeat",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Version of the agent.",
|
||||
"example": "6.0.0-rc2",
|
||||
"field": "agent.version",
|
||||
"originalValue": "8.0.0",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"8.0.0",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Availability zone in which this host is running.",
|
||||
"example": "us-east-1c",
|
||||
"field": "cloud.availability_zone",
|
||||
"originalValue": "projects/189716325846/zones/us-east1-b",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"projects/189716325846/zones/us-east1-b",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Instance ID of the host machine.",
|
||||
"example": "i-1234567890abcdef0",
|
||||
"field": "cloud.instance.id",
|
||||
"originalValue": "5412578377715150143",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"5412578377715150143",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Instance name of the host machine.",
|
||||
"example": null,
|
||||
"field": "cloud.instance.name",
|
||||
"originalValue": "siem-kibana",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"siem-kibana",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Machine type of the host machine.",
|
||||
"example": "t2.medium",
|
||||
"field": "cloud.machine.type",
|
||||
"originalValue": "projects/189716325846/machineTypes/n1-standard-1",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"projects/189716325846/machineTypes/n1-standard-1",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "cloud.project.id",
|
||||
"originalValue": "elastic-beats",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"elastic-beats",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Name of the cloud provider. Example values are ec2, gce, or digitalocean.",
|
||||
"example": "ec2",
|
||||
"field": "cloud.provider",
|
||||
"originalValue": "gce",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"gce",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Bytes sent from the destination to the source.",
|
||||
"example": "184",
|
||||
"field": "destination.bytes",
|
||||
"originalValue": 584,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"584",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "IP address of the destination.Can be one or multiple IPv4 or IPv6 addresses.",
|
||||
"example": null,
|
||||
"field": "destination.ip",
|
||||
"originalValue": "10.47.8.200",
|
||||
"type": "ip",
|
||||
"values": Array [
|
||||
"10.47.8.200",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Packets sent from the destination to the source.",
|
||||
"example": "12",
|
||||
"field": "destination.packets",
|
||||
"originalValue": 4,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"4",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Port of the destination.",
|
||||
"example": null,
|
||||
"field": "destination.port",
|
||||
"originalValue": 902,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"902",
|
||||
],
|
||||
|
|
|
@ -5,221 +5,141 @@ exports[`JSON View rendering should match snapshot 1`] = `
|
|||
data={
|
||||
Array [
|
||||
Object {
|
||||
"category": "_id",
|
||||
"description": "Each document has an _id that uniquely identifies it",
|
||||
"example": "Y-6TfmcB0WOhS6qyMv3s",
|
||||
"field": "_id",
|
||||
"originalValue": "pEMaMmkBUV60JmNWmWVi",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"pEMaMmkBUV60JmNWmWVi",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_index",
|
||||
"description": "An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.",
|
||||
"example": "auditbeat-8.0.0-2019.02.19-000001",
|
||||
"field": "_index",
|
||||
"originalValue": "filebeat-8.0.0-2019.02.19-000001",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"filebeat-8.0.0-2019.02.19-000001",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_type",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "_type",
|
||||
"originalValue": "_doc",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"_doc",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "_score",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "_score",
|
||||
"originalValue": 1,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"1",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "@timestamp",
|
||||
"description": "Date/time when the event originated.For log events this is the date/time when the event was generated, and not when it was read.Required field for all events.",
|
||||
"example": "2016-05-23T08:05:34.853Z",
|
||||
"field": "@timestamp",
|
||||
"originalValue": "2019-02-28T16:50:54.621Z",
|
||||
"type": "date",
|
||||
"values": Array [
|
||||
"2019-02-28T16:50:54.621Z",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Ephemeral identifier of this agent (if one exists).This id normally changes across restarts, but \`agent.id\` does not.",
|
||||
"example": "8a4f500f",
|
||||
"field": "agent.ephemeral_id",
|
||||
"originalValue": "9d391ef2-a734-4787-8891-67031178c641",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"9d391ef2-a734-4787-8891-67031178c641",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "agent.hostname",
|
||||
"originalValue": "siem-kibana",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"siem-kibana",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Unique identifier of this agent (if one exists).Example: For Beats this would be beat.id.",
|
||||
"example": "8a4f500d",
|
||||
"field": "agent.id",
|
||||
"originalValue": "5de03d5f-52f3-482e-91d4-853c7de073c3",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"5de03d5f-52f3-482e-91d4-853c7de073c3",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Type of the agent.The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.",
|
||||
"example": "filebeat",
|
||||
"field": "agent.type",
|
||||
"originalValue": "filebeat",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"filebeat",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "agent",
|
||||
"description": "Version of the agent.",
|
||||
"example": "6.0.0-rc2",
|
||||
"field": "agent.version",
|
||||
"originalValue": "8.0.0",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"8.0.0",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Availability zone in which this host is running.",
|
||||
"example": "us-east-1c",
|
||||
"field": "cloud.availability_zone",
|
||||
"originalValue": "projects/189716325846/zones/us-east1-b",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"projects/189716325846/zones/us-east1-b",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Instance ID of the host machine.",
|
||||
"example": "i-1234567890abcdef0",
|
||||
"field": "cloud.instance.id",
|
||||
"originalValue": "5412578377715150143",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"5412578377715150143",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Instance name of the host machine.",
|
||||
"example": null,
|
||||
"field": "cloud.instance.name",
|
||||
"originalValue": "siem-kibana",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"siem-kibana",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Machine type of the host machine.",
|
||||
"example": "t2.medium",
|
||||
"field": "cloud.machine.type",
|
||||
"originalValue": "projects/189716325846/machineTypes/n1-standard-1",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"projects/189716325846/machineTypes/n1-standard-1",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": null,
|
||||
"example": null,
|
||||
"field": "cloud.project.id",
|
||||
"originalValue": "elastic-beats",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"elastic-beats",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "cloud",
|
||||
"description": "Name of the cloud provider. Example values are ec2, gce, or digitalocean.",
|
||||
"example": "ec2",
|
||||
"field": "cloud.provider",
|
||||
"originalValue": "gce",
|
||||
"type": "keyword",
|
||||
"values": Array [
|
||||
"gce",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Bytes sent from the destination to the source.",
|
||||
"example": "184",
|
||||
"field": "destination.bytes",
|
||||
"originalValue": 584,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"584",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "IP address of the destination.Can be one or multiple IPv4 or IPv6 addresses.",
|
||||
"example": null,
|
||||
"field": "destination.ip",
|
||||
"originalValue": "10.47.8.200",
|
||||
"type": "ip",
|
||||
"values": Array [
|
||||
"10.47.8.200",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Packets sent from the destination to the source.",
|
||||
"example": "12",
|
||||
"field": "destination.packets",
|
||||
"originalValue": 4,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"4",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"category": "destination",
|
||||
"description": "Port of the destination.",
|
||||
"example": null,
|
||||
"field": "destination.port",
|
||||
"originalValue": 902,
|
||||
"type": "long",
|
||||
"values": Array [
|
||||
"902",
|
||||
],
|
||||
|
|
|
@ -12,7 +12,7 @@ import styled from 'styled-components';
|
|||
import { BrowserFields } from '../../containers/source';
|
||||
import { DragEffects } from '../drag_and_drop/draggable_wrapper';
|
||||
import { DefaultDraggable } from '../draggables';
|
||||
import { DetailItem, ToStringArray } from '../../graphql/types';
|
||||
import { ToStringArray } from '../../graphql/types';
|
||||
import { DroppableWrapper } from '../drag_and_drop/droppable_wrapper';
|
||||
import { DraggableFieldBadge } from '../draggables/field_badge';
|
||||
import { FormattedFieldValue } from '../timeline/body/renderers/formatted_field';
|
||||
|
@ -28,6 +28,7 @@ import * as i18n from './translations';
|
|||
import { OverflowField } from '../tables/helpers';
|
||||
import { DATE_FIELD_TYPE, MESSAGE_FIELD_NAME } from '../timeline/body/renderers/constants';
|
||||
import { EVENT_DURATION_FIELD_NAME } from '../duration';
|
||||
import { EventFieldsData } from './types';
|
||||
|
||||
const HoverActionsContainer = styled(EuiPanel)`
|
||||
align-items: center;
|
||||
|
@ -76,7 +77,7 @@ export const getColumns = ({
|
|||
name: i18n.FIELD,
|
||||
sortable: true,
|
||||
truncateText: false,
|
||||
render: (field: string, data: DetailItem) => (
|
||||
render: (field: string, data: EventFieldsData) => (
|
||||
<DroppableWrapper
|
||||
droppableId={getDroppableId(
|
||||
`event-details-${eventId}-${data.category}-${field}-${timelineId}`
|
||||
|
@ -125,7 +126,7 @@ export const getColumns = ({
|
|||
name: i18n.VALUE,
|
||||
sortable: true,
|
||||
truncateText: false,
|
||||
render: (values: ToStringArray | null | undefined, data: DetailItem) => (
|
||||
render: (values: ToStringArray | null | undefined, data: EventFieldsData) => (
|
||||
<EuiFlexGroup direction="column" alignItems="flexStart" component="span" gutterSize="none">
|
||||
{values != null &&
|
||||
values.map((value, i) => (
|
||||
|
@ -176,7 +177,7 @@ export const getColumns = ({
|
|||
{
|
||||
field: 'description',
|
||||
name: i18n.DESCRIPTION,
|
||||
render: (description: string | null | undefined, data: DetailItem) => (
|
||||
render: (description: string | null | undefined, data: EventFieldsData) => (
|
||||
<SelectableText>{`${description || ''} ${getExampleText(data.example)}`}</SelectableText>
|
||||
),
|
||||
sortable: true,
|
||||
|
@ -185,9 +186,9 @@ export const getColumns = ({
|
|||
},
|
||||
{
|
||||
field: 'valuesConcatenated',
|
||||
render: () => null,
|
||||
sortable: false,
|
||||
truncateText: true,
|
||||
render: () => null,
|
||||
width: '1px',
|
||||
},
|
||||
];
|
||||
|
|
|
@ -101,7 +101,7 @@ describe('EventFieldsBrowser', () => {
|
|||
.find('[data-test-subj="field-name"]')
|
||||
.at(0)
|
||||
.text()
|
||||
).toEqual('_id');
|
||||
).toEqual('@timestamp');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -124,7 +124,7 @@ describe('EventFieldsBrowser', () => {
|
|||
.find('[data-test-subj="draggable-content"]')
|
||||
.at(0)
|
||||
.text()
|
||||
).toEqual('pEMaMmkBUV60JmNWmWVi');
|
||||
).toEqual('Feb 28, 2019 @ 16:50:54.621');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -149,7 +149,9 @@ describe('EventFieldsBrowser', () => {
|
|||
.find('.euiTableRowCell')
|
||||
.at(3)
|
||||
.text()
|
||||
).toContain('Each document has an _id that uniquely identifies it');
|
||||
).toContain(
|
||||
'DescriptionDate/time when the event originated. For log events this is the date/time when the event was generated, and not when it was read. Required field for all events. Example: 2016-05-23T08:05:34.853Z'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,7 +11,8 @@ import {
|
|||
import * as React from 'react';
|
||||
import { pure } from 'recompose';
|
||||
|
||||
import { BrowserFields } from '../../containers/source';
|
||||
import { sortBy } from 'lodash';
|
||||
import { BrowserFields, getAllFieldsByName } from '../../containers/source';
|
||||
import { DetailItem } from '../../graphql/types';
|
||||
import { OnUpdateColumns } from '../timeline/events';
|
||||
|
||||
|
@ -29,22 +30,28 @@ interface Props {
|
|||
|
||||
/** Renders a table view or JSON view of the `ECS` `data` */
|
||||
export const EventFieldsBrowser = pure<Props>(
|
||||
({ browserFields, data, eventId, isLoading, onUpdateColumns, timelineId }) => (
|
||||
<EuiInMemoryTable
|
||||
items={data.map(item => ({
|
||||
...item,
|
||||
valuesConcatenated: item.values != null ? item.values.join() : '',
|
||||
}))}
|
||||
columns={getColumns({
|
||||
browserFields,
|
||||
eventId,
|
||||
isLoading,
|
||||
onUpdateColumns,
|
||||
timelineId,
|
||||
})}
|
||||
pagination={false}
|
||||
search={search}
|
||||
sorting={true}
|
||||
/>
|
||||
)
|
||||
({ browserFields, data, eventId, isLoading, onUpdateColumns, timelineId }) => {
|
||||
const fieldsByName = getAllFieldsByName(browserFields);
|
||||
return (
|
||||
<EuiInMemoryTable
|
||||
items={sortBy(data, ['field']).map(item => {
|
||||
return {
|
||||
...item,
|
||||
...fieldsByName[item.field],
|
||||
valuesConcatenated: item.values != null ? item.values.join() : '',
|
||||
};
|
||||
})}
|
||||
columns={getColumns({
|
||||
browserFields,
|
||||
eventId,
|
||||
isLoading,
|
||||
onUpdateColumns,
|
||||
timelineId,
|
||||
})}
|
||||
pagination={false}
|
||||
search={search}
|
||||
sorting={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -7,13 +7,17 @@
|
|||
import { mockDetailItemData } from '../../mock/mock_detail_item';
|
||||
|
||||
import { getExampleText, getIconFromType } from './helpers';
|
||||
import { mockBrowserFields } from '../../containers/source/mock';
|
||||
|
||||
const aField = mockDetailItemData[0];
|
||||
const aField = {
|
||||
...mockDetailItemData[4],
|
||||
...mockBrowserFields.base.fields!['@timestamp'],
|
||||
};
|
||||
|
||||
describe('helpers', () => {
|
||||
describe('getExampleText', () => {
|
||||
test('it returns the expected example text when the field contains an example', () => {
|
||||
expect(getExampleText(aField.example)).toEqual('Example: Y-6TfmcB0WOhS6qyMv3s');
|
||||
expect(getExampleText(aField.example)).toEqual('Example: 2016-05-23T08:05:34.853Z');
|
||||
});
|
||||
|
||||
test(`it returns an empty string when the field's example is an empty string`, () => {
|
||||
|
|
10
x-pack/plugins/siem/public/components/event_details/types.ts
Normal file
10
x-pack/plugins/siem/public/components/event_details/types.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { BrowserField } from '../../containers/source';
|
||||
import { DetailItem } from '../../graphql/types';
|
||||
|
||||
export type EventFieldsData = BrowserField & DetailItem;
|
|
@ -741,6 +741,7 @@ In other use cases the message field can be used to concatenate different values
|
|||
onToggleDataProviderEnabled={[MockFunction]}
|
||||
onToggleDataProviderExcluded={[MockFunction]}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
sort={
|
||||
Object {
|
||||
"columnId": "@timestamp",
|
||||
|
|
|
@ -230,6 +230,7 @@ exports[`Header rendering renders correctly against snapshot 1`] = `
|
|||
onToggleDataProviderEnabled={[MockFunction]}
|
||||
onToggleDataProviderExcluded={[MockFunction]}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
sort={
|
||||
Object {
|
||||
"columnId": "@timestamp",
|
||||
|
|
|
@ -33,6 +33,7 @@ describe('Header', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
sort={{
|
||||
columnId: '@timestamp',
|
||||
sortDirection: Direction.desc,
|
||||
|
@ -57,6 +58,7 @@ describe('Header', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
sort={{
|
||||
columnId: '@timestamp',
|
||||
sortDirection: Direction.desc,
|
||||
|
@ -67,5 +69,32 @@ describe('Header', () => {
|
|||
|
||||
expect(wrapper.find('[data-test-subj="dataProviders"]').exists()).toEqual(true);
|
||||
});
|
||||
|
||||
test('it renders the unauthorized call out providers', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<TimelineHeader
|
||||
browserFields={{}}
|
||||
dataProviders={mockDataProviders}
|
||||
id="foo"
|
||||
indexPattern={indexPattern}
|
||||
onChangeDataProviderKqlQuery={jest.fn()}
|
||||
onChangeDroppableAndProvider={jest.fn()}
|
||||
onDataProviderEdited={jest.fn()}
|
||||
onDataProviderRemoved={jest.fn()}
|
||||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={true}
|
||||
sort={{
|
||||
columnId: '@timestamp',
|
||||
sortDirection: Direction.desc,
|
||||
}}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="timelineCallOutUnauthorized"]').exists()).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
import * as React from 'react';
|
||||
import { pure } from 'recompose';
|
||||
import styled from 'styled-components';
|
||||
|
@ -23,6 +24,8 @@ import {
|
|||
import { StatefulSearchOrFilter } from '../search_or_filter';
|
||||
import { BrowserFields } from '../../../containers/source';
|
||||
|
||||
import * as i18n from './translations';
|
||||
|
||||
interface Props {
|
||||
browserFields: BrowserFields;
|
||||
dataProviders: DataProvider[];
|
||||
|
@ -35,6 +38,7 @@ interface Props {
|
|||
onToggleDataProviderEnabled: OnToggleDataProviderEnabled;
|
||||
onToggleDataProviderExcluded: OnToggleDataProviderExcluded;
|
||||
show: boolean;
|
||||
showCallOutUnauthorizedMsg: boolean;
|
||||
sort: Sort;
|
||||
}
|
||||
|
||||
|
@ -55,8 +59,18 @@ export const TimelineHeader = pure<Props>(
|
|||
onToggleDataProviderEnabled,
|
||||
onToggleDataProviderExcluded,
|
||||
show,
|
||||
showCallOutUnauthorizedMsg,
|
||||
}) => (
|
||||
<TimelineHeaderContainer data-test-subj="timelineHeader">
|
||||
{showCallOutUnauthorizedMsg && (
|
||||
<EuiCallOut
|
||||
data-test-subj="timelineCallOutUnauthorized"
|
||||
title={i18n.CALL_OUT_UNAUTHORIZED_MSG}
|
||||
color="warning"
|
||||
iconType="alert"
|
||||
size="s"
|
||||
/>
|
||||
)}
|
||||
<DataProviders
|
||||
browserFields={browserFields}
|
||||
id={id}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const CALL_OUT_UNAUTHORIZED_MSG = i18n.translate(
|
||||
'xpack.siem.timeline.callOut.unauthorized.message.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'You require permission to auto-save timelines within the SIEM application, though you may continue to use the timeline to search and filter security events',
|
||||
}
|
||||
);
|
|
@ -49,6 +49,7 @@ interface StateReduxProps {
|
|||
sort?: Sort;
|
||||
start: number;
|
||||
show?: boolean;
|
||||
showCallOutUnauthorizedMsg: boolean;
|
||||
}
|
||||
|
||||
interface DispatchProps {
|
||||
|
@ -139,6 +140,7 @@ class StatefulTimelineComponent extends React.Component<Props> {
|
|||
sort,
|
||||
start,
|
||||
show,
|
||||
showCallOutUnauthorizedMsg,
|
||||
}: Props) =>
|
||||
id !== this.props.id ||
|
||||
flyoutHeaderHeight !== this.props.flyoutHeaderHeight ||
|
||||
|
@ -155,7 +157,8 @@ class StatefulTimelineComponent extends React.Component<Props> {
|
|||
pageCount !== this.props.pageCount ||
|
||||
!isEqual(sort, this.props.sort) ||
|
||||
start !== this.props.start ||
|
||||
show !== this.props.show;
|
||||
show !== this.props.show ||
|
||||
showCallOutUnauthorizedMsg !== this.props.showCallOutUnauthorizedMsg;
|
||||
|
||||
public componentDidMount() {
|
||||
const { createTimeline, id } = this.props;
|
||||
|
@ -179,6 +182,7 @@ class StatefulTimelineComponent extends React.Component<Props> {
|
|||
kqlMode,
|
||||
kqlQueryExpression,
|
||||
show,
|
||||
showCallOutUnauthorizedMsg,
|
||||
start,
|
||||
sort,
|
||||
} = this.props;
|
||||
|
@ -208,6 +212,7 @@ class StatefulTimelineComponent extends React.Component<Props> {
|
|||
onToggleDataProviderEnabled={this.onToggleDataProviderEnabled}
|
||||
onToggleDataProviderExcluded={this.onToggleDataProviderExcluded}
|
||||
show={show!}
|
||||
showCallOutUnauthorizedMsg={showCallOutUnauthorizedMsg}
|
||||
start={start}
|
||||
sort={sort!}
|
||||
/>
|
||||
|
@ -274,6 +279,7 @@ class StatefulTimelineComponent extends React.Component<Props> {
|
|||
}
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getShowCallOutUnauthorizedMsg = timelineSelectors.getShowCallOutUnauthorizedMsg();
|
||||
const getTimeline = timelineSelectors.getTimelineByIdSelector();
|
||||
const getKqlQueryTimeline = timelineSelectors.getKqlFilterQuerySelector();
|
||||
const getInputsTimeline = inputsSelectors.getTimelineSelector();
|
||||
|
@ -303,6 +309,7 @@ const makeMapStateToProps = () => {
|
|||
kqlQueryExpression,
|
||||
sort,
|
||||
start: input.timerange.from,
|
||||
showCallOutUnauthorizedMsg: getShowCallOutUnauthorizedMsg(state),
|
||||
show,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -67,6 +67,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -100,6 +101,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -136,6 +138,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -172,6 +175,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -213,6 +217,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -256,6 +261,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -307,6 +313,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={mockOnToggleDataProviderEnabled}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -362,6 +369,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={mockOnToggleDataProviderExcluded}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -418,6 +426,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -466,6 +475,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -518,6 +528,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={mockOnToggleDataProviderEnabled}
|
||||
onToggleDataProviderExcluded={jest.fn()}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
@ -574,6 +585,7 @@ describe('Timeline', () => {
|
|||
onToggleDataProviderEnabled={jest.fn()}
|
||||
onToggleDataProviderExcluded={mockOnToggleDataProviderExcluded}
|
||||
show={true}
|
||||
showCallOutUnauthorizedMsg={false}
|
||||
start={startDate}
|
||||
sort={sort}
|
||||
/>
|
||||
|
|
|
@ -71,6 +71,7 @@ interface Props {
|
|||
onToggleDataProviderEnabled: OnToggleDataProviderEnabled;
|
||||
onToggleDataProviderExcluded: OnToggleDataProviderExcluded;
|
||||
show: boolean;
|
||||
showCallOutUnauthorizedMsg: boolean;
|
||||
start: number;
|
||||
sort: Sort;
|
||||
}
|
||||
|
@ -99,6 +100,7 @@ export const Timeline = pure<Props>(
|
|||
onToggleDataProviderEnabled,
|
||||
onToggleDataProviderExcluded,
|
||||
show,
|
||||
showCallOutUnauthorizedMsg,
|
||||
start,
|
||||
sort,
|
||||
}) => {
|
||||
|
@ -134,6 +136,7 @@ export const Timeline = pure<Props>(
|
|||
onToggleDataProviderEnabled={onToggleDataProviderEnabled}
|
||||
onToggleDataProviderExcluded={onToggleDataProviderExcluded}
|
||||
show={show}
|
||||
showCallOutUnauthorizedMsg={showCallOutUnauthorizedMsg}
|
||||
sort={sort}
|
||||
/>
|
||||
</WrappedByAutoSizer>
|
||||
|
|
|
@ -17,11 +17,7 @@ export const timelineDetailsQuery = gql`
|
|||
id
|
||||
TimelineDetails(eventId: $eventId, indexName: $indexName, defaultIndex: $defaultIndex) {
|
||||
data {
|
||||
category
|
||||
description
|
||||
example
|
||||
field
|
||||
type
|
||||
values
|
||||
originalValue
|
||||
}
|
||||
|
|
|
@ -527,6 +527,22 @@
|
|||
"name": "PinnedEvent",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "code",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "pinnedEventId",
|
||||
"description": "",
|
||||
|
@ -5327,34 +5343,6 @@
|
|||
"name": "DetailItem",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "category",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "example",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "field",
|
||||
"description": "",
|
||||
|
@ -5367,18 +5355,6 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "values",
|
||||
"description": "",
|
||||
|
@ -8429,6 +8405,14 @@
|
|||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
|
@ -9316,6 +9300,12 @@
|
|||
"description": "",
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "operator",
|
||||
"description": "",
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"interfaces": null,
|
||||
|
@ -9475,6 +9465,22 @@
|
|||
"name": "ResponseFavoriteTimeline",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "code",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "savedObjectId",
|
||||
"description": "",
|
||||
|
|
|
@ -79,6 +79,10 @@ export interface ResponseNotes {
|
|||
}
|
||||
|
||||
export interface PinnedEvent {
|
||||
code?: number | null;
|
||||
|
||||
message?: string | null;
|
||||
|
||||
pinnedEventId: string;
|
||||
|
||||
eventId?: string | null;
|
||||
|
@ -832,16 +836,8 @@ export interface TimelineDetailsData {
|
|||
}
|
||||
|
||||
export interface DetailItem {
|
||||
category: string;
|
||||
|
||||
description?: string | null;
|
||||
|
||||
example?: string | null;
|
||||
|
||||
field: string;
|
||||
|
||||
type: string;
|
||||
|
||||
values?: ToStringArray | null;
|
||||
|
||||
originalValue?: EsValue | null;
|
||||
|
@ -1338,6 +1334,8 @@ export interface QueryMatchResult {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
}
|
||||
|
||||
export interface DateRangePickerResult {
|
||||
|
@ -1420,6 +1418,10 @@ export interface ResponseTimeline {
|
|||
}
|
||||
|
||||
export interface ResponseFavoriteTimeline {
|
||||
code?: number | null;
|
||||
|
||||
message?: string | null;
|
||||
|
||||
savedObjectId: string;
|
||||
|
||||
version: string;
|
||||
|
@ -1625,6 +1627,8 @@ export interface QueryMatchInput {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
}
|
||||
|
||||
export interface SerializedFilterQueryInput {
|
||||
|
@ -3504,16 +3508,8 @@ export namespace GetTimelineDetailsQuery {
|
|||
export type Data = {
|
||||
__typename?: 'DetailItem';
|
||||
|
||||
category: string;
|
||||
|
||||
description?: string | null;
|
||||
|
||||
example?: string | null;
|
||||
|
||||
field: string;
|
||||
|
||||
type: string;
|
||||
|
||||
values?: ToStringArray | null;
|
||||
|
||||
originalValue?: EsValue | null;
|
||||
|
@ -4384,6 +4380,8 @@ export namespace GetOneTimeline {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
};
|
||||
|
||||
export type And = {
|
||||
|
@ -4412,6 +4410,8 @@ export namespace GetOneTimeline {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
};
|
||||
|
||||
export type DateRange = {
|
||||
|
@ -4640,6 +4640,8 @@ export namespace PersistTimelineMutation {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
};
|
||||
|
||||
export type And = {
|
||||
|
@ -4668,6 +4670,8 @@ export namespace PersistTimelineMutation {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
};
|
||||
|
||||
export type Favorite = {
|
||||
|
|
|
@ -113,6 +113,7 @@ export const mockGlobalState: State = {
|
|||
},
|
||||
dragAndDrop: { dataProviders: {} },
|
||||
timeline: {
|
||||
showCallOutUnauthorizedMsg: false,
|
||||
autoSavedWarningMsg: {
|
||||
timelineId: null,
|
||||
newTimelineModel: null,
|
||||
|
|
|
@ -10,187 +10,102 @@ export const mockDetailItemDataId = 'Y-6TfmcB0WOhS6qyMv3s';
|
|||
|
||||
export const mockDetailItemData: DetailItem[] = [
|
||||
{
|
||||
category: '_id',
|
||||
description: 'Each document has an _id that uniquely identifies it',
|
||||
example: 'Y-6TfmcB0WOhS6qyMv3s',
|
||||
field: '_id',
|
||||
type: 'keyword',
|
||||
originalValue: 'pEMaMmkBUV60JmNWmWVi',
|
||||
values: ['pEMaMmkBUV60JmNWmWVi'],
|
||||
},
|
||||
{
|
||||
category: '_index',
|
||||
description:
|
||||
'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.',
|
||||
example: 'auditbeat-8.0.0-2019.02.19-000001',
|
||||
field: '_index',
|
||||
type: 'keyword',
|
||||
originalValue: 'filebeat-8.0.0-2019.02.19-000001',
|
||||
values: ['filebeat-8.0.0-2019.02.19-000001'],
|
||||
},
|
||||
{
|
||||
category: '_type',
|
||||
description: null,
|
||||
example: null,
|
||||
field: '_type',
|
||||
type: 'keyword',
|
||||
originalValue: '_doc',
|
||||
values: ['_doc'],
|
||||
},
|
||||
{
|
||||
category: '_score',
|
||||
description: null,
|
||||
example: null,
|
||||
field: '_score',
|
||||
type: 'long',
|
||||
originalValue: 1,
|
||||
values: ['1'],
|
||||
},
|
||||
{
|
||||
category: '@timestamp',
|
||||
description:
|
||||
'Date/time when the event originated.For log events this is the date/time when the event was generated, and not when it was read.Required field for all events.',
|
||||
example: '2016-05-23T08:05:34.853Z',
|
||||
field: '@timestamp',
|
||||
type: 'date',
|
||||
originalValue: '2019-02-28T16:50:54.621Z',
|
||||
values: ['2019-02-28T16:50:54.621Z'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Ephemeral identifier of this agent (if one exists).This id normally changes across restarts, but `agent.id` does not.',
|
||||
example: '8a4f500f',
|
||||
field: 'agent.ephemeral_id',
|
||||
type: 'keyword',
|
||||
originalValue: '9d391ef2-a734-4787-8891-67031178c641',
|
||||
values: ['9d391ef2-a734-4787-8891-67031178c641'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'agent.hostname',
|
||||
type: 'keyword',
|
||||
originalValue: 'siem-kibana',
|
||||
values: ['siem-kibana'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Unique identifier of this agent (if one exists).Example: For Beats this would be beat.id.',
|
||||
example: '8a4f500d',
|
||||
field: 'agent.id',
|
||||
type: 'keyword',
|
||||
originalValue: '5de03d5f-52f3-482e-91d4-853c7de073c3',
|
||||
values: ['5de03d5f-52f3-482e-91d4-853c7de073c3'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Type of the agent.The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.',
|
||||
example: 'filebeat',
|
||||
field: 'agent.type',
|
||||
type: 'keyword',
|
||||
originalValue: 'filebeat',
|
||||
values: ['filebeat'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description: 'Version of the agent.',
|
||||
example: '6.0.0-rc2',
|
||||
field: 'agent.version',
|
||||
type: 'keyword',
|
||||
originalValue: '8.0.0',
|
||||
values: ['8.0.0'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: 'Availability zone in which this host is running.',
|
||||
example: 'us-east-1c',
|
||||
field: 'cloud.availability_zone',
|
||||
type: 'keyword',
|
||||
originalValue: 'projects/189716325846/zones/us-east1-b',
|
||||
values: ['projects/189716325846/zones/us-east1-b'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: 'Instance ID of the host machine.',
|
||||
example: 'i-1234567890abcdef0',
|
||||
field: 'cloud.instance.id',
|
||||
type: 'keyword',
|
||||
originalValue: '5412578377715150143',
|
||||
values: ['5412578377715150143'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: 'Instance name of the host machine.',
|
||||
example: null,
|
||||
field: 'cloud.instance.name',
|
||||
type: 'keyword',
|
||||
originalValue: 'siem-kibana',
|
||||
values: ['siem-kibana'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: 'Machine type of the host machine.',
|
||||
example: 't2.medium',
|
||||
field: 'cloud.machine.type',
|
||||
type: 'keyword',
|
||||
originalValue: 'projects/189716325846/machineTypes/n1-standard-1',
|
||||
values: ['projects/189716325846/machineTypes/n1-standard-1'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'cloud.project.id',
|
||||
type: 'keyword',
|
||||
originalValue: 'elastic-beats',
|
||||
values: ['elastic-beats'],
|
||||
},
|
||||
{
|
||||
category: 'cloud',
|
||||
description: 'Name of the cloud provider. Example values are ec2, gce, or digitalocean.',
|
||||
example: 'ec2',
|
||||
field: 'cloud.provider',
|
||||
type: 'keyword',
|
||||
originalValue: 'gce',
|
||||
values: ['gce'],
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'Bytes sent from the destination to the source.',
|
||||
example: '184',
|
||||
field: 'destination.bytes',
|
||||
type: 'long',
|
||||
originalValue: 584,
|
||||
values: ['584'],
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'IP address of the destination.Can be one or multiple IPv4 or IPv6 addresses.',
|
||||
example: null,
|
||||
field: 'destination.ip',
|
||||
type: 'ip',
|
||||
originalValue: '10.47.8.200',
|
||||
values: ['10.47.8.200'],
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'Packets sent from the destination to the source.',
|
||||
example: '12',
|
||||
field: 'destination.packets',
|
||||
type: 'long',
|
||||
originalValue: 4,
|
||||
values: ['4'],
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'Port of the destination.',
|
||||
example: null,
|
||||
field: 'destination.port',
|
||||
type: 'long',
|
||||
originalValue: 902,
|
||||
values: ['902'],
|
||||
},
|
||||
|
|
|
@ -183,3 +183,5 @@ export const updateAutoSaveMsg = actionCreator<{
|
|||
timelineId: string | null;
|
||||
newTimelineModel: TimelineModel | null;
|
||||
}>('UPDATE_AUTO_SAVE');
|
||||
|
||||
export const showCallOutUnauthorizedMsg = actionCreator('SHOW_CALL_OUT_UNAUTHORIZED_MSG');
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
TimelineResult,
|
||||
} from '../../graphql/types';
|
||||
import { AppApolloClient } from '../../lib/lib';
|
||||
import { addError } from '../app/actions';
|
||||
import { NotesById } from '../app/model';
|
||||
import { TimeRange } from '../inputs/model';
|
||||
|
||||
|
@ -55,6 +56,7 @@ import {
|
|||
endTimelineSaving,
|
||||
createTimeline,
|
||||
addTimeline,
|
||||
showCallOutUnauthorizedMsg,
|
||||
} from './actions';
|
||||
import { TimelineModel } from './model';
|
||||
import { TimelineById } from './reducer';
|
||||
|
@ -131,6 +133,9 @@ export const createTimelineEpic = <State>(): Epic<
|
|||
withLatestFrom(timeline$),
|
||||
filter(([action, timeline]) => {
|
||||
const timelineId: TimelineModel = timeline[get('payload.id', action)];
|
||||
if (action.type === addError.type) {
|
||||
return true;
|
||||
}
|
||||
if (action.type === createTimeline.type) {
|
||||
myEpicTimelineId.setTimelineId(null);
|
||||
myEpicTimelineId.setTimelineVersion(null);
|
||||
|
@ -186,6 +191,7 @@ export const createTimelineEpic = <State>(): Epic<
|
|||
mergeMap(([result, recentTimeline]) => {
|
||||
const savedTimeline = recentTimeline[get('payload.id', action)];
|
||||
const response: ResponseTimeline = get('data.persistTimeline', result);
|
||||
const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : [];
|
||||
|
||||
return [
|
||||
response.code === 409
|
||||
|
@ -202,6 +208,7 @@ export const createTimelineEpic = <State>(): Epic<
|
|||
isSaving: false,
|
||||
},
|
||||
}),
|
||||
...callOutMsg,
|
||||
endTimelineSaving({
|
||||
id: get('payload.id', action),
|
||||
}),
|
||||
|
|
|
@ -14,12 +14,13 @@ import { filter, mergeMap, withLatestFrom, startWith, takeUntil } from 'rxjs/ope
|
|||
|
||||
import { persistTimelineFavoriteMutation } from '../../containers/timeline/favorite/persist.gql_query';
|
||||
import { PersistTimelineFavoriteMutation, ResponseFavoriteTimeline } from '../../graphql/types';
|
||||
|
||||
import { addError } from '../app/actions';
|
||||
import {
|
||||
endTimelineSaving,
|
||||
updateIsFavorite,
|
||||
updateTimeline,
|
||||
startTimelineSaving,
|
||||
showCallOutUnauthorizedMsg,
|
||||
} from './actions';
|
||||
import { TimelineById } from './reducer';
|
||||
import { dispatcherTimelinePersistQueue } from './epic_dispatcher_timeline_persistence_queue';
|
||||
|
@ -53,7 +54,10 @@ export const epicPersistTimelineFavorite = (
|
|||
mergeMap(([result, recentTimelines]) => {
|
||||
const savedTimeline = recentTimelines[get('payload.id', action)];
|
||||
const response: ResponseFavoriteTimeline = get('data.persistFavorite', result);
|
||||
const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : [];
|
||||
|
||||
return [
|
||||
...callOutMsg,
|
||||
updateTimeline({
|
||||
id: get('payload.id', action),
|
||||
timeline: {
|
||||
|
@ -73,6 +77,9 @@ export const epicPersistTimelineFavorite = (
|
|||
action$.pipe(
|
||||
withLatestFrom(timeline$),
|
||||
filter(([checkAction, updatedTimeline]) => {
|
||||
if (checkAction.type === addError.type) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
checkAction.type === endTimelineSaving.type &&
|
||||
updatedTimeline[get('payload.id', checkAction)].savedObjectId != null
|
||||
|
|
|
@ -14,7 +14,7 @@ import { filter, mergeMap, switchMap, withLatestFrom, startWith, takeUntil } fro
|
|||
|
||||
import { persistTimelineNoteMutation } from '../../containers/timeline/notes/persist.gql_query';
|
||||
import { PersistTimelineNoteMutation, ResponseNote } from '../../graphql/types';
|
||||
import { updateNote } from '../app/actions';
|
||||
import { updateNote, addError } from '../app/actions';
|
||||
import { NotesById } from '../app/model';
|
||||
|
||||
import {
|
||||
|
@ -23,6 +23,7 @@ import {
|
|||
endTimelineSaving,
|
||||
updateTimeline,
|
||||
startTimelineSaving,
|
||||
showCallOutUnauthorizedMsg,
|
||||
} from './actions';
|
||||
import { TimelineById } from './reducer';
|
||||
import { myEpicTimelineId } from './my_epic_timeline_id';
|
||||
|
@ -63,8 +64,10 @@ export const epicPersistNote = (
|
|||
mergeMap(([result, recentTimeline, recentNotes]) => {
|
||||
const noteIdRedux = get('payload.noteId', action);
|
||||
const response: ResponseNote = get('data.persistNote', result);
|
||||
const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : [];
|
||||
|
||||
return [
|
||||
...callOutMsg,
|
||||
recentTimeline[get('payload.id', action)].savedObjectId == null
|
||||
? updateTimeline({
|
||||
id: get('payload.id', action),
|
||||
|
@ -100,6 +103,9 @@ export const epicPersistNote = (
|
|||
action$.pipe(
|
||||
withLatestFrom(timeline$),
|
||||
filter(([checkAction, updatedTimeline]) => {
|
||||
if (checkAction.type === addError.type) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
checkAction.type === endTimelineSaving.type &&
|
||||
updatedTimeline[get('payload.id', checkAction)].savedObjectId != null
|
||||
|
|
|
@ -14,13 +14,14 @@ import { filter, mergeMap, startWith, withLatestFrom, takeUntil } from 'rxjs/ope
|
|||
|
||||
import { persistTimelinePinnedEventMutation } from '../../containers/timeline/pinned_event/persist.gql_query';
|
||||
import { PersistTimelinePinnedEventMutation, PinnedEvent } from '../../graphql/types';
|
||||
|
||||
import { addError } from '../app/actions';
|
||||
import {
|
||||
pinEvent,
|
||||
endTimelineSaving,
|
||||
unPinEvent,
|
||||
updateTimeline,
|
||||
startTimelineSaving,
|
||||
showCallOutUnauthorizedMsg,
|
||||
} from './actions';
|
||||
import { TimelineById } from './reducer';
|
||||
import { myEpicTimelineId } from './my_epic_timeline_id';
|
||||
|
@ -63,6 +64,7 @@ export const epicPersistPinnedEvent = (
|
|||
mergeMap(([result, recentTimeline]) => {
|
||||
const savedTimeline = recentTimeline[get('payload.id', action)];
|
||||
const response: PinnedEvent = get('data.persistPinnedEventOnTimeline', result);
|
||||
const callOutMsg = response && response.code === 403 ? [showCallOutUnauthorizedMsg()] : [];
|
||||
|
||||
return [
|
||||
response != null
|
||||
|
@ -94,6 +96,7 @@ export const epicPersistPinnedEvent = (
|
|||
),
|
||||
},
|
||||
}),
|
||||
...callOutMsg,
|
||||
endTimelineSaving({
|
||||
id: get('payload.id', action),
|
||||
}),
|
||||
|
@ -104,6 +107,9 @@ export const epicPersistPinnedEvent = (
|
|||
action$.pipe(
|
||||
withLatestFrom(timeline$),
|
||||
filter(([checkAction, updatedTimeline]) => {
|
||||
if (checkAction.type === addError.type) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
checkAction.type === endTimelineSaving.type &&
|
||||
updatedTimeline[get('payload.id', checkAction)].savedObjectId != null
|
||||
|
|
|
@ -28,6 +28,7 @@ export const initialTimelineState: TimelineState = {
|
|||
timelineId: null,
|
||||
newTimelineModel: null,
|
||||
},
|
||||
showCallOutUnauthorizedMsg: false,
|
||||
};
|
||||
|
||||
interface AddTimelineHistoryParams {
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
removeColumn,
|
||||
removeProvider,
|
||||
setKqlFilterQueryDraft,
|
||||
showCallOutUnauthorizedMsg,
|
||||
showTimeline,
|
||||
startTimelineSaving,
|
||||
unPinEvent,
|
||||
|
@ -97,6 +98,7 @@ export interface AutoSavedWarningMsg {
|
|||
export interface TimelineState {
|
||||
timelineById: TimelineById;
|
||||
autoSavedWarningMsg: AutoSavedWarningMsg;
|
||||
showCallOutUnauthorizedMsg: boolean;
|
||||
}
|
||||
|
||||
const EMPTY_TIMELINE_BY_ID: TimelineById = {}; // stable reference
|
||||
|
@ -107,6 +109,7 @@ export const initialTimelineState: TimelineState = {
|
|||
timelineId: null,
|
||||
newTimelineModel: null,
|
||||
},
|
||||
showCallOutUnauthorizedMsg: false,
|
||||
};
|
||||
|
||||
/** The reducer for all timeline actions */
|
||||
|
@ -387,4 +390,8 @@ export const timelineReducer = reducerWithInitialState(initialTimelineState)
|
|||
newTimelineModel,
|
||||
},
|
||||
}))
|
||||
.case(showCallOutUnauthorizedMsg, state => ({
|
||||
...state,
|
||||
showCallOutUnauthorizedMsg: true,
|
||||
}))
|
||||
.build();
|
||||
|
|
|
@ -16,6 +16,9 @@ const selectTimelineById = (state: State): TimelineById => state.timeline.timeli
|
|||
|
||||
const selectAutoSaveMsg = (state: State): AutoSavedWarningMsg => state.timeline.autoSavedWarningMsg;
|
||||
|
||||
const selectCallOutUnauthorizedMsg = (state: State): boolean =>
|
||||
state.timeline.showCallOutUnauthorizedMsg;
|
||||
|
||||
export const selectTimeline = (state: State, timelineId: string): TimelineModel =>
|
||||
state.timeline.timelineById[timelineId];
|
||||
|
||||
|
@ -29,6 +32,12 @@ export const timelineByIdSelector = createSelector(
|
|||
timelineById => timelineById
|
||||
);
|
||||
|
||||
export const getShowCallOutUnauthorizedMsg = () =>
|
||||
createSelector(
|
||||
selectCallOutUnauthorizedMsg,
|
||||
showCallOutUnauthorizedMsg => showCallOutUnauthorizedMsg
|
||||
);
|
||||
|
||||
export const getTimelineByIdSelector = () =>
|
||||
createSelector(
|
||||
selectTimeline,
|
||||
|
|
|
@ -45,11 +45,7 @@ export const eventsSchema = gql`
|
|||
}
|
||||
|
||||
type DetailItem {
|
||||
category: String!
|
||||
description: String
|
||||
example: String
|
||||
field: String!
|
||||
type: String!
|
||||
values: ToStringArray
|
||||
originalValue: EsValue
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ export const pinnedEventSchema = gql`
|
|||
#########################
|
||||
|
||||
type PinnedEvent {
|
||||
code: Float
|
||||
message: String
|
||||
pinnedEventId: ID!
|
||||
eventId: ID
|
||||
timelineId: ID
|
||||
|
|
|
@ -201,6 +201,8 @@ export const timelineSchema = gql`
|
|||
}
|
||||
|
||||
type ResponseFavoriteTimeline {
|
||||
code: Float
|
||||
message: String
|
||||
savedObjectId: String!
|
||||
version: String!
|
||||
favorite: [FavoriteTimelineResult!]
|
||||
|
|
|
@ -108,6 +108,10 @@ export interface ResponseNotes {
|
|||
}
|
||||
|
||||
export interface PinnedEvent {
|
||||
code?: number | null;
|
||||
|
||||
message?: string | null;
|
||||
|
||||
pinnedEventId: string;
|
||||
|
||||
eventId?: string | null;
|
||||
|
@ -861,16 +865,8 @@ export interface TimelineDetailsData {
|
|||
}
|
||||
|
||||
export interface DetailItem {
|
||||
category: string;
|
||||
|
||||
description?: string | null;
|
||||
|
||||
example?: string | null;
|
||||
|
||||
field: string;
|
||||
|
||||
type: string;
|
||||
|
||||
values?: ToStringArray | null;
|
||||
|
||||
originalValue?: EsValue | null;
|
||||
|
@ -1367,6 +1363,8 @@ export interface QueryMatchResult {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
}
|
||||
|
||||
export interface DateRangePickerResult {
|
||||
|
@ -1449,6 +1447,10 @@ export interface ResponseTimeline {
|
|||
}
|
||||
|
||||
export interface ResponseFavoriteTimeline {
|
||||
code?: number | null;
|
||||
|
||||
message?: string | null;
|
||||
|
||||
savedObjectId: string;
|
||||
|
||||
version: string;
|
||||
|
@ -1654,6 +1656,8 @@ export interface QueryMatchInput {
|
|||
value?: string | null;
|
||||
|
||||
displayValue?: string | null;
|
||||
|
||||
operator?: string | null;
|
||||
}
|
||||
|
||||
export interface SerializedFilterQueryInput {
|
||||
|
@ -2316,6 +2320,10 @@ export namespace ResponseNotesResolvers {
|
|||
|
||||
export namespace PinnedEventResolvers {
|
||||
export interface Resolvers<Context = SiemContext, TypeParent = PinnedEvent> {
|
||||
code?: CodeResolver<number | null, TypeParent, Context>;
|
||||
|
||||
message?: MessageResolver<string | null, TypeParent, Context>;
|
||||
|
||||
pinnedEventId?: PinnedEventIdResolver<string, TypeParent, Context>;
|
||||
|
||||
eventId?: EventIdResolver<string | null, TypeParent, Context>;
|
||||
|
@ -2335,6 +2343,16 @@ export namespace PinnedEventResolvers {
|
|||
version?: VersionResolver<string | null, TypeParent, Context>;
|
||||
}
|
||||
|
||||
export type CodeResolver<
|
||||
R = number | null,
|
||||
Parent = PinnedEvent,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type MessageResolver<
|
||||
R = string | null,
|
||||
Parent = PinnedEvent,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type PinnedEventIdResolver<
|
||||
R = string,
|
||||
Parent = PinnedEvent,
|
||||
|
@ -5084,46 +5102,18 @@ export namespace TimelineDetailsDataResolvers {
|
|||
|
||||
export namespace DetailItemResolvers {
|
||||
export interface Resolvers<Context = SiemContext, TypeParent = DetailItem> {
|
||||
category?: CategoryResolver<string, TypeParent, Context>;
|
||||
|
||||
description?: DescriptionResolver<string | null, TypeParent, Context>;
|
||||
|
||||
example?: ExampleResolver<string | null, TypeParent, Context>;
|
||||
|
||||
field?: FieldResolver<string, TypeParent, Context>;
|
||||
|
||||
type?: TypeResolver<string, TypeParent, Context>;
|
||||
|
||||
values?: ValuesResolver<ToStringArray | null, TypeParent, Context>;
|
||||
|
||||
originalValue?: OriginalValueResolver<EsValue | null, TypeParent, Context>;
|
||||
}
|
||||
|
||||
export type CategoryResolver<R = string, Parent = DetailItem, Context = SiemContext> = Resolver<
|
||||
R,
|
||||
Parent,
|
||||
Context
|
||||
>;
|
||||
export type DescriptionResolver<
|
||||
R = string | null,
|
||||
Parent = DetailItem,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type ExampleResolver<
|
||||
R = string | null,
|
||||
Parent = DetailItem,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type FieldResolver<R = string, Parent = DetailItem, Context = SiemContext> = Resolver<
|
||||
R,
|
||||
Parent,
|
||||
Context
|
||||
>;
|
||||
export type TypeResolver<R = string, Parent = DetailItem, Context = SiemContext> = Resolver<
|
||||
R,
|
||||
Parent,
|
||||
Context
|
||||
>;
|
||||
export type ValuesResolver<
|
||||
R = ToStringArray | null,
|
||||
Parent = DetailItem,
|
||||
|
@ -6767,6 +6757,8 @@ export namespace QueryMatchResultResolvers {
|
|||
value?: ValueResolver<string | null, TypeParent, Context>;
|
||||
|
||||
displayValue?: DisplayValueResolver<string | null, TypeParent, Context>;
|
||||
|
||||
operator?: OperatorResolver<string | null, TypeParent, Context>;
|
||||
}
|
||||
|
||||
export type FieldResolver<
|
||||
|
@ -6789,6 +6781,11 @@ export namespace QueryMatchResultResolvers {
|
|||
Parent = QueryMatchResult,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type OperatorResolver<
|
||||
R = string | null,
|
||||
Parent = QueryMatchResult,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
}
|
||||
|
||||
export namespace DateRangePickerResultResolvers {
|
||||
|
@ -7107,6 +7104,10 @@ export namespace ResponseTimelineResolvers {
|
|||
|
||||
export namespace ResponseFavoriteTimelineResolvers {
|
||||
export interface Resolvers<Context = SiemContext, TypeParent = ResponseFavoriteTimeline> {
|
||||
code?: CodeResolver<number | null, TypeParent, Context>;
|
||||
|
||||
message?: MessageResolver<string | null, TypeParent, Context>;
|
||||
|
||||
savedObjectId?: SavedObjectIdResolver<string, TypeParent, Context>;
|
||||
|
||||
version?: VersionResolver<string, TypeParent, Context>;
|
||||
|
@ -7114,6 +7115,16 @@ export namespace ResponseFavoriteTimelineResolvers {
|
|||
favorite?: FavoriteResolver<FavoriteTimelineResult[] | null, TypeParent, Context>;
|
||||
}
|
||||
|
||||
export type CodeResolver<
|
||||
R = number | null,
|
||||
Parent = ResponseFavoriteTimeline,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type MessageResolver<
|
||||
R = string | null,
|
||||
Parent = ResponseFavoriteTimeline,
|
||||
Context = SiemContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type SavedObjectIdResolver<
|
||||
R = string,
|
||||
Parent = ResponseFavoriteTimeline,
|
||||
|
|
|
@ -28,17 +28,11 @@ import {
|
|||
TimelineDetailsData,
|
||||
TimelineEdges,
|
||||
} from '../../graphql/types';
|
||||
import { getDocumentation, getIndexAlias, hasDocumentation } from '../../utils/beat_schema';
|
||||
import { baseCategoryFields } from '../../utils/beat_schema/8.0.0';
|
||||
import { reduceFields } from '../../utils/build_query/reduce_fields';
|
||||
import { mergeFieldsWithHit } from '../../utils/build_query';
|
||||
import { eventFieldsMap } from '../ecs_fields';
|
||||
import {
|
||||
FrameworkAdapter,
|
||||
FrameworkRequest,
|
||||
MappingProperties,
|
||||
RequestOptions,
|
||||
} from '../framework';
|
||||
import { FrameworkAdapter, FrameworkRequest, RequestOptions } from '../framework';
|
||||
import { TermAggregation } from '../types';
|
||||
|
||||
import { buildDetailsQuery, buildQuery } from './query.dsl';
|
||||
|
@ -114,32 +108,18 @@ export class ElasticsearchEventsAdapter implements EventsAdapter {
|
|||
request: FrameworkRequest,
|
||||
options: RequestDetailsOptions
|
||||
): Promise<TimelineDetailsData> {
|
||||
const [mapResponse, searchResponse] = await Promise.all([
|
||||
this.framework.callWithRequest(request, 'indices.getMapping', {
|
||||
allowNoIndices: true,
|
||||
ignoreUnavailable: true,
|
||||
index: options.indexName,
|
||||
}),
|
||||
this.framework.callWithRequest<EventHit, TermAggregation>(
|
||||
request,
|
||||
'search',
|
||||
buildDetailsQuery(options.indexName, options.eventId)
|
||||
),
|
||||
]);
|
||||
const searchResponse = await this.framework.callWithRequest<EventHit, TermAggregation>(
|
||||
request,
|
||||
'search',
|
||||
buildDetailsQuery(options.indexName, options.eventId)
|
||||
);
|
||||
|
||||
const sourceData = getOr({}, 'hits.hits.0._source', searchResponse);
|
||||
const hitsData = getOr({}, 'hits.hits.0', searchResponse);
|
||||
delete hitsData._source;
|
||||
|
||||
return {
|
||||
data: getSchemaFromData(
|
||||
{
|
||||
...addBasicElasticSearchProperties(),
|
||||
...getOr({}, [options.indexName, 'mappings', 'properties'], mapResponse),
|
||||
},
|
||||
getDataFromHits(merge(sourceData, hitsData)),
|
||||
getIndexAlias(options.defaultIndex, options.indexName)
|
||||
),
|
||||
data: getDataFromHits(merge(sourceData, hitsData)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -289,50 +269,3 @@ const getDataFromHits = (sources: EventSource, category?: string, path?: string)
|
|||
}
|
||||
return accumulator;
|
||||
}, []);
|
||||
|
||||
const getSchemaFromData = (
|
||||
properties: MappingProperties,
|
||||
data: DetailItem[],
|
||||
index: string,
|
||||
path?: string
|
||||
): DetailItem[] =>
|
||||
!isEmpty(properties)
|
||||
? Object.keys(properties).reduce<DetailItem[]>((accumulator, property) => {
|
||||
const item = get(property, properties);
|
||||
const field = path ? `${path}.${property}` : property;
|
||||
const dataFilterItem = data.filter(dataItem => dataItem.field === field);
|
||||
if (item.properties == null && dataFilterItem.length === 1) {
|
||||
const dataItem = dataFilterItem[0];
|
||||
const dataFromMapping = {
|
||||
type: get([property, 'type'], properties),
|
||||
};
|
||||
return [
|
||||
...accumulator,
|
||||
{
|
||||
...dataItem,
|
||||
...(hasDocumentation(index, field)
|
||||
? merge(getDocumentation(index, field), dataFromMapping)
|
||||
: dataFromMapping),
|
||||
},
|
||||
];
|
||||
} else if (item.properties != null) {
|
||||
return [...accumulator, ...getSchemaFromData(item.properties, data, index, field)];
|
||||
}
|
||||
return accumulator;
|
||||
}, [])
|
||||
: data;
|
||||
|
||||
const addBasicElasticSearchProperties = () => ({
|
||||
_id: {
|
||||
type: 'keyword',
|
||||
},
|
||||
_index: {
|
||||
type: 'keyword',
|
||||
},
|
||||
_type: {
|
||||
type: 'keyword',
|
||||
},
|
||||
_score: {
|
||||
type: 'long',
|
||||
},
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,11 +8,18 @@ import { failure } from 'io-ts/lib/PathReporter';
|
|||
import { RequestAuth } from 'hapi';
|
||||
import { Legacy } from 'kibana';
|
||||
import { getOr } from 'lodash/fp';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import { FindOptions } from 'src/legacy/server/saved_objects/service';
|
||||
|
||||
import { Pick3 } from '../../../common/utility_types';
|
||||
import { PageInfoNote, ResponseNote, ResponseNotes, SortNote } from '../../graphql/types';
|
||||
import {
|
||||
PageInfoNote,
|
||||
ResponseNote,
|
||||
ResponseNotes,
|
||||
SortNote,
|
||||
NoteResult,
|
||||
} from '../../graphql/types';
|
||||
import { FrameworkRequest, internalFrameworkRequest } from '../framework';
|
||||
import { SavedNote, NoteSavedObjectRuntimeType, NoteSavedObject } from './types';
|
||||
import { noteSavedObjectType } from './saved_object_mappings';
|
||||
|
@ -104,21 +111,24 @@ export class Note {
|
|||
version: string | null,
|
||||
note: SavedNote
|
||||
): Promise<ResponseNote> {
|
||||
let timelineVersionSavedObject = null;
|
||||
try {
|
||||
if (note.timelineId == null) {
|
||||
const timelineResult = convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(null, {}, request[internalFrameworkRequest].auth || null)
|
||||
)
|
||||
);
|
||||
note.timelineId = timelineResult.savedObjectId;
|
||||
timelineVersionSavedObject = timelineResult.version;
|
||||
}
|
||||
if (noteId == null) {
|
||||
const timelineVersionSavedObject =
|
||||
note.timelineId == null
|
||||
? await (async () => {
|
||||
const timelineResult = convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(null, {}, request[internalFrameworkRequest].auth || null)
|
||||
)
|
||||
);
|
||||
note.timelineId = timelineResult.savedObjectId;
|
||||
return timelineResult.version;
|
||||
})()
|
||||
: null;
|
||||
|
||||
// Create new note
|
||||
return {
|
||||
code: 200,
|
||||
|
@ -134,6 +144,7 @@ export class Note {
|
|||
),
|
||||
};
|
||||
}
|
||||
|
||||
// Update new note
|
||||
return {
|
||||
code: 200,
|
||||
|
@ -152,6 +163,20 @@ export class Note {
|
|||
),
|
||||
};
|
||||
} catch (err) {
|
||||
if (getOr(null, 'output.statusCode', err) === 403) {
|
||||
const noteToReturn: NoteResult = {
|
||||
...note,
|
||||
noteId: uuid.v1(),
|
||||
version: '',
|
||||
timelineId: '',
|
||||
timelineVersion: '',
|
||||
};
|
||||
return {
|
||||
code: 403,
|
||||
message: err.message,
|
||||
note: noteToReturn,
|
||||
};
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
PinnedEventSavedObjectRuntimeType,
|
||||
SavedPinnedEvent,
|
||||
} from './types';
|
||||
import { PageInfoNote, SortNote } from '../../graphql/types';
|
||||
import { PageInfoNote, SortNote, PinnedEvent as PinnedEventResponse } from '../../graphql/types';
|
||||
import { pinnedEventSavedObjectType, timelineSavedObjectType } from '../../saved_objects';
|
||||
import { pickSavedTimeline } from '../timeline/pick_saved_timeline';
|
||||
import { convertSavedObjectToSavedTimeline } from '../timeline/convert_saved_object_to_savedtimeline';
|
||||
|
@ -96,52 +96,69 @@ export class PinnedEvent {
|
|||
pinnedEventId: string | null,
|
||||
eventId: string,
|
||||
timelineId: string | null
|
||||
): Promise<PinnedEventSavedObject | null> {
|
||||
let timelineVersionSavedObject = null;
|
||||
): Promise<PinnedEventResponse | null> {
|
||||
try {
|
||||
if (timelineId == null) {
|
||||
const timelineResult = convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(null, {}, request[internalFrameworkRequest].auth || null)
|
||||
)
|
||||
);
|
||||
timelineId = timelineResult.savedObjectId;
|
||||
timelineVersionSavedObject = timelineResult.version;
|
||||
}
|
||||
if (pinnedEventId == null) {
|
||||
const allPinnedEventId = await this.getAllPinnedEventsByTimelineId(request, timelineId);
|
||||
const isPinnedAlreadyExisting = allPinnedEventId.filter(
|
||||
pinnedEvent => pinnedEvent.eventId === eventId
|
||||
);
|
||||
if (isPinnedAlreadyExisting.length === 0) {
|
||||
const savedPinnedEvent: SavedPinnedEvent = {
|
||||
eventId,
|
||||
timelineId,
|
||||
};
|
||||
// create Pinned Event on Timeline
|
||||
return convertSavedObjectToSavedPinnedEvent(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
pinnedEventSavedObjectType,
|
||||
pickSavedPinnedEvent(
|
||||
pinnedEventId,
|
||||
savedPinnedEvent,
|
||||
request[internalFrameworkRequest].auth || null
|
||||
)
|
||||
),
|
||||
timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined
|
||||
const timelineVersionSavedObject =
|
||||
timelineId == null
|
||||
? await (async () => {
|
||||
const timelineResult = convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(null, {}, request[internalFrameworkRequest].auth || null)
|
||||
)
|
||||
);
|
||||
timelineId = timelineResult.savedObjectId;
|
||||
return timelineResult.version;
|
||||
})()
|
||||
: null;
|
||||
|
||||
if (timelineId != null) {
|
||||
const allPinnedEventId = await this.getAllPinnedEventsByTimelineId(request, timelineId);
|
||||
const isPinnedAlreadyExisting = allPinnedEventId.filter(
|
||||
pinnedEvent => pinnedEvent.eventId === eventId
|
||||
);
|
||||
if (isPinnedAlreadyExisting.length === 0) {
|
||||
const savedPinnedEvent: SavedPinnedEvent = {
|
||||
eventId,
|
||||
timelineId,
|
||||
};
|
||||
// create Pinned Event on Timeline
|
||||
return convertSavedObjectToSavedPinnedEvent(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
pinnedEventSavedObjectType,
|
||||
pickSavedPinnedEvent(
|
||||
pinnedEventId,
|
||||
savedPinnedEvent,
|
||||
request[internalFrameworkRequest].auth || null
|
||||
)
|
||||
),
|
||||
timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined
|
||||
);
|
||||
}
|
||||
return isPinnedAlreadyExisting[0];
|
||||
}
|
||||
return isPinnedAlreadyExisting[0];
|
||||
throw new Error('You can NOT pinned event without a timelineID');
|
||||
}
|
||||
// Delete Pinned Event on Timeline
|
||||
await this.deletePinnedEventOnTimeline(request, [pinnedEventId]);
|
||||
return null;
|
||||
} catch (err) {
|
||||
if (getOr(null, 'output.statusCode', err) === 403) {
|
||||
return pinnedEventId != null
|
||||
? {
|
||||
code: 403,
|
||||
message: err.message,
|
||||
pinnedEventId: eventId,
|
||||
timelineId: '',
|
||||
timelineVersion: '',
|
||||
}
|
||||
: null;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
PageInfoTimeline,
|
||||
SortTimeline,
|
||||
ResponseFavoriteTimeline,
|
||||
TimelineResult,
|
||||
} from '../../graphql/types';
|
||||
import { FrameworkRequest, internalFrameworkRequest } from '../framework';
|
||||
import { NoteSavedObject } from '../note/types';
|
||||
|
@ -77,54 +78,68 @@ export class Timeline {
|
|||
request: FrameworkRequest,
|
||||
timelineId: string | null
|
||||
): Promise<ResponseFavoriteTimeline> {
|
||||
let timeline: SavedTimeline = {};
|
||||
if (timelineId != null) {
|
||||
const {
|
||||
eventIdToNoteIds,
|
||||
notes,
|
||||
noteIds,
|
||||
pinnedEventIds,
|
||||
pinnedEventsSaveObject,
|
||||
savedObjectId,
|
||||
version,
|
||||
...savedTimeline
|
||||
} = await this.getBasicSavedTimeline(request, timelineId);
|
||||
timelineId = savedObjectId;
|
||||
timeline = savedTimeline;
|
||||
}
|
||||
const userName = getOr(null, 'credentials.username', request[internalFrameworkRequest].auth);
|
||||
const fullName = getOr(null, 'credentials.fullname', request[internalFrameworkRequest].auth);
|
||||
const userFavoriteTimeline = {
|
||||
keySearch: userName != null ? convertStringToBase64(userName) : null,
|
||||
favoriteDate: new Date().valueOf(),
|
||||
fullName,
|
||||
userName,
|
||||
};
|
||||
if (timeline.favorite != null) {
|
||||
const alreadyExistsTimelineFavoriteByUser = timeline.favorite.findIndex(
|
||||
user => user.userName === userName
|
||||
);
|
||||
try {
|
||||
let timeline: SavedTimeline = {};
|
||||
if (timelineId != null) {
|
||||
const {
|
||||
eventIdToNoteIds,
|
||||
notes,
|
||||
noteIds,
|
||||
pinnedEventIds,
|
||||
pinnedEventsSaveObject,
|
||||
savedObjectId,
|
||||
version,
|
||||
...savedTimeline
|
||||
} = await this.getBasicSavedTimeline(request, timelineId);
|
||||
timelineId = savedObjectId;
|
||||
timeline = savedTimeline;
|
||||
}
|
||||
|
||||
timeline.favorite =
|
||||
alreadyExistsTimelineFavoriteByUser > -1
|
||||
? [
|
||||
...timeline.favorite.slice(0, alreadyExistsTimelineFavoriteByUser),
|
||||
...timeline.favorite.slice(alreadyExistsTimelineFavoriteByUser + 1),
|
||||
]
|
||||
: [...timeline.favorite, userFavoriteTimeline];
|
||||
} else if (timeline.favorite == null) {
|
||||
timeline.favorite = [userFavoriteTimeline];
|
||||
const userFavoriteTimeline = {
|
||||
keySearch: userName != null ? convertStringToBase64(userName) : null,
|
||||
favoriteDate: new Date().valueOf(),
|
||||
fullName,
|
||||
userName,
|
||||
};
|
||||
if (timeline.favorite != null) {
|
||||
const alreadyExistsTimelineFavoriteByUser = timeline.favorite.findIndex(
|
||||
user => user.userName === userName
|
||||
);
|
||||
|
||||
timeline.favorite =
|
||||
alreadyExistsTimelineFavoriteByUser > -1
|
||||
? [
|
||||
...timeline.favorite.slice(0, alreadyExistsTimelineFavoriteByUser),
|
||||
...timeline.favorite.slice(alreadyExistsTimelineFavoriteByUser + 1),
|
||||
]
|
||||
: [...timeline.favorite, userFavoriteTimeline];
|
||||
} else if (timeline.favorite == null) {
|
||||
timeline.favorite = [userFavoriteTimeline];
|
||||
}
|
||||
|
||||
const persistResponse = await this.persistTimeline(request, timelineId, null, timeline);
|
||||
return {
|
||||
savedObjectId: persistResponse.timeline.savedObjectId,
|
||||
version: persistResponse.timeline.version,
|
||||
favorite:
|
||||
persistResponse.timeline.favorite != null
|
||||
? persistResponse.timeline.favorite.filter(fav => fav.userName === userName)
|
||||
: [],
|
||||
};
|
||||
} catch (err) {
|
||||
if (getOr(null, 'output.statusCode', err) === 403) {
|
||||
return {
|
||||
savedObjectId: '',
|
||||
version: '',
|
||||
favorite: [],
|
||||
code: 403,
|
||||
message: err.message,
|
||||
};
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
const persistResponse = await this.persistTimeline(request, timelineId, null, timeline);
|
||||
return {
|
||||
savedObjectId: persistResponse.timeline.savedObjectId,
|
||||
version: persistResponse.timeline.version,
|
||||
favorite:
|
||||
persistResponse.timeline.favorite != null
|
||||
? persistResponse.timeline.favorite.filter(fav => fav.userName === userName)
|
||||
: [],
|
||||
};
|
||||
}
|
||||
|
||||
public async persistTimeline(
|
||||
|
@ -133,27 +148,26 @@ export class Timeline {
|
|||
version: string | null,
|
||||
timeline: SavedTimeline
|
||||
): Promise<ResponseTimeline> {
|
||||
if (timelineId == null) {
|
||||
// Create new timeline
|
||||
return {
|
||||
code: 200,
|
||||
message: 'success',
|
||||
timeline: convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(
|
||||
timelineId,
|
||||
timeline,
|
||||
request[internalFrameworkRequest].auth || null
|
||||
)
|
||||
)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
if (timelineId == null) {
|
||||
// Create new timeline
|
||||
return {
|
||||
code: 200,
|
||||
message: 'success',
|
||||
timeline: convertSavedObjectToSavedTimeline(
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
.create(
|
||||
timelineSavedObjectType,
|
||||
pickSavedTimeline(
|
||||
timelineId,
|
||||
timeline,
|
||||
request[internalFrameworkRequest].auth || null
|
||||
)
|
||||
)
|
||||
),
|
||||
};
|
||||
}
|
||||
// Update Timeline
|
||||
await this.libs.savedObjects
|
||||
.getScopedSavedObjectsClient(request[internalFrameworkRequest])
|
||||
|
@ -171,12 +185,26 @@ export class Timeline {
|
|||
timeline: await this.getSavedTimeline(request, timelineId),
|
||||
};
|
||||
} catch (err) {
|
||||
if (this.libs.savedObjects.SavedObjectsClient.errors.isConflictError(err)) {
|
||||
if (
|
||||
timelineId != null &&
|
||||
this.libs.savedObjects.SavedObjectsClient.errors.isConflictError(err)
|
||||
) {
|
||||
return {
|
||||
code: 409,
|
||||
message: err.message,
|
||||
timeline: await this.getSavedTimeline(request, timelineId),
|
||||
};
|
||||
} else if (getOr(null, 'output.statusCode', err) === 403) {
|
||||
const timelineToReturn: TimelineResult = {
|
||||
...timeline,
|
||||
savedObjectId: '',
|
||||
version: '',
|
||||
};
|
||||
return {
|
||||
code: 403,
|
||||
message: err.message,
|
||||
timeline: timelineToReturn,
|
||||
};
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,7 @@ import { DetailItem, GetTimelineDetailsQuery } from '../../../../plugins/siem/pu
|
|||
import { KbnTestProvider } from './types';
|
||||
|
||||
type DetailsData = Array<
|
||||
Pick<
|
||||
DetailItem,
|
||||
'category' | 'description' | 'example' | 'field' | 'type' | 'values' | 'originalValue'
|
||||
> & {
|
||||
Pick<DetailItem, 'field' | 'values' | 'originalValue'> & {
|
||||
__typename: string;
|
||||
}
|
||||
>;
|
||||
|
@ -25,618 +22,277 @@ const INDEX_NAME = 'filebeat-7.0.0-iot-2019.06';
|
|||
const ID = 'QRhG1WgBqd-n62SwZYDT';
|
||||
const EXPECTED_DATA: DetailItem[] = [
|
||||
{
|
||||
category: '_id',
|
||||
description: 'Each document has an _id that uniquely identifies it',
|
||||
example: 'Y-6TfmcB0WOhS6qyMv3s',
|
||||
field: '_id',
|
||||
type: 'keyword',
|
||||
originalValue: 'QRhG1WgBqd-n62SwZYDT',
|
||||
values: ['QRhG1WgBqd-n62SwZYDT'],
|
||||
},
|
||||
{
|
||||
category: '_index',
|
||||
description:
|
||||
'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.',
|
||||
example: 'auditbeat-8.0.0-2019.02.19-000001',
|
||||
field: '_index',
|
||||
type: 'keyword',
|
||||
originalValue: 'filebeat-7.0.0-iot-2019.06',
|
||||
values: ['filebeat-7.0.0-iot-2019.06'],
|
||||
},
|
||||
{
|
||||
category: '_type',
|
||||
description: null,
|
||||
example: null,
|
||||
field: '_type',
|
||||
type: 'keyword',
|
||||
originalValue: '_doc',
|
||||
values: ['_doc'],
|
||||
},
|
||||
{
|
||||
category: '_score',
|
||||
description: null,
|
||||
example: null,
|
||||
field: '_score',
|
||||
type: 'long',
|
||||
originalValue: 1,
|
||||
values: ['1'],
|
||||
},
|
||||
{
|
||||
category: '@timestamp',
|
||||
description:
|
||||
'Date/time when the event originated. For log events this is the date/time when the event was generated, and not when it was read. Required field for all events.',
|
||||
example: '2016-05-23T08:05:34.853Z',
|
||||
field: '@timestamp',
|
||||
type: 'date',
|
||||
originalValue: '2019-02-10T02:39:44.107Z',
|
||||
values: ['2019-02-10T02:39:44.107Z'],
|
||||
originalValue: '2019-02-10T02:39:44.107Z',
|
||||
},
|
||||
{ field: '@version', values: ['1'], originalValue: '1' },
|
||||
{
|
||||
category: '@version',
|
||||
description: null,
|
||||
example: null,
|
||||
field: '@version',
|
||||
type: 'keyword',
|
||||
originalValue: '1',
|
||||
values: ['1'],
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Ephemeral identifier of this agent (if one exists). This id normally changes across restarts, but `agent.id` does not.',
|
||||
example: '8a4f500f',
|
||||
field: 'agent.ephemeral_id',
|
||||
type: 'keyword',
|
||||
originalValue: '909cd6a1-527d-41a5-9585-a7fb5386f851',
|
||||
values: ['909cd6a1-527d-41a5-9585-a7fb5386f851'],
|
||||
originalValue: '909cd6a1-527d-41a5-9585-a7fb5386f851',
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'agent.hostname',
|
||||
type: 'keyword',
|
||||
originalValue: 'raspberrypi',
|
||||
values: ['raspberrypi'],
|
||||
originalValue: 'raspberrypi',
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Unique identifier of this agent (if one exists). Example: For Beats this would be beat.id.',
|
||||
example: '8a4f500d',
|
||||
field: 'agent.id',
|
||||
type: 'keyword',
|
||||
originalValue: '4d3ea604-27e5-4ec7-ab64-44f82285d776',
|
||||
values: ['4d3ea604-27e5-4ec7-ab64-44f82285d776'],
|
||||
originalValue: '4d3ea604-27e5-4ec7-ab64-44f82285d776',
|
||||
},
|
||||
{
|
||||
category: 'agent',
|
||||
description:
|
||||
'Type of the agent. The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.',
|
||||
example: 'filebeat',
|
||||
field: 'agent.type',
|
||||
type: 'keyword',
|
||||
originalValue: 'filebeat',
|
||||
values: ['filebeat'],
|
||||
originalValue: 'filebeat',
|
||||
},
|
||||
{ field: 'agent.version', values: ['7.0.0'], originalValue: '7.0.0' },
|
||||
{
|
||||
category: 'agent',
|
||||
description: 'Version of the agent.',
|
||||
example: '6.0.0-rc2',
|
||||
field: 'agent.version',
|
||||
type: 'keyword',
|
||||
originalValue: '7.0.0',
|
||||
values: ['7.0.0'],
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'Destination domain.',
|
||||
example: null,
|
||||
field: 'destination.domain',
|
||||
type: 'keyword',
|
||||
originalValue: 's3-iad-2.cf.dash.row.aiv-cdn.net',
|
||||
values: ['s3-iad-2.cf.dash.row.aiv-cdn.net'],
|
||||
originalValue: 's3-iad-2.cf.dash.row.aiv-cdn.net',
|
||||
},
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'IP address of the destination. Can be one or multiple IPv4 or IPv6 addresses.',
|
||||
example: null,
|
||||
field: 'destination.ip',
|
||||
type: 'ip',
|
||||
originalValue: '10.100.7.196',
|
||||
values: ['10.100.7.196'],
|
||||
originalValue: '10.100.7.196',
|
||||
},
|
||||
{ field: 'destination.port', values: ['40684'], originalValue: 40684 },
|
||||
{
|
||||
category: 'destination',
|
||||
description: 'Port of the destination.',
|
||||
example: null,
|
||||
field: 'destination.port',
|
||||
type: 'long',
|
||||
originalValue: 40684,
|
||||
values: ['40684'],
|
||||
},
|
||||
{
|
||||
category: 'ecs',
|
||||
description:
|
||||
'ECS version this event conforms to. `ecs.version` is a required field and must exist in all events. When querying across multiple indices -- which may conform to slightly different ECS versions -- this field lets integrations adjust to the schema version of the events. The current version is 1.0.0-beta2 .',
|
||||
example: '1.0.0-beta2',
|
||||
field: 'ecs.version',
|
||||
type: 'keyword',
|
||||
originalValue: '1.0.0-beta2',
|
||||
values: ['1.0.0-beta2'],
|
||||
originalValue: '1.0.0-beta2',
|
||||
},
|
||||
{
|
||||
category: 'event',
|
||||
description:
|
||||
'Name of the dataset. The concept of a `dataset` (fileset / metricset) is used in Beats as a subset of modules. It contains the information which is currently stored in metricset.name and metricset.module or fileset.name.',
|
||||
example: 'stats',
|
||||
field: 'event.dataset',
|
||||
type: 'keyword',
|
||||
originalValue: 'suricata.eve',
|
||||
values: ['suricata.eve'],
|
||||
originalValue: 'suricata.eve',
|
||||
},
|
||||
{
|
||||
category: 'event',
|
||||
description:
|
||||
'event.end contains the date when the event ended or when the activity was last observed.',
|
||||
example: null,
|
||||
field: 'event.end',
|
||||
type: 'date',
|
||||
originalValue: '2019-02-10T02:39:44.107Z',
|
||||
values: ['2019-02-10T02:39:44.107Z'],
|
||||
originalValue: '2019-02-10T02:39:44.107Z',
|
||||
},
|
||||
{ field: 'event.kind', values: ['event'], originalValue: 'event' },
|
||||
{
|
||||
category: 'event',
|
||||
description:
|
||||
'The kind of the event. This gives information about what type of information the event contains, without being specific to the contents of the event. Examples are `event`, `state`, `alarm`. Warning: In future versions of ECS, we plan to provide a list of acceptable values for this field, please use with caution.',
|
||||
example: 'state',
|
||||
field: 'event.kind',
|
||||
type: 'keyword',
|
||||
originalValue: 'event',
|
||||
values: ['event'],
|
||||
},
|
||||
{
|
||||
category: 'event',
|
||||
description:
|
||||
'Name of the module this data is coming from. This information is coming from the modules used in Beats or Logstash.',
|
||||
example: 'mysql',
|
||||
field: 'event.module',
|
||||
type: 'keyword',
|
||||
originalValue: 'suricata',
|
||||
values: ['suricata'],
|
||||
originalValue: 'suricata',
|
||||
},
|
||||
{
|
||||
category: 'event',
|
||||
description: 'Reserved for future usage. Please avoid using this field for user data.',
|
||||
example: null,
|
||||
field: 'event.type',
|
||||
type: 'keyword',
|
||||
originalValue: 'fileinfo',
|
||||
values: ['fileinfo'],
|
||||
originalValue: 'fileinfo',
|
||||
},
|
||||
{
|
||||
category: 'file',
|
||||
description: 'Path to the file.',
|
||||
example: null,
|
||||
field: 'file.path',
|
||||
type: 'keyword',
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
values: [
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
],
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
},
|
||||
{ field: 'file.size', values: ['48277'], originalValue: 48277 },
|
||||
{ field: 'fileset.name', values: ['eve'], originalValue: 'eve' },
|
||||
{ field: 'flow.locality', values: ['public'], originalValue: 'public' },
|
||||
{
|
||||
category: 'file',
|
||||
description: 'File size in bytes (field is only added when `type` is `file`).',
|
||||
example: null,
|
||||
field: 'file.size',
|
||||
type: 'long',
|
||||
originalValue: 48277,
|
||||
values: ['48277'],
|
||||
},
|
||||
{
|
||||
category: 'fileset',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'fileset.name',
|
||||
type: 'keyword',
|
||||
originalValue: 'eve',
|
||||
values: ['eve'],
|
||||
},
|
||||
{
|
||||
category: 'flow',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'flow.locality',
|
||||
type: 'keyword',
|
||||
originalValue: 'public',
|
||||
values: ['public'],
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: 'Operating system architecture.',
|
||||
example: 'x86_64',
|
||||
field: 'host.architecture',
|
||||
type: 'keyword',
|
||||
originalValue: 'armv7l',
|
||||
values: ['armv7l'],
|
||||
originalValue: 'armv7l',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description:
|
||||
'Hostname of the host. It normally contains what the `hostname` command returns on the host machine.',
|
||||
example: null,
|
||||
field: 'host.hostname',
|
||||
type: 'keyword',
|
||||
originalValue: 'raspberrypi',
|
||||
values: ['raspberrypi'],
|
||||
originalValue: 'raspberrypi',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description:
|
||||
'Unique host id. As hostname is not always unique, use values that are meaningful in your environment. Example: The current usage of `beat.name`.',
|
||||
example: null,
|
||||
field: 'host.id',
|
||||
type: 'keyword',
|
||||
originalValue: 'b19a781f683541a7a25ee345133aa399',
|
||||
values: ['b19a781f683541a7a25ee345133aa399'],
|
||||
originalValue: 'b19a781f683541a7a25ee345133aa399',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description:
|
||||
'Name of the host. It can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.',
|
||||
example: null,
|
||||
field: 'host.name',
|
||||
type: 'keyword',
|
||||
originalValue: 'raspberrypi',
|
||||
values: ['raspberrypi'],
|
||||
originalValue: 'raspberrypi',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'host.os.codename',
|
||||
type: 'keyword',
|
||||
originalValue: 'stretch',
|
||||
values: ['stretch'],
|
||||
originalValue: 'stretch',
|
||||
},
|
||||
{ field: 'host.os.family', values: [''], originalValue: '' },
|
||||
{
|
||||
category: 'host',
|
||||
description: 'OS family (such as redhat, debian, freebsd, windows).',
|
||||
example: 'debian',
|
||||
field: 'host.os.family',
|
||||
type: 'keyword',
|
||||
originalValue: '',
|
||||
values: [''],
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: 'Operating system kernel version as a raw string.',
|
||||
example: '4.4.0-112-generic',
|
||||
field: 'host.os.kernel',
|
||||
type: 'keyword',
|
||||
originalValue: '4.14.50-v7+',
|
||||
values: ['4.14.50-v7+'],
|
||||
originalValue: '4.14.50-v7+',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: 'Operating system name, without the version.',
|
||||
example: 'Mac OS X',
|
||||
field: 'host.os.name',
|
||||
type: 'keyword',
|
||||
originalValue: 'Raspbian GNU/Linux',
|
||||
values: ['Raspbian GNU/Linux'],
|
||||
originalValue: 'Raspbian GNU/Linux',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: 'Operating system platform (such centos, ubuntu, windows).',
|
||||
example: 'darwin',
|
||||
field: 'host.os.platform',
|
||||
type: 'keyword',
|
||||
originalValue: 'raspbian',
|
||||
values: ['raspbian'],
|
||||
originalValue: 'raspbian',
|
||||
},
|
||||
{
|
||||
category: 'host',
|
||||
description: 'Operating system version as a raw string.',
|
||||
example: '10.14.1',
|
||||
field: 'host.os.version',
|
||||
type: 'keyword',
|
||||
originalValue: '9 (stretch)',
|
||||
values: ['9 (stretch)'],
|
||||
originalValue: '9 (stretch)',
|
||||
},
|
||||
{ field: 'http.request.method', values: ['get'], originalValue: 'get' },
|
||||
{
|
||||
category: 'http',
|
||||
description:
|
||||
'Http request method. The field value must be normalized to lowercase for querying. See "Lowercase Capitalization" in the "Implementing ECS" section.',
|
||||
example: 'get, post, put',
|
||||
field: 'http.request.method',
|
||||
type: 'keyword',
|
||||
originalValue: 'get',
|
||||
values: ['get'],
|
||||
},
|
||||
{
|
||||
category: 'http',
|
||||
description: 'Size in bytes of the response body.',
|
||||
example: '887',
|
||||
field: 'http.response.body.bytes',
|
||||
type: 'long',
|
||||
originalValue: 48277,
|
||||
values: ['48277'],
|
||||
originalValue: 48277,
|
||||
},
|
||||
{
|
||||
category: 'http',
|
||||
description: 'Http response status code.',
|
||||
example: '404',
|
||||
field: 'http.response.status_code',
|
||||
type: 'long',
|
||||
originalValue: 206,
|
||||
values: ['206'],
|
||||
originalValue: 206,
|
||||
},
|
||||
{ field: 'input.type', values: ['log'], originalValue: 'log' },
|
||||
{
|
||||
category: 'input',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'input.type',
|
||||
type: 'keyword',
|
||||
originalValue: 'log',
|
||||
values: ['log'],
|
||||
},
|
||||
{
|
||||
category: 'labels',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'labels.pipeline',
|
||||
type: 'keyword',
|
||||
originalValue: 'filebeat-7.0.0-suricata-eve-pipeline',
|
||||
values: ['filebeat-7.0.0-suricata-eve-pipeline'],
|
||||
originalValue: 'filebeat-7.0.0-suricata-eve-pipeline',
|
||||
},
|
||||
{
|
||||
category: 'log',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'log.file.path',
|
||||
type: 'keyword',
|
||||
originalValue: '/var/log/suricata/eve.json',
|
||||
values: ['/var/log/suricata/eve.json'],
|
||||
originalValue: '/var/log/suricata/eve.json',
|
||||
},
|
||||
{
|
||||
category: 'log',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'log.offset',
|
||||
type: 'long',
|
||||
originalValue: 1856288115,
|
||||
values: ['1856288115'],
|
||||
originalValue: 1856288115,
|
||||
},
|
||||
{ field: 'network.name', values: ['iot'], originalValue: 'iot' },
|
||||
{ field: 'network.protocol', values: ['http'], originalValue: 'http' },
|
||||
{ field: 'network.transport', values: ['tcp'], originalValue: 'tcp' },
|
||||
{
|
||||
category: 'network',
|
||||
description: 'Name given by operators to sections of their network.',
|
||||
example: 'Guest Wifi',
|
||||
field: 'network.name',
|
||||
type: 'keyword',
|
||||
originalValue: 'iot',
|
||||
values: ['iot'],
|
||||
},
|
||||
{
|
||||
category: 'network',
|
||||
description:
|
||||
'L7 Network protocol name. ex. http, lumberjack, transport protocol. The field value must be normalized to lowercase for querying. See "Lowercase Capitalization" in the "Implementing ECS" section.',
|
||||
example: 'http',
|
||||
field: 'network.protocol',
|
||||
type: 'keyword',
|
||||
originalValue: 'http',
|
||||
values: ['http'],
|
||||
},
|
||||
{
|
||||
category: 'network',
|
||||
description:
|
||||
'Same as network.iana_number, but instead using the Keyword name of the transport layer (udp, tcp, ipv6-icmp, etc.) The field value must be normalized to lowercase for querying. See "Lowercase Capitalization" in the "Implementing ECS" section.',
|
||||
example: 'tcp',
|
||||
field: 'network.transport',
|
||||
type: 'keyword',
|
||||
originalValue: 'tcp',
|
||||
values: ['tcp'],
|
||||
},
|
||||
{
|
||||
category: 'service',
|
||||
description:
|
||||
'The type of the service data is collected from. The type can be used to group and correlate logs and metrics from one service type. Example: If logs or metrics are collected from Elasticsearch, `service.type` would be `elasticsearch`.',
|
||||
example: 'elasticsearch',
|
||||
field: 'service.type',
|
||||
type: 'keyword',
|
||||
values: ['suricata'],
|
||||
originalValue: 'suricata',
|
||||
values: ['suricata'],
|
||||
},
|
||||
{ field: 'source.as.num', values: ['16509'], originalValue: 16509 },
|
||||
{
|
||||
category: 'source',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'source.as.num',
|
||||
type: 'long',
|
||||
originalValue: 16509,
|
||||
values: ['16509'],
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'source.as.org',
|
||||
type: 'keyword',
|
||||
originalValue: 'Amazon.com, Inc.',
|
||||
values: ['Amazon.com, Inc.'],
|
||||
originalValue: 'Amazon.com, Inc.',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Source domain.',
|
||||
example: null,
|
||||
field: 'source.domain',
|
||||
type: 'keyword',
|
||||
originalValue: 'server-54-239-219-210.jfk51.r.cloudfront.net',
|
||||
values: ['server-54-239-219-210.jfk51.r.cloudfront.net'],
|
||||
originalValue: 'server-54-239-219-210.jfk51.r.cloudfront.net',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'City name.',
|
||||
example: 'Montreal',
|
||||
field: 'source.geo.city_name',
|
||||
type: 'keyword',
|
||||
originalValue: 'Seattle',
|
||||
values: ['Seattle'],
|
||||
originalValue: 'Seattle',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Name of the continent.',
|
||||
example: 'North America',
|
||||
field: 'source.geo.continent_name',
|
||||
type: 'keyword',
|
||||
originalValue: 'North America',
|
||||
values: ['North America'],
|
||||
originalValue: 'North America',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Country ISO code.',
|
||||
example: 'CA',
|
||||
field: 'source.geo.country_iso_code',
|
||||
type: 'keyword',
|
||||
originalValue: 'US',
|
||||
values: ['US'],
|
||||
originalValue: 'US',
|
||||
},
|
||||
{
|
||||
field: 'source.geo.location.lat',
|
||||
values: ['47.6103'],
|
||||
originalValue: 47.6103,
|
||||
},
|
||||
{
|
||||
field: 'source.geo.location.lon',
|
||||
values: ['-122.3341'],
|
||||
originalValue: -122.3341,
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Region ISO code.',
|
||||
example: 'CA-QC',
|
||||
field: 'source.geo.region_iso_code',
|
||||
type: 'keyword',
|
||||
originalValue: 'US-WA',
|
||||
values: ['US-WA'],
|
||||
originalValue: 'US-WA',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Region name.',
|
||||
example: 'Quebec',
|
||||
field: 'source.geo.region_name',
|
||||
type: 'keyword',
|
||||
originalValue: 'Washington',
|
||||
values: ['Washington'],
|
||||
originalValue: 'Washington',
|
||||
},
|
||||
{
|
||||
category: 'source',
|
||||
description: 'IP address of the source. Can be one or multiple IPv4 or IPv6 addresses.',
|
||||
example: null,
|
||||
field: 'source.ip',
|
||||
type: 'ip',
|
||||
originalValue: '54.239.219.210',
|
||||
values: ['54.239.219.210'],
|
||||
originalValue: '54.239.219.210',
|
||||
},
|
||||
{ field: 'source.port', values: ['80'], originalValue: 80 },
|
||||
{
|
||||
category: 'source',
|
||||
description: 'Port of the source.',
|
||||
example: null,
|
||||
field: 'source.port',
|
||||
type: 'long',
|
||||
originalValue: 80,
|
||||
values: ['80'],
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.fileinfo.state',
|
||||
type: 'keyword',
|
||||
originalValue: 'CLOSED',
|
||||
values: ['CLOSED'],
|
||||
originalValue: 'CLOSED',
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.fileinfo.tx_id',
|
||||
type: 'long',
|
||||
originalValue: 301,
|
||||
values: ['301'],
|
||||
originalValue: 301,
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.flow_id',
|
||||
type: 'keyword',
|
||||
originalValue: 196625917175466,
|
||||
values: ['196625917175466'],
|
||||
originalValue: 196625917175466,
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.http.http_content_type',
|
||||
type: 'keyword',
|
||||
originalValue: 'video/mp4',
|
||||
values: ['video/mp4'],
|
||||
originalValue: 'video/mp4',
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.http.protocol',
|
||||
type: 'keyword',
|
||||
originalValue: 'HTTP/1.1',
|
||||
values: ['HTTP/1.1'],
|
||||
originalValue: 'HTTP/1.1',
|
||||
},
|
||||
{
|
||||
category: 'suricata',
|
||||
description: null,
|
||||
example: null,
|
||||
field: 'suricata.eve.in_iface',
|
||||
type: 'keyword',
|
||||
originalValue: 'eth0',
|
||||
values: ['eth0'],
|
||||
originalValue: 'eth0',
|
||||
},
|
||||
{ field: 'tags', values: ['suricata'], originalValue: ['suricata'] },
|
||||
{
|
||||
category: 'tags',
|
||||
description: 'List of keywords used to tag each event.',
|
||||
example: '["production", "env2"]',
|
||||
field: 'tags',
|
||||
type: 'keyword',
|
||||
originalValue: ['suricata'],
|
||||
values: ['suricata'],
|
||||
},
|
||||
{
|
||||
category: 'url',
|
||||
description:
|
||||
'Domain of the request, such as "www.elastic.co". In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the `domain` field.',
|
||||
example: 'www.elastic.co',
|
||||
field: 'url.domain',
|
||||
type: 'keyword',
|
||||
originalValue: 's3-iad-2.cf.dash.row.aiv-cdn.net',
|
||||
values: ['s3-iad-2.cf.dash.row.aiv-cdn.net'],
|
||||
originalValue: 's3-iad-2.cf.dash.row.aiv-cdn.net',
|
||||
},
|
||||
{
|
||||
category: 'url',
|
||||
description:
|
||||
'Unmodified original url as seen in the event source. Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not.',
|
||||
example: 'https://www.elastic.co:443/search?q=elasticsearch#top or /search?q=elasticsearch',
|
||||
field: 'url.original',
|
||||
type: 'keyword',
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
values: [
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
],
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
},
|
||||
{
|
||||
category: 'url',
|
||||
description: 'Path of the request, such as "/search".',
|
||||
example: null,
|
||||
field: 'url.path',
|
||||
type: 'keyword',
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
values: [
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
],
|
||||
originalValue:
|
||||
'/dm/2$XTMWANo0Q2RZKlH-95UoAahZrOg~/0a9a/bf72/e1da/4c20-919e-0cbabcf7bfe8/75f50c57-d25f-4e97-9e37-01b9f5caa293_audio_13.mp4',
|
||||
},
|
||||
{
|
||||
field: '_index',
|
||||
values: ['filebeat-7.0.0-iot-2019.06'],
|
||||
originalValue: 'filebeat-7.0.0-iot-2019.06',
|
||||
},
|
||||
{ field: '_type', values: ['_doc'], originalValue: '_doc' },
|
||||
{
|
||||
field: '_id',
|
||||
values: ['QRhG1WgBqd-n62SwZYDT'],
|
||||
originalValue: 'QRhG1WgBqd-n62SwZYDT',
|
||||
},
|
||||
{ field: '_score', values: ['1'], originalValue: 1 },
|
||||
];
|
||||
|
||||
const timelineDetailsTests: KbnTestProvider = ({ getService }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue