mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.x] [Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule (#196561) (#196904)
# Backport This will backport the following commits from `main` to `8.x`: - [[Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule (#196561)](https://github.com/elastic/kibana/pull/196561) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Juan Pablo Djeredjian","email":"jpdjeredjian@gmail.com"},"sourceCommit":{"committedDate":"2024-10-18T14:50:36Z","message":"[Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule (#196561)\n\nResolves: https://github.com/elastic/kibana/issues/196213\r\n\r\n## Summary\r\n\r\nExcludes the fields `exceptions_list`, `author` and `license` from the\r\n`DiffableRule` definition.\r\n\r\nThis will:\r\n\r\n- prevent them from appearing in the Three Way Diff component\r\n- prevent them from being able to be passed as a value in the `fields`\r\nobject of the `/upgrade/_perform` endpoint to set a specific\r\n`pick_version` for it (NOTE: the current logic already forces\r\n`exceptions_list` to upgrade to the CURRENT version, but removing it\r\nfrom DiffableRule, will completely remove the from the payload schema,\r\nand the endpoint will then throw a validation error if included, rather\r\nthan silently ignoring it)\r\n\r\n## Screenshots\r\n\r\n### Before\r\n\r\n\r\n\r\n\r\n\r\n### After\r\n\r\n\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"716fdb23c7d42c9f7c29525af793ff1594ad67f0","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","Feature:Prebuilt Detection Rules","backport:prev-minor","v8.16.0"],"title":"[Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule","number":196561,"url":"https://github.com/elastic/kibana/pull/196561","mergeCommit":{"message":"[Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule (#196561)\n\nResolves: https://github.com/elastic/kibana/issues/196213\r\n\r\n## Summary\r\n\r\nExcludes the fields `exceptions_list`, `author` and `license` from the\r\n`DiffableRule` definition.\r\n\r\nThis will:\r\n\r\n- prevent them from appearing in the Three Way Diff component\r\n- prevent them from being able to be passed as a value in the `fields`\r\nobject of the `/upgrade/_perform` endpoint to set a specific\r\n`pick_version` for it (NOTE: the current logic already forces\r\n`exceptions_list` to upgrade to the CURRENT version, but removing it\r\nfrom DiffableRule, will completely remove the from the payload schema,\r\nand the endpoint will then throw a validation error if included, rather\r\nthan silently ignoring it)\r\n\r\n## Screenshots\r\n\r\n### Before\r\n\r\n\r\n\r\n\r\n\r\n### After\r\n\r\n\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"716fdb23c7d42c9f7c29525af793ff1594ad67f0"}},"sourceBranch":"main","suggestedTargetBranches":["8.16"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/196561","number":196561,"mergeCommit":{"message":"[Security Solution] Remove `exceptions_list`, `author` and `license` from Diffable Rule (#196561)\n\nResolves: https://github.com/elastic/kibana/issues/196213\r\n\r\n## Summary\r\n\r\nExcludes the fields `exceptions_list`, `author` and `license` from the\r\n`DiffableRule` definition.\r\n\r\nThis will:\r\n\r\n- prevent them from appearing in the Three Way Diff component\r\n- prevent them from being able to be passed as a value in the `fields`\r\nobject of the `/upgrade/_perform` endpoint to set a specific\r\n`pick_version` for it (NOTE: the current logic already forces\r\n`exceptions_list` to upgrade to the CURRENT version, but removing it\r\nfrom DiffableRule, will completely remove the from the payload schema,\r\nand the endpoint will then throw a validation error if included, rather\r\nthan silently ignoring it)\r\n\r\n## Screenshots\r\n\r\n### Before\r\n\r\n\r\n\r\n\r\n\r\n### After\r\n\r\n\r\n\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"716fdb23c7d42c9f7c29525af793ff1594ad67f0"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Juan Pablo Djeredjian <jpdjeredjian@gmail.com>
This commit is contained in:
parent
8e2facb817
commit
125e7fe8b1
15 changed files with 22 additions and 209 deletions
|
@ -21,11 +21,8 @@ import {
|
|||
RequiredFieldArray,
|
||||
RiskScore,
|
||||
RiskScoreMapping,
|
||||
RuleAuthorArray,
|
||||
RuleDescription,
|
||||
RuleExceptionList,
|
||||
RuleFalsePositiveArray,
|
||||
RuleLicense,
|
||||
RuleName,
|
||||
RuleReferenceArray,
|
||||
RuleSignatureId,
|
||||
|
@ -82,12 +79,9 @@ export const DiffableCommonFields = z.object({
|
|||
setup: SetupGuide,
|
||||
related_integrations: RelatedIntegrationArray,
|
||||
required_fields: RequiredFieldArray,
|
||||
author: RuleAuthorArray,
|
||||
license: RuleLicense,
|
||||
|
||||
// Other domain fields
|
||||
rule_schedule: RuleSchedule, // NOTE: new field
|
||||
exceptions_list: z.array(RuleExceptionList),
|
||||
max_signals: MaxSignals,
|
||||
|
||||
// Optional fields
|
||||
|
|
|
@ -40,7 +40,7 @@ export const FIELDS_TO_UPGRADE_TO_CURRENT_VERSION = [
|
|||
'items_per_search',
|
||||
] as const;
|
||||
|
||||
export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [
|
||||
export const FIELDS_TO_UPGRADE_TO_TARGET_VERSION = [
|
||||
'type',
|
||||
'rule_id',
|
||||
'version',
|
||||
|
@ -48,6 +48,10 @@ export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [
|
|||
'license',
|
||||
] as const;
|
||||
|
||||
// Fields which are part of DiffableRule but are not upgradeable
|
||||
// and need to be omittted from the DiffableUpgradableFields
|
||||
export const NON_UPGRADEABLE_DIFFABLE_FIELDS = ['type', 'rule_id', 'version'] as const;
|
||||
|
||||
type NON_UPGRADEABLE_DIFFABLE_FIELDS_TO_OMIT_TYPE = {
|
||||
readonly [key in (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number]]: true;
|
||||
};
|
||||
|
|
|
@ -133,12 +133,9 @@ const extractDiffableCommonFields = (
|
|||
setup: rule.setup ?? '',
|
||||
related_integrations: rule.related_integrations ?? [],
|
||||
required_fields: addEcsToRequiredFields(rule.required_fields),
|
||||
author: rule.author ?? [],
|
||||
license: rule.license ?? '',
|
||||
|
||||
// Other domain fields
|
||||
rule_schedule: extractRuleSchedule(rule),
|
||||
exceptions_list: rule.exceptions_list ?? [],
|
||||
max_signals: rule.max_signals ?? DEFAULT_MAX_SIGNALS,
|
||||
|
||||
// --------------------- OPTIONAL FIELDS
|
||||
|
|
|
@ -14,7 +14,6 @@ export const ABOUT_UPGRADE_FIELD_ORDER: Array<keyof DiffableAllFields> = [
|
|||
'version',
|
||||
'name',
|
||||
'description',
|
||||
'author',
|
||||
'building_block',
|
||||
'investigation_fields',
|
||||
'severity',
|
||||
|
@ -23,7 +22,6 @@ export const ABOUT_UPGRADE_FIELD_ORDER: Array<keyof DiffableAllFields> = [
|
|||
'risk_score_mapping',
|
||||
'references',
|
||||
'false_positives',
|
||||
'license',
|
||||
'rule_name_override',
|
||||
'threat',
|
||||
'threat_indicator_path',
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { DiffableAllFields } from '../../../../../../../common/api/detection_engine';
|
||||
|
||||
type NonEditableFields = Readonly<Set<keyof DiffableAllFields>>;
|
||||
|
||||
/* These fields are not visible in the comparison UI and are not editable */
|
||||
export const HIDDEN_FIELDS: NonEditableFields = new Set([
|
||||
'alert_suppression',
|
||||
'author',
|
||||
'rule_id',
|
||||
'license',
|
||||
'version',
|
||||
]);
|
|
@ -19,11 +19,9 @@ import { NameReadOnly } from './fields/name/name';
|
|||
import { TagsReadOnly } from './fields/tags/tags';
|
||||
import { DescriptionReadOnly } from './fields/description/description';
|
||||
import { assertUnreachable } from '../../../../../../../common/utility_types';
|
||||
import { AuthorReadOnly } from './fields/author/author';
|
||||
import { BuildingBlockReadOnly } from './fields/building_block/building_block';
|
||||
import { InvestigationFieldsReadOnly } from './fields/investigation_fields/investigation_fields';
|
||||
import { FalsePositivesReadOnly } from './fields/false_positives/false_positives';
|
||||
import { LicenseReadOnly } from './fields/license/license';
|
||||
import { MaxSignalsReadOnly } from './fields/max_signals/max_signals';
|
||||
import { NoteReadOnly } from './fields/note/note';
|
||||
import { RuleScheduleReadOnly } from './fields/rule_schedule/rule_schedule';
|
||||
|
@ -46,23 +44,16 @@ export function CommonRuleFieldReadOnly({
|
|||
finalDiffableRule,
|
||||
}: CommonRuleFieldReadOnlyProps) {
|
||||
switch (fieldName) {
|
||||
case 'author':
|
||||
return <AuthorReadOnly author={finalDiffableRule.author} />;
|
||||
case 'building_block':
|
||||
return <BuildingBlockReadOnly />;
|
||||
case 'description':
|
||||
return <DescriptionReadOnly description={finalDiffableRule.description} />;
|
||||
case 'exceptions_list':
|
||||
/* Exceptions are not used in prebuilt rules */
|
||||
return null;
|
||||
case 'investigation_fields':
|
||||
return (
|
||||
<InvestigationFieldsReadOnly investigationFields={finalDiffableRule.investigation_fields} />
|
||||
);
|
||||
case 'false_positives':
|
||||
return <FalsePositivesReadOnly falsePositives={finalDiffableRule.false_positives} />;
|
||||
case 'license':
|
||||
return <LicenseReadOnly license={finalDiffableRule.license} />;
|
||||
case 'max_signals':
|
||||
return <MaxSignalsReadOnly maxSignals={finalDiffableRule.max_signals} />;
|
||||
case 'name':
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Story } from '@storybook/react';
|
||||
import { AuthorReadOnly } from './author';
|
||||
import { FieldReadOnly } from '../../field_readonly';
|
||||
import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine';
|
||||
import { mockCustomQueryRule } from '../../storybook/mocks';
|
||||
import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers';
|
||||
|
||||
export default {
|
||||
component: AuthorReadOnly,
|
||||
title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/author',
|
||||
};
|
||||
|
||||
interface TemplateProps {
|
||||
finalDiffableRule: DiffableRule;
|
||||
}
|
||||
|
||||
const Template: Story<TemplateProps> = (args) => {
|
||||
return (
|
||||
<ThreeWayDiffStorybookProviders finalDiffableRule={args.finalDiffableRule}>
|
||||
<FieldReadOnly fieldName="author" />
|
||||
</ThreeWayDiffStorybookProviders>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {
|
||||
finalDiffableRule: mockCustomQueryRule({
|
||||
author: ['Elastic', 'John Doe'],
|
||||
}),
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiDescriptionList } from '@elastic/eui';
|
||||
import * as ruleDetailsI18n from '../../../../translations';
|
||||
import type { RuleAuthorArray } from '../../../../../../../../../common/api/detection_engine';
|
||||
import { Author } from '../../../../rule_about_section';
|
||||
|
||||
interface AuthorReadOnlyProps {
|
||||
author: RuleAuthorArray;
|
||||
}
|
||||
|
||||
export function AuthorReadOnly({ author }: AuthorReadOnlyProps) {
|
||||
return (
|
||||
<EuiDescriptionList
|
||||
listItems={[
|
||||
{
|
||||
title: ruleDetailsI18n.AUTHOR_FIELD_LABEL,
|
||||
description: <Author author={author} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Story } from '@storybook/react';
|
||||
import { LicenseReadOnly } from './license';
|
||||
import { FieldReadOnly } from '../../field_readonly';
|
||||
import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine';
|
||||
import { mockCustomQueryRule } from '../../storybook/mocks';
|
||||
import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers';
|
||||
|
||||
export default {
|
||||
component: LicenseReadOnly,
|
||||
title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/license',
|
||||
};
|
||||
|
||||
interface TemplateProps {
|
||||
finalDiffableRule: DiffableRule;
|
||||
}
|
||||
|
||||
const Template: Story<TemplateProps> = (args) => {
|
||||
return (
|
||||
<ThreeWayDiffStorybookProviders finalDiffableRule={args.finalDiffableRule}>
|
||||
<FieldReadOnly fieldName="license" />
|
||||
</ThreeWayDiffStorybookProviders>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {
|
||||
finalDiffableRule: mockCustomQueryRule({
|
||||
license: 'Elastic License 2.0',
|
||||
}),
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiDescriptionList } from '@elastic/eui';
|
||||
import * as ruleDetailsI18n from '../../../../translations';
|
||||
import type { RuleLicense } from '../../../../../../../../../common/api/detection_engine';
|
||||
import { License } from '../../../../rule_about_section';
|
||||
|
||||
interface LicenseReadOnlyProps {
|
||||
license: RuleLicense;
|
||||
}
|
||||
|
||||
export function LicenseReadOnly({ license }: LicenseReadOnlyProps) {
|
||||
return (
|
||||
<EuiDescriptionList
|
||||
listItems={[
|
||||
{
|
||||
title: ruleDetailsI18n.LICENSE_FIELD_LABEL,
|
||||
description: <License license={license} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -137,14 +137,10 @@ const commonDiffableRuleFields: DiffableCommonFields = {
|
|||
setup: '',
|
||||
related_integrations: [],
|
||||
required_fields: [],
|
||||
author: [],
|
||||
license: '',
|
||||
|
||||
rule_schedule: {
|
||||
interval: '5m',
|
||||
lookback: '360s',
|
||||
},
|
||||
exceptions_list: [],
|
||||
max_signals: DEFAULT_MAX_SIGNALS,
|
||||
};
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DiffableCommonFields } from '../../../../../common/api/detection_engine';
|
||||
import type {
|
||||
DiffableCustomQueryFields,
|
||||
DiffableEqlFields,
|
||||
DiffableEsqlFields,
|
||||
DiffableMachineLearningFields,
|
||||
DiffableNewTermsFields,
|
||||
DiffableSavedQueryFields,
|
||||
DiffableThreatMatchFields,
|
||||
DiffableThresholdFields,
|
||||
RuleFieldsDiff,
|
||||
import {
|
||||
DiffableCommonFields,
|
||||
NON_UPGRADEABLE_DIFFABLE_FIELDS,
|
||||
type DiffableCustomQueryFields,
|
||||
type DiffableEqlFields,
|
||||
type DiffableEsqlFields,
|
||||
type DiffableMachineLearningFields,
|
||||
type DiffableNewTermsFields,
|
||||
type DiffableSavedQueryFields,
|
||||
type DiffableThreatMatchFields,
|
||||
type DiffableThresholdFields,
|
||||
type RuleFieldsDiff,
|
||||
} from '../../../../../common/api/detection_engine';
|
||||
|
||||
export type NonUpgradeableDiffableFields = (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number];
|
||||
|
@ -61,14 +61,6 @@ export type UpgradeableNewTermsFields = Exclude<
|
|||
NonUpgradeableDiffableFields
|
||||
>;
|
||||
|
||||
export const NON_UPGRADEABLE_DIFFABLE_FIELDS = [
|
||||
'author',
|
||||
'license',
|
||||
'rule_id',
|
||||
'type',
|
||||
'version',
|
||||
] as const;
|
||||
|
||||
export const COMMON_FIELD_NAMES = DiffableCommonFields.keyof().options;
|
||||
|
||||
export function isCommonFieldName(fieldName: string): fieldName is keyof DiffableCommonFields {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import {
|
||||
FIELDS_TO_UPGRADE_TO_CURRENT_VERSION,
|
||||
NON_UPGRADEABLE_DIFFABLE_FIELDS,
|
||||
FIELDS_TO_UPGRADE_TO_TARGET_VERSION,
|
||||
} from '../../../../../../common/api/detection_engine';
|
||||
import { type PrebuiltRuleAsset } from '../../model/rule_assets/prebuilt_rule_asset';
|
||||
import type { RuleTriad } from '../../model/rule_groups/get_rule_groups';
|
||||
|
@ -24,10 +24,10 @@ type GetFieldPredefinedValueReturnType =
|
|||
* a predefined value or is customizable), and returns the value if it is predefined.
|
||||
*
|
||||
* This function checks whether a field can be upgraded via API contract and how it should
|
||||
* be handled during the rule upgrade process. It uses the `NON_UPGRADEABLE_DIFFABLE_FIELDS` and
|
||||
* be handled during the rule upgrade process. It uses the `FIELDS_TO_UPGRADE_TO_TARGET_VERSION` and
|
||||
* `FIELDS_TO_UPGRADE_TO_CURRENT_VERSION` constants to make this determination.
|
||||
*
|
||||
* `NON_UPGRADEABLE_DIFFABLE_FIELDS` includes fields that are not upgradeable: 'type', 'rule_id',
|
||||
* `FIELDS_TO_UPGRADE_TO_TARGET_VERSION` includes fields that are not upgradeable: 'type', 'rule_id',
|
||||
* 'version', 'author', and 'license', and are always upgraded to the target version.
|
||||
*
|
||||
* `FIELDS_TO_UPGRADE_TO_CURRENT_VERSION` includes fields that should be updated to their
|
||||
|
@ -46,8 +46,8 @@ export const getFieldPredefinedValue = (
|
|||
upgradeableRule: RuleTriad
|
||||
): GetFieldPredefinedValueReturnType => {
|
||||
if (
|
||||
NON_UPGRADEABLE_DIFFABLE_FIELDS.includes(
|
||||
fieldName as (typeof NON_UPGRADEABLE_DIFFABLE_FIELDS)[number]
|
||||
FIELDS_TO_UPGRADE_TO_TARGET_VERSION.includes(
|
||||
fieldName as (typeof FIELDS_TO_UPGRADE_TO_TARGET_VERSION)[number]
|
||||
)
|
||||
) {
|
||||
return {
|
||||
|
|
|
@ -194,10 +194,7 @@ const commonFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableCommonFields>
|
|||
setup: multiLineStringDiffAlgorithm,
|
||||
related_integrations: simpleDiffAlgorithm,
|
||||
required_fields: simpleDiffAlgorithm,
|
||||
author: scalarArrayDiffAlgorithm,
|
||||
license: singleLineStringDiffAlgorithm,
|
||||
rule_schedule: simpleDiffAlgorithm,
|
||||
exceptions_list: simpleDiffAlgorithm,
|
||||
max_signals: numberDiffAlgorithm,
|
||||
rule_name_override: simpleDiffAlgorithm,
|
||||
timestamp_override: simpleDiffAlgorithm,
|
||||
|
|
|
@ -776,7 +776,6 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
|
||||
// Create resolved values different from current values
|
||||
const resolvedValues: { [key: string]: unknown } = {
|
||||
exceptions_list: [],
|
||||
alert_suppression: {
|
||||
group_by: ['test'],
|
||||
duration: { value: 10, unit: 'm' as const },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue