mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution] Extend the /upgrade/_perform
API endpoint's contract migrating to Zod (#189790)
Partially addresses (contract change only): https://github.com/elastic/kibana/issues/166376 Created in favour of: https://github.com/elastic/kibana/pull/189187 (closed) ## Summary - Extends contract as described in the [POC](https://github.com/elastic/kibana/pull/144060), migrating from `io-ts` to Zod (search for `Perform rule upgrade`) - Uses new types in endpoint, but functionality remains unchaged. ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
986e760756
commit
8d550b0ad2
4 changed files with 395 additions and 98 deletions
|
@ -5,11 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface AggregatedPrebuiltRuleError {
|
||||
message: string;
|
||||
status_code?: number;
|
||||
rules: Array<{
|
||||
rule_id: string;
|
||||
name?: string;
|
||||
}>;
|
||||
}
|
||||
import { z } from 'zod';
|
||||
import { RuleName, RuleSignatureId } from '../../model/rule_schema/common_attributes.gen';
|
||||
|
||||
export type AggregatedPrebuiltRuleError = z.infer<typeof AggregatedPrebuiltRuleError>;
|
||||
export const AggregatedPrebuiltRuleError = z.object({
|
||||
message: z.string(),
|
||||
status_code: z.number().optional(),
|
||||
rules: z.array(
|
||||
z.object({
|
||||
rule_id: RuleSignatureId,
|
||||
name: RuleName.optional(),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* 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 { expectParseError, expectParseSuccess, stringifyZodError } from '@kbn/zod-helpers';
|
||||
import {
|
||||
PickVersionValues,
|
||||
RuleUpgradeSpecifier,
|
||||
UpgradeSpecificRulesRequest,
|
||||
UpgradeAllRulesRequest,
|
||||
PerformRuleUpgradeResponseBody,
|
||||
PerformRuleUpgradeRequestBody,
|
||||
} from './perform_rule_upgrade_route';
|
||||
|
||||
describe('Perform Rule Upgrade Route Schemas', () => {
|
||||
describe('PickVersionValues', () => {
|
||||
test('validates correct enum values', () => {
|
||||
const validValues = ['BASE', 'CURRENT', 'TARGET', 'MERGED'];
|
||||
validValues.forEach((value) => {
|
||||
const result = PickVersionValues.safeParse(value);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toBe(value);
|
||||
});
|
||||
});
|
||||
|
||||
test('rejects invalid enum values', () => {
|
||||
const invalidValues = ['RESOLVED', 'MALFORMED_STRING'];
|
||||
invalidValues.forEach((value) => {
|
||||
const result = PickVersionValues.safeParse(value);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(
|
||||
`"Invalid enum value. Expected 'BASE' | 'CURRENT' | 'TARGET' | 'MERGED', received '${value}'"`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('RuleUpgradeSpecifier', () => {
|
||||
const validSpecifier = {
|
||||
rule_id: 'rule-1',
|
||||
revision: 1,
|
||||
version: 1,
|
||||
pick_version: 'TARGET',
|
||||
};
|
||||
|
||||
test('validates a valid upgrade specifier without fields property', () => {
|
||||
const result = RuleUpgradeSpecifier.safeParse(validSpecifier);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validSpecifier);
|
||||
});
|
||||
|
||||
test('validates a valid upgrade specifier with a fields property', () => {
|
||||
const specifierWithFields = {
|
||||
...validSpecifier,
|
||||
fields: {
|
||||
name: {
|
||||
pick_version: 'CURRENT',
|
||||
},
|
||||
},
|
||||
};
|
||||
const result = RuleUpgradeSpecifier.safeParse(specifierWithFields);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(specifierWithFields);
|
||||
});
|
||||
|
||||
test('rejects upgrade specifier with invalid pick_version rule_id', () => {
|
||||
const invalid = { ...validSpecifier, rule_id: 123 };
|
||||
const result = RuleUpgradeSpecifier.safeParse(invalid);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(
|
||||
`"rule_id: Expected string, received number"`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UpgradeSpecificRulesRequest', () => {
|
||||
const validRequest = {
|
||||
mode: 'SPECIFIC_RULES',
|
||||
rules: [
|
||||
{
|
||||
rule_id: 'rule-1',
|
||||
revision: 1,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
test('validates a correct upgrade specific rules request', () => {
|
||||
const result = UpgradeSpecificRulesRequest.safeParse(validRequest);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validRequest);
|
||||
});
|
||||
|
||||
test('rejects invalid mode', () => {
|
||||
const invalid = { ...validRequest, mode: 'INVALID_MODE' };
|
||||
const result = UpgradeSpecificRulesRequest.safeParse(invalid);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(
|
||||
`"mode: Invalid literal value, expected \\"SPECIFIC_RULES\\""`
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects paylaod with missing rules array', () => {
|
||||
const invalid = { ...validRequest, rules: undefined };
|
||||
const result = UpgradeSpecificRulesRequest.safeParse(invalid);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(`"rules: Required"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UpgradeAllRulesRequest', () => {
|
||||
const validRequest = {
|
||||
mode: 'ALL_RULES',
|
||||
};
|
||||
|
||||
test('validates a correct upgrade all rules request', () => {
|
||||
const result = UpgradeAllRulesRequest.safeParse(validRequest);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validRequest);
|
||||
});
|
||||
|
||||
test('allows optional pick_version', () => {
|
||||
const withPickVersion = { ...validRequest, pick_version: 'BASE' };
|
||||
const result = UpgradeAllRulesRequest.safeParse(withPickVersion);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(withPickVersion);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PerformRuleUpgradeRequestBody', () => {
|
||||
test('validates a correct upgrade specific rules request', () => {
|
||||
const validRequest = {
|
||||
mode: 'SPECIFIC_RULES',
|
||||
pick_version: 'BASE',
|
||||
rules: [
|
||||
{
|
||||
rule_id: 'rule-1',
|
||||
revision: 1,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
const result = PerformRuleUpgradeRequestBody.safeParse(validRequest);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validRequest);
|
||||
});
|
||||
|
||||
test('validates a correct upgrade all rules request', () => {
|
||||
const validRequest = {
|
||||
mode: 'ALL_RULES',
|
||||
pick_version: 'BASE',
|
||||
};
|
||||
const result = PerformRuleUpgradeRequestBody.safeParse(validRequest);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validRequest);
|
||||
});
|
||||
|
||||
test('rejects invalid mode', () => {
|
||||
const invalid = { mode: 'INVALID_MODE' };
|
||||
const result = PerformRuleUpgradeRequestBody.safeParse(invalid);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(
|
||||
`"mode: Invalid discriminator value. Expected 'ALL_RULES' | 'SPECIFIC_RULES'"`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PerformRuleUpgradeResponseBody', () => {
|
||||
const validResponse = {
|
||||
summary: {
|
||||
total: 1,
|
||||
succeeded: 1,
|
||||
skipped: 0,
|
||||
failed: 0,
|
||||
},
|
||||
results: {
|
||||
updated: [],
|
||||
skipped: [],
|
||||
},
|
||||
errors: [],
|
||||
};
|
||||
|
||||
test('validates a correct perform rule upgrade response', () => {
|
||||
const result = PerformRuleUpgradeResponseBody.safeParse(validResponse);
|
||||
expectParseSuccess(result);
|
||||
expect(result.data).toEqual(validResponse);
|
||||
});
|
||||
|
||||
test('rejects missing required fields', () => {
|
||||
const propsToDelete = Object.keys(validResponse);
|
||||
propsToDelete.forEach((deletedProp) => {
|
||||
const invalidResponse = Object.fromEntries(
|
||||
Object.entries(validResponse).filter(([key]) => key !== deletedProp)
|
||||
);
|
||||
const result = PerformRuleUpgradeResponseBody.safeParse(invalidResponse);
|
||||
expectParseError(result);
|
||||
expect(stringifyZodError(result.error)).toMatchInlineSnapshot(`"${deletedProp}: Required"`);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,94 +5,176 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { enumeration } from '@kbn/securitysolution-io-ts-types';
|
||||
import * as t from 'io-ts';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { RuleResponse } from '../../model';
|
||||
import type { AggregatedPrebuiltRuleError } from '../model';
|
||||
import {
|
||||
RuleSignatureId,
|
||||
RuleVersion,
|
||||
RuleName,
|
||||
RuleTagArray,
|
||||
RuleDescription,
|
||||
Severity,
|
||||
SeverityMapping,
|
||||
RiskScore,
|
||||
RiskScoreMapping,
|
||||
RuleReferenceArray,
|
||||
RuleFalsePositiveArray,
|
||||
ThreatArray,
|
||||
InvestigationGuide,
|
||||
SetupGuide,
|
||||
RelatedIntegrationArray,
|
||||
RequiredFieldArray,
|
||||
MaxSignals,
|
||||
BuildingBlockType,
|
||||
RuleIntervalFrom,
|
||||
RuleInterval,
|
||||
RuleExceptionList,
|
||||
RuleNameOverride,
|
||||
TimestampOverride,
|
||||
TimestampOverrideFallbackDisabled,
|
||||
TimelineTemplateId,
|
||||
TimelineTemplateTitle,
|
||||
IndexPatternArray,
|
||||
DataViewId,
|
||||
RuleQuery,
|
||||
QueryLanguage,
|
||||
RuleFilterArray,
|
||||
SavedQueryId,
|
||||
KqlQueryLanguage,
|
||||
} from '../../model/rule_schema/common_attributes.gen';
|
||||
import {
|
||||
MachineLearningJobId,
|
||||
AnomalyThreshold,
|
||||
} from '../../model/rule_schema/specific_attributes/ml_attributes.gen';
|
||||
import {
|
||||
ThreatQuery,
|
||||
ThreatMapping,
|
||||
ThreatIndex,
|
||||
ThreatFilters,
|
||||
ThreatIndicatorPath,
|
||||
} from '../../model/rule_schema/specific_attributes/threat_match_attributes.gen';
|
||||
import {
|
||||
NewTermsFields,
|
||||
HistoryWindowStart,
|
||||
} from '../../model/rule_schema/specific_attributes/new_terms_attributes.gen';
|
||||
import { RuleResponse } from '../../model/rule_schema/rule_schemas.gen';
|
||||
import { AggregatedPrebuiltRuleError } from '../model';
|
||||
|
||||
export enum PickVersionValues {
|
||||
BASE = 'BASE',
|
||||
CURRENT = 'CURRENT',
|
||||
TARGET = 'TARGET',
|
||||
}
|
||||
export type PickVersionValues = z.infer<typeof PickVersionValues>;
|
||||
export const PickVersionValues = z.enum(['BASE', 'CURRENT', 'TARGET', 'MERGED']);
|
||||
export type PickVersionValuesEnum = typeof PickVersionValues.enum;
|
||||
export const PickVersionValuesEnum = PickVersionValues.enum;
|
||||
|
||||
export const TPickVersionValues = enumeration('PickVersionValues', PickVersionValues);
|
||||
const createUpgradeFieldSchema = <T extends z.ZodType>(fieldSchema: T) =>
|
||||
z
|
||||
.discriminatedUnion('pick_version', [
|
||||
z.object({
|
||||
pick_version: PickVersionValues,
|
||||
}),
|
||||
z.object({
|
||||
pick_version: z.literal('RESOLVED'),
|
||||
resolved_value: fieldSchema,
|
||||
}),
|
||||
])
|
||||
.optional();
|
||||
|
||||
export const RuleUpgradeSpecifier = t.exact(
|
||||
t.intersection([
|
||||
t.type({
|
||||
rule_id: t.string,
|
||||
/**
|
||||
* This parameter is needed for handling race conditions with Optimistic Concurrency Control.
|
||||
* Two or more users can call upgrade/_review and upgrade/_perform endpoints concurrently.
|
||||
* Also, in general the time between these two calls can be anything.
|
||||
* The idea is to only allow the user to install a rule if the user has reviewed the exact version
|
||||
* of it that had been returned from the _review endpoint. If the version changed on the BE,
|
||||
* upgrade/_perform endpoint will return a version mismatch error for this rule.
|
||||
*/
|
||||
revision: t.number,
|
||||
/**
|
||||
* The target version to upgrade to.
|
||||
*/
|
||||
version: t.number,
|
||||
}),
|
||||
t.partial({
|
||||
pick_version: TPickVersionValues,
|
||||
}),
|
||||
])
|
||||
);
|
||||
export type RuleUpgradeSpecifier = t.TypeOf<typeof RuleUpgradeSpecifier>;
|
||||
export type RuleUpgradeSpecifier = z.infer<typeof RuleUpgradeSpecifier>;
|
||||
export const RuleUpgradeSpecifier = z.object({
|
||||
rule_id: RuleSignatureId,
|
||||
revision: z.number(),
|
||||
version: RuleVersion,
|
||||
pick_version: PickVersionValues.optional(),
|
||||
// Fields that can be customized during the upgrade workflow
|
||||
// as decided in: https://github.com/elastic/kibana/issues/186544
|
||||
fields: z
|
||||
.object({
|
||||
name: createUpgradeFieldSchema(RuleName),
|
||||
tags: createUpgradeFieldSchema(RuleTagArray),
|
||||
description: createUpgradeFieldSchema(RuleDescription),
|
||||
severity: createUpgradeFieldSchema(Severity),
|
||||
severity_mapping: createUpgradeFieldSchema(SeverityMapping),
|
||||
risk_score: createUpgradeFieldSchema(RiskScore),
|
||||
risk_score_mapping: createUpgradeFieldSchema(RiskScoreMapping),
|
||||
references: createUpgradeFieldSchema(RuleReferenceArray),
|
||||
false_positives: createUpgradeFieldSchema(RuleFalsePositiveArray),
|
||||
threat: createUpgradeFieldSchema(ThreatArray),
|
||||
note: createUpgradeFieldSchema(InvestigationGuide),
|
||||
setup: createUpgradeFieldSchema(SetupGuide),
|
||||
related_integrations: createUpgradeFieldSchema(RelatedIntegrationArray),
|
||||
required_fields: createUpgradeFieldSchema(RequiredFieldArray),
|
||||
max_signals: createUpgradeFieldSchema(MaxSignals),
|
||||
building_block_type: createUpgradeFieldSchema(BuildingBlockType),
|
||||
from: createUpgradeFieldSchema(RuleIntervalFrom),
|
||||
interval: createUpgradeFieldSchema(RuleInterval),
|
||||
exceptions_list: createUpgradeFieldSchema(RuleExceptionList),
|
||||
rule_name_override: createUpgradeFieldSchema(RuleNameOverride),
|
||||
timestamp_override: createUpgradeFieldSchema(TimestampOverride),
|
||||
timestamp_override_fallback_disabled: createUpgradeFieldSchema(
|
||||
TimestampOverrideFallbackDisabled
|
||||
),
|
||||
timeline_id: createUpgradeFieldSchema(TimelineTemplateId),
|
||||
timeline_title: createUpgradeFieldSchema(TimelineTemplateTitle),
|
||||
index: createUpgradeFieldSchema(IndexPatternArray),
|
||||
data_view_id: createUpgradeFieldSchema(DataViewId),
|
||||
query: createUpgradeFieldSchema(RuleQuery),
|
||||
language: createUpgradeFieldSchema(QueryLanguage),
|
||||
filters: createUpgradeFieldSchema(RuleFilterArray),
|
||||
saved_id: createUpgradeFieldSchema(SavedQueryId),
|
||||
machine_learning_job_id: createUpgradeFieldSchema(MachineLearningJobId),
|
||||
anomaly_threshold: createUpgradeFieldSchema(AnomalyThreshold),
|
||||
threat_query: createUpgradeFieldSchema(ThreatQuery),
|
||||
threat_mapping: createUpgradeFieldSchema(ThreatMapping),
|
||||
threat_index: createUpgradeFieldSchema(ThreatIndex),
|
||||
threat_filters: createUpgradeFieldSchema(ThreatFilters),
|
||||
threat_indicator_path: createUpgradeFieldSchema(ThreatIndicatorPath),
|
||||
threat_language: createUpgradeFieldSchema(KqlQueryLanguage),
|
||||
new_terms_fields: createUpgradeFieldSchema(NewTermsFields),
|
||||
history_window_start: createUpgradeFieldSchema(HistoryWindowStart),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type UpgradeSpecificRulesRequest = t.TypeOf<typeof UpgradeSpecificRulesRequest>;
|
||||
export const UpgradeSpecificRulesRequest = t.exact(
|
||||
t.intersection([
|
||||
t.type({
|
||||
mode: t.literal(`SPECIFIC_RULES`),
|
||||
rules: t.array(RuleUpgradeSpecifier),
|
||||
}),
|
||||
t.partial({
|
||||
pick_version: TPickVersionValues,
|
||||
}),
|
||||
])
|
||||
);
|
||||
export type UpgradeSpecificRulesRequest = z.infer<typeof UpgradeSpecificRulesRequest>;
|
||||
export const UpgradeSpecificRulesRequest = z.object({
|
||||
mode: z.literal('SPECIFIC_RULES'),
|
||||
rules: z.array(RuleUpgradeSpecifier),
|
||||
pick_version: PickVersionValues.optional(),
|
||||
});
|
||||
|
||||
export const UpgradeAllRulesRequest = t.exact(
|
||||
t.intersection([
|
||||
t.type({
|
||||
mode: t.literal(`ALL_RULES`),
|
||||
}),
|
||||
t.partial({
|
||||
pick_version: TPickVersionValues,
|
||||
}),
|
||||
])
|
||||
);
|
||||
export type UpgradeAllRulesRequest = z.infer<typeof UpgradeAllRulesRequest>;
|
||||
export const UpgradeAllRulesRequest = z.object({
|
||||
mode: z.literal('ALL_RULES'),
|
||||
pick_version: PickVersionValues.optional(),
|
||||
});
|
||||
|
||||
export const PerformRuleUpgradeRequestBody = t.union([
|
||||
export type SkipRuleUpgradeReason = z.infer<typeof SkipRuleUpgradeReason>;
|
||||
export const SkipRuleUpgradeReason = z.enum(['RULE_UP_TO_DATE']);
|
||||
export type SkipRuleUpgradeReasonEnum = typeof SkipRuleUpgradeReason.enum;
|
||||
export const SkipRuleUpgradeReasonEnum = SkipRuleUpgradeReason.enum;
|
||||
|
||||
export type SkippedRuleUpgrade = z.infer<typeof SkippedRuleUpgrade>;
|
||||
export const SkippedRuleUpgrade = z.object({
|
||||
rule_id: z.string(),
|
||||
reason: SkipRuleUpgradeReason,
|
||||
});
|
||||
|
||||
export type PerformRuleUpgradeResponseBody = z.infer<typeof PerformRuleUpgradeResponseBody>;
|
||||
export const PerformRuleUpgradeResponseBody = z.object({
|
||||
summary: z.object({
|
||||
total: z.number(),
|
||||
succeeded: z.number(),
|
||||
skipped: z.number(),
|
||||
failed: z.number(),
|
||||
}),
|
||||
results: z.object({
|
||||
updated: z.array(RuleResponse),
|
||||
skipped: z.array(SkippedRuleUpgrade),
|
||||
}),
|
||||
errors: z.array(AggregatedPrebuiltRuleError),
|
||||
});
|
||||
|
||||
export type PerformRuleUpgradeRequestBody = z.infer<typeof PerformRuleUpgradeRequestBody>;
|
||||
export const PerformRuleUpgradeRequestBody = z.discriminatedUnion('mode', [
|
||||
UpgradeAllRulesRequest,
|
||||
UpgradeSpecificRulesRequest,
|
||||
]);
|
||||
export type PerformRuleUpgradeRequestBody = t.TypeOf<typeof PerformRuleUpgradeRequestBody>;
|
||||
|
||||
export enum SkipRuleUpgradeReason {
|
||||
RULE_UP_TO_DATE = 'RULE_UP_TO_DATE',
|
||||
}
|
||||
|
||||
export interface SkippedRuleUpgrade {
|
||||
rule_id: string;
|
||||
reason: SkipRuleUpgradeReason;
|
||||
}
|
||||
|
||||
export interface PerformRuleUpgradeResponseBody {
|
||||
summary: {
|
||||
total: number;
|
||||
succeeded: number;
|
||||
skipped: number;
|
||||
failed: number;
|
||||
};
|
||||
results: {
|
||||
updated: RuleResponse[];
|
||||
skipped: SkippedRuleUpgrade[];
|
||||
};
|
||||
errors: AggregatedPrebuiltRuleError[];
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import {
|
||||
PERFORM_RULE_UPGRADE_URL,
|
||||
SkipRuleUpgradeReason,
|
||||
PerformRuleUpgradeRequestBody,
|
||||
PickVersionValues,
|
||||
PickVersionValuesEnum,
|
||||
SkipRuleUpgradeReasonEnum,
|
||||
} from '../../../../../../common/api/detection_engine/prebuilt_rules';
|
||||
import type {
|
||||
PerformRuleUpgradeResponseBody,
|
||||
|
@ -18,7 +19,6 @@ import type {
|
|||
} from '../../../../../../common/api/detection_engine/prebuilt_rules';
|
||||
import { assertUnreachable } from '../../../../../../common/utility_types';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import { buildRouteValidation } from '../../../../../utils/build_validation/route_validation';
|
||||
import type { PromisePoolError } from '../../../../../utils/promise_pool';
|
||||
import { buildSiemResponse } from '../../../routes/utils';
|
||||
import { aggregatePrebuiltRuleErrors } from '../../logic/aggregate_prebuilt_rule_errors';
|
||||
|
@ -48,7 +48,7 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) =>
|
|||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: buildRouteValidation(PerformRuleUpgradeRequestBody),
|
||||
body: buildRouteValidationWithZod(PerformRuleUpgradeRequestBody),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -63,7 +63,8 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) =>
|
|||
const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient);
|
||||
const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient);
|
||||
|
||||
const { mode, pick_version: globalPickVersion = PickVersionValues.TARGET } = request.body;
|
||||
const { mode, pick_version: globalPickVersion = PickVersionValuesEnum.TARGET } =
|
||||
request.body;
|
||||
|
||||
const fetchErrors: Array<PromisePoolError<{ rule_id: string }>> = [];
|
||||
const targetRules: PrebuiltRuleAsset[] = [];
|
||||
|
@ -105,7 +106,7 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) =>
|
|||
if (!upgradeableRuleIds.has(rule.rule_id)) {
|
||||
skippedRules.push({
|
||||
rule_id: rule.rule_id,
|
||||
reason: SkipRuleUpgradeReason.RULE_UP_TO_DATE,
|
||||
reason: SkipRuleUpgradeReasonEnum.RULE_UP_TO_DATE,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -132,7 +133,7 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) =>
|
|||
const rulePickVersion =
|
||||
versionSpecifiersMap?.get(current.rule_id)?.pick_version ?? globalPickVersion;
|
||||
switch (rulePickVersion) {
|
||||
case PickVersionValues.BASE:
|
||||
case PickVersionValuesEnum.BASE:
|
||||
const baseVersion = ruleVersionsMap.get(current.rule_id)?.base;
|
||||
if (baseVersion) {
|
||||
targetRules.push({ ...baseVersion, version: target.version });
|
||||
|
@ -143,10 +144,14 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) =>
|
|||
});
|
||||
}
|
||||
break;
|
||||
case PickVersionValues.CURRENT:
|
||||
case PickVersionValuesEnum.CURRENT:
|
||||
targetRules.push({ ...current, version: target.version });
|
||||
break;
|
||||
case PickVersionValues.TARGET:
|
||||
case PickVersionValuesEnum.TARGET:
|
||||
targetRules.push(target);
|
||||
break;
|
||||
case PickVersionValuesEnum.MERGED:
|
||||
// TODO: Implement functionality to handle MERGED
|
||||
targetRules.push(target);
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue