[SecuritySolution] remove "fields" from the BrowserField (#187066)

## Summary

This is part 1/n of a wider effort:)

BrowserField used to be some kind of field dictionary (!) which is
obviously wrong:). Added FieldCategory type for that as an intermediate
step as I dont know if it will hold up after the changes I am doing are
complete.
This commit is contained in:
Luke G 2024-07-03 22:03:02 +02:00 committed by GitHub
parent 184b6e2ad4
commit adc9310845
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 19 additions and 53 deletions

View file

@ -60,7 +60,7 @@ describe('getColumns', () => {
describe('column actions', () => {
let actionsColumn: Column;
const mockDataToUse = mockBrowserFields.agent;
const mockDataToUse = mockBrowserFields.agent.fields;
const testValue = 'testValue';
const testData = {
type: 'someType',

View file

@ -21,7 +21,6 @@ import { getEnrichmentIdentifiers, isInvestigationTimeEnrichment } from './helpe
import type { FieldsData } from '../types';
import type {
BrowserField,
BrowserFields,
TimelineEventsDetailsItem,
} from '../../../../../common/search_strategy';
@ -30,7 +29,6 @@ import { EnrichedDataRow, ThreatSummaryPanelHeader } from './threat_summary_view
import { getSourcererScopeId } from '../../../../helpers';
export interface ThreatSummaryDescription {
browserField: BrowserField;
data: FieldsData | undefined;
eventId: string;
index: number;
@ -63,7 +61,6 @@ export const StyledEuiFlexGroup = styled(EuiFlexGroup)`
`;
const EnrichmentDescription: React.FC<ThreatSummaryDescription> = ({
browserField,
data,
eventId,
index,
@ -179,7 +176,6 @@ const EnrichmentSummaryComponent: React.FC<{
scopeId={scopeId}
value={value}
data={fieldsData}
browserField={browserField}
isDraggable={isDraggable}
isReadOnly={isReadOnly}
/>
@ -210,7 +206,6 @@ const EnrichmentSummaryComponent: React.FC<{
scopeId={scopeId}
value={value}
data={fieldsData}
browserField={browserField}
isDraggable={isDraggable}
isReadOnly={isReadOnly}
/>

View file

@ -21,7 +21,6 @@ const eventId = 'TUWyf3wBFCFU0qRJTauW';
const hostIpValues = ['127.0.0.1', '::1', '10.1.2.3', '2001:0DB8:AC10:FE01::'];
const hostIpFieldFromBrowserField: BrowserField = {
aggregatable: true,
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
name: 'host.ip',
@ -33,7 +32,6 @@ const hostIpData: EventFieldsData = {
...hostIpFieldFromBrowserField,
ariaRowindex: 35,
field: 'host.ip',
fields: {},
format: '',
isObjectArray: false,
originalValue: [...hostIpValues],

View file

@ -21,7 +21,6 @@ const hostIpData: EventFieldsData = {
aggregatable: true,
ariaRowindex: 35,
field: 'host.ip',
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
isObjectArray: false,
@ -87,7 +86,6 @@ describe('FieldValueCell', () => {
aggregatable: false,
ariaRowindex: 50,
field: 'message',
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
isObjectArray: false,
@ -102,7 +100,6 @@ describe('FieldValueCell', () => {
const messageFieldFromBrowserField: BrowserField = {
aggregatable: false,
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
name: 'message',
@ -139,7 +136,6 @@ describe('FieldValueCell', () => {
describe('when `BrowserField` metadata IS available', () => {
const hostIpFieldFromBrowserField: BrowserField = {
aggregatable: true,
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
name: 'host.ip',

View file

@ -18,7 +18,7 @@ export interface FieldValueCellProps {
contextId: string;
data: EventFieldsData | FieldsData;
eventId: string;
fieldFromBrowserField?: BrowserField;
fieldFromBrowserField?: Partial<BrowserField>;
getLinkValue?: (field: string) => string | null;
isDraggable?: boolean;
linkValue?: string | null | undefined;

View file

@ -27,7 +27,6 @@ const eventId = 'TUWyf3wBFCFU0qRJTauW';
const hostIpValues = ['127.0.0.1', '::1', '10.1.2.3', '2001:0DB8:AC10:FE01::'];
const hostIpFieldFromBrowserField: BrowserField = {
aggregatable: true,
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
name: 'host.ip',
@ -39,7 +38,6 @@ const hostIpData: EventFieldsData = {
...hostIpFieldFromBrowserField,
ariaRowindex: 35,
field: 'host.ip',
fields: {},
format: '',
isObjectArray: false,
originalValue: [...hostIpValues],

View file

@ -24,7 +24,6 @@ const eventId = 'TUWyf3wBFCFU0qRJTauW';
const hostIpValues = ['127.0.0.1', '::1', '10.1.2.3', '2001:0DB8:AC10:FE01::'];
const hostIpFieldFromBrowserField: BrowserField = {
aggregatable: true,
fields: {},
format: '',
indexes: ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'],
name: 'host.ip',
@ -36,7 +35,6 @@ const hostIpData: EventFieldsData = {
...hostIpFieldFromBrowserField,
ariaRowindex: 35,
field: 'host.ip',
fields: {},
format: '',
isObjectArray: false,
originalValue: [...hostIpValues],
@ -58,7 +56,6 @@ const enrichedAgentStatusData: AlertSummaryRow['description'] = {
format: '',
type: '',
aggregatable: false,
fields: {},
indexes: [],
name: AGENT_STATUS_FIELD_NAME,
searchable: false,

View file

@ -38,7 +38,7 @@ export interface UseActionCellDataProvider {
eventId?: string;
field: string;
fieldFormat?: string;
fieldFromBrowserField?: BrowserField;
fieldFromBrowserField?: Partial<BrowserField>;
fieldType?: string;
isObjectArray?: boolean;
linkValue?: string | null;

View file

@ -20,7 +20,7 @@ export interface FieldsData {
export interface EnrichedFieldInfo {
data: FieldsData | EventFieldsData;
eventId: string;
fieldFromBrowserField?: BrowserField;
fieldFromBrowserField?: Partial<BrowserField>;
scopeId: string;
values: string[] | null | undefined;
linkValue?: string;

View file

@ -73,7 +73,6 @@ describe('QueryBarDefineRule', () => {
<TestProviders>
<Router history={mockHistory}>
<QueryBarDefineRule
browserFields={{}}
isLoading={false}
indexPattern={{ fields: [], title: 'title' }}
onCloseTimelineSearch={jest.fn()}
@ -96,7 +95,6 @@ describe('QueryBarDefineRule', () => {
<TestProviders>
<Router history={mockHistory}>
<QueryBarDefineRule
browserFields={{}}
isLoading={false}
indexPattern={{ fields: [], title: 'title' }}
onCloseTimelineSearch={jest.fn()}
@ -122,7 +120,6 @@ describe('QueryBarDefineRule', () => {
<TestProviders>
<Router history={mockHistory}>
<QueryBarDefineRule
browserFields={{}}
isLoading={false}
indexPattern={{ fields: [], title: 'title' }}
onCloseTimelineSearch={jest.fn()}

View file

@ -13,7 +13,6 @@ import type { DataViewBase, Filter, Query } from '@kbn/es-query';
import type { SavedQuery } from '@kbn/data-plugin/public';
import { FilterManager } from '@kbn/data-plugin/public';
import type { BrowserFields } from '../../../../common/containers/source';
import { OpenTimelineModal } from '../../../../timelines/components/open_timeline/open_timeline_modal';
import type { ActionTimelineToShow } from '../../../../timelines/components/open_timeline/types';
import { QueryBar } from '../../../../common/components/query_bar';
@ -31,7 +30,6 @@ export interface FieldValueQueryBar {
title?: string;
}
export interface QueryBarDefineRuleProps {
browserFields: BrowserFields;
dataTestSubj: string;
field: FieldHook;
idAria: string;
@ -74,7 +72,6 @@ const savedQueryToFieldValue = (savedQuery: SavedQuery): FieldValueQueryBar => (
export const QueryBarDefineRule = ({
defaultSavedQuery,
browserFields,
dataTestSubj,
field,
idAria,

View file

@ -704,7 +704,6 @@ function TestForm({
setOptionsSelected={setSelectedEqlOptions}
indexPattern={indexPattern}
isIndexPatternLoading={false}
browserFields={{}}
isQueryBarValid={true}
setIsQueryBarValid={jest.fn()}
setIsThreatQueryBarValid={jest.fn()}

View file

@ -26,7 +26,6 @@ import { i18n as i18nCore } from '@kbn/i18n';
import { isEqual, isEmpty } from 'lodash';
import type { FieldSpec } from '@kbn/data-views-plugin/common';
import usePrevious from 'react-use/lib/usePrevious';
import type { BrowserFields } from '@kbn/timelines-plugin/common';
import type { Type } from '@kbn/securitysolution-io-ts-alerting-types';
import { useQueryClient } from '@tanstack/react-query';
@ -118,7 +117,6 @@ export interface StepDefineRuleProps extends RuleStepProps {
setOptionsSelected: React.Dispatch<React.SetStateAction<EqlOptionsSelected>>;
indexPattern: DataViewBase;
isIndexPatternLoading: boolean;
browserFields: BrowserFields;
isQueryBarValid: boolean;
setIsQueryBarValid: (valid: boolean) => void;
setIsThreatQueryBarValid: (valid: boolean) => void;
@ -167,7 +165,6 @@ const IntendedRuleTypeEuiFormRow = styled(RuleTypeEuiFormRow)`
// eslint-disable-next-line complexity
const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
browserFields,
dataSourceType,
defaultSavedQuery,
enableThresholdSuppression,
@ -293,10 +290,8 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
[aggFields]
);
const [
threatIndexPatternsLoading,
{ browserFields: threatBrowserFields, indexPatterns: threatIndexPatterns },
] = useFetchIndex(threatIndex);
const [threatIndexPatternsLoading, { indexPatterns: threatIndexPatterns }] =
useFetchIndex(threatIndex);
// reset form when rule type changes
useEffect(() => {
@ -452,7 +447,6 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
<ThreatMatchInput
handleResetThreatIndices={handleResetThreatIndices}
indexPatterns={indexPattern}
threatBrowserFields={threatBrowserFields}
threatIndexModified={threatIndexModified}
threatIndexPatterns={threatIndexPatterns}
threatIndexPatternsLoading={threatIndexPatternsLoading}
@ -464,7 +458,6 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
handleResetThreatIndices,
indexPattern,
setIsThreatQueryBarValid,
threatBrowserFields,
threatIndexModified,
threatIndexPatterns,
threatIndexPatternsLoading,
@ -821,7 +814,6 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
component={QueryBarDefineRule}
componentProps={
{
browserFields,
idAria: 'detectionEngineStepDefineRuleQueryBar',
indexPattern,
isDisabled: isLoading || shouldLoadQueryDynamically || timelineQueryLoading,
@ -841,7 +833,6 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
[
handleOpenTimelineSearch,
shouldLoadQueryDynamically,
browserFields,
indexPattern,
isLoading,
timelineQueryLoading,

View file

@ -10,7 +10,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiFormRow } from '@elastic/eui';
import type { DataViewBase } from '@kbn/es-query';
import type { ThreatMapEntries } from '../../../../common/components/threat_match/types';
import { ThreatMatchComponent } from '../../../../common/components/threat_match';
import type { BrowserField } from '../../../../common/containers/source';
import type { FieldHook } from '../../../../shared_imports';
import {
Field,
@ -28,7 +27,6 @@ const CommonUseField = getUseField({ component: Field });
interface ThreatMatchInputProps {
threatMapping: FieldHook;
threatBrowserFields: Readonly<Record<string, Partial<BrowserField>>>;
threatIndexPatterns: DataViewBase;
indexPatterns: DataViewBase;
threatIndexPatternsLoading: boolean;
@ -44,7 +42,6 @@ const ThreatMatchInputComponent: React.FC<ThreatMatchInputProps> = ({
indexPatterns,
threatIndexPatterns,
threatIndexPatternsLoading,
threatBrowserFields,
onValidityChange,
}: ThreatMatchInputProps) => {
const { setValue, value: threatItems } = threatMapping;
@ -101,7 +98,6 @@ const ThreatMatchInputComponent: React.FC<ThreatMatchInputProps> = ({
}}
component={QueryBarDefineRule}
componentProps={{
browserFields: threatBrowserFields,
idAria: 'detectionEngineStepDefineThreatRuleQueryBar',
indexPattern: threatIndexPatterns,
isDisabled: false,

View file

@ -262,7 +262,7 @@ const CreateRulePageComponent: React.FC = () => {
};
fetchDV();
}, [dataViews]);
const { indexPattern, isIndexPatternLoading, browserFields } = useRuleIndexPattern({
const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern({
dataSourceType: defineStepData.dataSourceType,
index: memoizedIndex,
dataViewId: defineStepData.dataViewId,
@ -504,7 +504,6 @@ const CreateRulePageComponent: React.FC = () => {
setOptionsSelected={setEqlOptionsSelected}
indexPattern={indexPattern}
isIndexPatternLoading={isIndexPatternLoading}
browserFields={browserFields}
isQueryBarValid={isQueryBarValid}
setIsQueryBarValid={setIsQueryBarValid}
setIsThreatQueryBarValid={setIsThreatQueryBarValid}
@ -530,7 +529,6 @@ const CreateRulePageComponent: React.FC = () => {
),
[
activeStep,
browserFields,
dataViewOptions,
defineRuleNextStep,
defineStepData.dataSourceType,

View file

@ -210,7 +210,7 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => {
});
const actionMessageParams = useMemo(() => getActionMessageParams(rule?.type), [rule?.type]);
const { indexPattern, isIndexPatternLoading, browserFields } = useRuleIndexPattern({
const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern({
dataSourceType: defineStepData.dataSourceType,
index: memoizedIndex,
dataViewId: defineStepData.dataViewId,
@ -245,7 +245,6 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => {
key="defineStep"
indexPattern={indexPattern}
isIndexPatternLoading={isIndexPatternLoading}
browserFields={browserFields}
isQueryBarValid={isQueryBarValid}
setIsQueryBarValid={setIsQueryBarValid}
setIsThreatQueryBarValid={setIsThreatQueryBarValid}
@ -371,7 +370,6 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => {
setEqlOptionsSelected,
indexPattern,
isIndexPatternLoading,
browserFields,
isQueryBarValid,
defineStepData,
aboutStepData,

View file

@ -8,9 +8,10 @@
import { findIndex } from 'lodash/fp';
import type { EuiComboBoxOptionOption } from '@elastic/eui';
import type { FieldCategory } from '@kbn/timelines-plugin/common/search_strategy';
import { DataProviderType } from '../../../../common/api/timeline';
import type { BrowserField, BrowserFields } from '../../../common/containers/source';
import type { BrowserFields } from '../../../common/containers/source';
import { getAllFieldsByName } from '../../../common/containers/source';
import type { QueryOperator } from '../timeline/data_providers/data_provider';
import {
@ -46,7 +47,7 @@ export const operatorLabels: EuiComboBoxOptionOption[] = [
export const EMPTY_ARRAY_RESULT = [];
/** Returns the names of fields in a category */
export const getFieldNames = (category: Partial<BrowserField>): string[] =>
export const getFieldNames = (category: FieldCategory): string[] =>
category.fields != null && Object.keys(category.fields).length > 0
? Object.keys(category.fields)
: EMPTY_ARRAY_RESULT;

View file

@ -71,7 +71,7 @@ const FormattedFieldValueComponent: React.FC<{
isObjectArray?: boolean;
isUnifiedDataTable?: boolean;
fieldFormat?: string;
fieldFromBrowserField?: BrowserField;
fieldFromBrowserField?: Partial<BrowserField>;
fieldName: string;
fieldType?: string;
isButton?: boolean;

View file

@ -76,7 +76,6 @@ export interface IndexFieldsStrategyResponse extends IEsSearchResponse {
*/
export interface BrowserField {
aggregatable: boolean;
fields: Record<string, Partial<BrowserField>>; // FIXME: missing in FieldSpec
format: string;
indexes: string[]; // FIXME: missing in FieldSpec
name: string;
@ -88,6 +87,12 @@ export interface BrowserField {
runtimeField?: RuntimeField;
}
type FieldCategoryName = string;
export interface FieldCategory {
fields: Record<string, Partial<BrowserField>>;
}
/**
* @deprecated use fields list on dataview / "indexPattern"
* about to use browserFields? Reconsider! Maybe you can accomplish
@ -95,7 +100,7 @@ export interface BrowserField {
* you are working with? Or perhaps you need a description for a
* particular field? Consider using the EcsFlat module from `@kbn/ecs`
*/
export type BrowserFields = Record<string, Partial<BrowserField>>;
export type BrowserFields = Record<FieldCategoryName, FieldCategory>;
export const EMPTY_BROWSER_FIELDS = {};
export const EMPTY_INDEX_FIELDS: FieldSpec[] = [];