mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution] Skip isCustomized calculation when the feature flag is off (#201825)
**Resolves: https://github.com/elastic/kibana/issues/201632** ## Summary When the rule customization feature flag is disabled, we should always return `isCustomized: false`, regardless of any changes introduced to a rule. This ensures that we do not accidentally mark prebuilt rules as customized in 8.16 with the feature flag off. For more details, refer to the related issue: https://github.com/elastic/kibana/issues/201632 ### Main Changes - The primary change in this PR is encapsulated in the `calculateIsCustomized` function - Other changes involve passing the feature flag to this function - Added integration tests to cover all API CRUD operations that can be performed with rules
This commit is contained in:
parent
839a927a94
commit
22911c1828
40 changed files with 425 additions and 36 deletions
|
@ -76,7 +76,8 @@ enabled:
|
|||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/serverless.config.ts
|
||||
|
|
|
@ -58,7 +58,8 @@ enabled:
|
|||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/ess.config.ts
|
||||
|
|
|
@ -92,14 +92,20 @@ export const bulkEditRules = async ({
|
|||
params: modifiedParams,
|
||||
};
|
||||
const ruleResponse = convertAlertingRuleToRuleResponse(updatedRule);
|
||||
let isCustomized = false;
|
||||
if (ruleResponse.immutable === true) {
|
||||
isCustomized = calculateIsCustomized({
|
||||
baseRule: baseVersionsMap.get(ruleResponse.rule_id),
|
||||
nextRule: ruleResponse,
|
||||
isRuleCustomizationEnabled: experimentalFeatures.prebuiltRulesCustomizationEnabled,
|
||||
});
|
||||
}
|
||||
|
||||
const ruleSource =
|
||||
ruleResponse.immutable === true
|
||||
? {
|
||||
type: 'external' as const,
|
||||
isCustomized: calculateIsCustomized(
|
||||
baseVersionsMap.get(ruleResponse.rule_id),
|
||||
ruleResponse
|
||||
),
|
||||
isCustomized,
|
||||
}
|
||||
: {
|
||||
type: 'internal' as const,
|
||||
|
|
|
@ -51,6 +51,7 @@ describe('DetectionRulesClient.createCustomRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ describe('DetectionRulesClient.createPrebuiltRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ describe('DetectionRulesClient.deleteRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ describe('DetectionRulesClient.importRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ describe('detectionRulesClient.importRules', () => {
|
|||
rulesClient: rulesClientMock.create(),
|
||||
mlAuthz: buildMlAuthz(),
|
||||
savedObjectsClient: savedObjectsClientMock.create(),
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
(checkRuleExceptionReferences as jest.Mock).mockReturnValue([[], []]);
|
||||
|
|
|
@ -50,6 +50,7 @@ describe('DetectionRulesClient.patchRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ interface DetectionRulesClientParams {
|
|||
rulesClient: RulesClient;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
mlAuthz: MlAuthz;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export const createDetectionRulesClient = ({
|
||||
|
@ -45,6 +46,7 @@ export const createDetectionRulesClient = ({
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled,
|
||||
}: DetectionRulesClientParams): IDetectionRulesClient => {
|
||||
const prebuiltRuleAssetClient = createPrebuiltRuleAssetsClient(savedObjectsClient);
|
||||
|
||||
|
@ -89,6 +91,7 @@ export const createDetectionRulesClient = ({
|
|||
prebuiltRuleAssetClient,
|
||||
mlAuthz,
|
||||
ruleUpdate,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -101,6 +104,7 @@ export const createDetectionRulesClient = ({
|
|||
prebuiltRuleAssetClient,
|
||||
mlAuthz,
|
||||
rulePatch,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -119,6 +123,7 @@ export const createDetectionRulesClient = ({
|
|||
ruleAsset,
|
||||
mlAuthz,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -131,6 +136,7 @@ export const createDetectionRulesClient = ({
|
|||
importRulePayload: args,
|
||||
mlAuthz,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
@ -50,6 +50,7 @@ describe('DetectionRulesClient.updateRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ describe('DetectionRulesClient.upgradePrebuiltRule', () => {
|
|||
rulesClient,
|
||||
mlAuthz,
|
||||
savedObjectsClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -65,6 +66,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -94,6 +96,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError(
|
||||
'event_category_override: Expected string, received number, tiebreaker_field: Expected string, received number, timestamp_field: Expected string, received number'
|
||||
|
@ -119,6 +122,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError('alert_suppression.group_by: Expected array, received string');
|
||||
});
|
||||
|
@ -134,6 +138,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -154,6 +159,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError(
|
||||
'threat_query: Expected string, received number, threat_indicator_path: Expected string, received number'
|
||||
|
@ -170,6 +176,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -190,6 +197,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError(
|
||||
"index.0: Expected string, received number, language: Invalid enum value. Expected 'kuery' | 'lucene', received 'non-language'"
|
||||
|
@ -206,6 +214,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -226,6 +235,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError(
|
||||
"index.0: Expected string, received number, language: Invalid enum value. Expected 'kuery' | 'lucene', received 'non-language'"
|
||||
|
@ -244,6 +254,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -268,6 +279,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError('threshold.value: Expected number, received string');
|
||||
});
|
||||
|
@ -285,6 +297,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -308,6 +321,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -330,6 +344,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -354,6 +369,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -376,6 +392,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -394,6 +411,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError('anomaly_threshold: Expected number, received string');
|
||||
});
|
||||
|
@ -410,6 +428,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(patchedRule).toEqual(
|
||||
|
@ -432,6 +451,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -450,6 +470,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
})
|
||||
).rejects.toThrowError('new_terms_fields: Expected array, received string');
|
||||
});
|
||||
|
@ -472,6 +493,7 @@ describe('applyRulePatch', () => {
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(patchedRule).toEqual(
|
||||
expect.objectContaining({
|
||||
|
|
|
@ -51,6 +51,7 @@ interface ApplyRulePatchProps {
|
|||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
existingRule: RuleResponse;
|
||||
rulePatch: PatchRuleRequestBody;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
|
@ -58,6 +59,7 @@ export const applyRulePatch = async ({
|
|||
rulePatch,
|
||||
existingRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
}: ApplyRulePatchProps): Promise<RuleResponse> => {
|
||||
const typeSpecificParams = patchTypeSpecificParams(rulePatch, existingRule);
|
||||
|
||||
|
@ -122,6 +124,7 @@ export const applyRulePatch = async ({
|
|||
nextRule.rule_source = await calculateRuleSource({
|
||||
rule: nextRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
return nextRule;
|
||||
|
|
|
@ -17,12 +17,14 @@ interface ApplyRuleUpdateProps {
|
|||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
existingRule: RuleResponse;
|
||||
ruleUpdate: RuleUpdateProps;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export const applyRuleUpdate = async ({
|
||||
prebuiltRuleAssetClient,
|
||||
existingRule,
|
||||
ruleUpdate,
|
||||
isRuleCustomizationEnabled,
|
||||
}: ApplyRuleUpdateProps): Promise<RuleResponse> => {
|
||||
const nextRule: RuleResponse = {
|
||||
...applyRuleDefaults(ruleUpdate),
|
||||
|
@ -46,6 +48,7 @@ export const applyRuleUpdate = async ({
|
|||
nextRule.rule_source = await calculateRuleSource({
|
||||
rule: nextRule,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
return nextRule;
|
||||
|
|
|
@ -12,10 +12,22 @@ import { calculateRuleFieldsDiff } from '../../../../../prebuilt_rules/logic/dif
|
|||
import { convertRuleToDiffable } from '../../../../../../../../common/detection_engine/prebuilt_rules/diff/convert_rule_to_diffable';
|
||||
import { convertPrebuiltRuleAssetToRuleResponse } from '../../converters/convert_prebuilt_rule_asset_to_rule_response';
|
||||
|
||||
export function calculateIsCustomized(
|
||||
baseRule: PrebuiltRuleAsset | undefined,
|
||||
nextRule: RuleResponse
|
||||
) {
|
||||
interface CalculateIsCustomizedArgs {
|
||||
baseRule: PrebuiltRuleAsset | undefined;
|
||||
nextRule: RuleResponse;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export function calculateIsCustomized({
|
||||
baseRule,
|
||||
nextRule,
|
||||
isRuleCustomizationEnabled,
|
||||
}: CalculateIsCustomizedArgs) {
|
||||
if (!isRuleCustomizationEnabled) {
|
||||
// We don't want to accidentally mark rules as customized when customization is disabled.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (baseRule == null) {
|
||||
// If the base version is missing, we consider the rule to be customized
|
||||
return true;
|
||||
|
|
|
@ -43,6 +43,7 @@ describe('calculateRuleSource', () => {
|
|||
const result = await calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
type: 'internal',
|
||||
|
@ -59,6 +60,7 @@ describe('calculateRuleSource', () => {
|
|||
const result = await calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -79,6 +81,7 @@ describe('calculateRuleSource', () => {
|
|||
const result = await calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -101,6 +104,28 @@ describe('calculateRuleSource', () => {
|
|||
const result = await calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
type: 'external',
|
||||
is_customized: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('returns is_customized false when the rule is customized but customization is disabled', async () => {
|
||||
const rule = getSampleRule();
|
||||
rule.immutable = true;
|
||||
rule.name = 'Updated name';
|
||||
|
||||
const baseRule = getSampleRuleAsset();
|
||||
prebuiltRuleAssetClient.fetchAssetsByVersion.mockResolvedValueOnce([baseRule]);
|
||||
|
||||
const result = await calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled: false,
|
||||
});
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({
|
||||
|
|
|
@ -16,11 +16,13 @@ import { calculateIsCustomized } from './calculate_is_customized';
|
|||
interface CalculateRuleSourceProps {
|
||||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
rule: RuleResponse;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export async function calculateRuleSource({
|
||||
prebuiltRuleAssetClient,
|
||||
rule,
|
||||
isRuleCustomizationEnabled,
|
||||
}: CalculateRuleSourceProps): Promise<RuleSource> {
|
||||
if (rule.immutable) {
|
||||
// This is a prebuilt rule and, despite the name, they are not immutable. So
|
||||
|
@ -33,7 +35,11 @@ export async function calculateRuleSource({
|
|||
]);
|
||||
const baseRule: PrebuiltRuleAsset | undefined = prebuiltRulesResponse.at(0);
|
||||
|
||||
const isCustomized = calculateIsCustomized(baseRule, rule);
|
||||
const isCustomized = calculateIsCustomized({
|
||||
baseRule,
|
||||
nextRule: rule,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'external',
|
||||
|
|
|
@ -26,6 +26,7 @@ interface ImportRuleOptions {
|
|||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
importRulePayload: ImportRuleArgs;
|
||||
mlAuthz: MlAuthz;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export const importRule = async ({
|
||||
|
@ -34,6 +35,7 @@ export const importRule = async ({
|
|||
importRulePayload,
|
||||
prebuiltRuleAssetClient,
|
||||
mlAuthz,
|
||||
isRuleCustomizationEnabled,
|
||||
}: ImportRuleOptions): Promise<RuleResponse> => {
|
||||
const { ruleToImport, overwriteRules, overrideFields, allowMissingConnectorSecrets } =
|
||||
importRulePayload;
|
||||
|
@ -60,6 +62,7 @@ export const importRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
existingRule,
|
||||
ruleUpdate: rule,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
// applyRuleUpdate prefers the existing rule's values for `rule_source` and `immutable`, but we want to use the importing rule's calculated values
|
||||
ruleWithUpdates = { ...ruleWithUpdates, ...overrideFields };
|
||||
|
|
|
@ -28,6 +28,7 @@ interface PatchRuleOptions {
|
|||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
rulePatch: RulePatchProps;
|
||||
mlAuthz: MlAuthz;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export const patchRule = async ({
|
||||
|
@ -36,6 +37,7 @@ export const patchRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
rulePatch,
|
||||
mlAuthz,
|
||||
isRuleCustomizationEnabled,
|
||||
}: PatchRuleOptions): Promise<RuleResponse> => {
|
||||
const { rule_id: ruleId, id } = rulePatch;
|
||||
|
||||
|
@ -58,6 +60,7 @@ export const patchRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
existingRule,
|
||||
rulePatch,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
const patchedInternalRule = await rulesClient.update({
|
||||
|
|
|
@ -27,6 +27,7 @@ interface UpdateRuleArguments {
|
|||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
ruleUpdate: RuleUpdateProps;
|
||||
mlAuthz: MlAuthz;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}
|
||||
|
||||
export const updateRule = async ({
|
||||
|
@ -35,6 +36,7 @@ export const updateRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
ruleUpdate,
|
||||
mlAuthz,
|
||||
isRuleCustomizationEnabled,
|
||||
}: UpdateRuleArguments): Promise<RuleResponse> => {
|
||||
const { rule_id: ruleId, id } = ruleUpdate;
|
||||
|
||||
|
@ -57,6 +59,7 @@ export const updateRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
existingRule,
|
||||
ruleUpdate,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
const updatedRule = await rulesClient.update({
|
||||
|
|
|
@ -25,12 +25,14 @@ export const upgradePrebuiltRule = async ({
|
|||
ruleAsset,
|
||||
mlAuthz,
|
||||
prebuiltRuleAssetClient,
|
||||
isRuleCustomizationEnabled,
|
||||
}: {
|
||||
actionsClient: ActionsClient;
|
||||
rulesClient: RulesClient;
|
||||
ruleAsset: PrebuiltRuleAsset;
|
||||
mlAuthz: MlAuthz;
|
||||
prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}): Promise<RuleResponse> => {
|
||||
await validateMlAuth(mlAuthz, ruleAsset.type);
|
||||
|
||||
|
@ -73,6 +75,7 @@ export const upgradePrebuiltRule = async ({
|
|||
prebuiltRuleAssetClient,
|
||||
existingRule,
|
||||
ruleUpdate: ruleAsset,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
const updatedInternalRule = await rulesClient.update({
|
||||
|
|
|
@ -15,6 +15,7 @@ describe('calculateRuleSourceForImport', () => {
|
|||
rule: getRulesSchemaMock(),
|
||||
prebuiltRuleAssetsByRuleId: {},
|
||||
isKnownPrebuiltRule: false,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -33,6 +34,7 @@ describe('calculateRuleSourceForImport', () => {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId: {},
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -53,6 +55,7 @@ describe('calculateRuleSourceForImport', () => {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId,
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -73,6 +76,7 @@ describe('calculateRuleSourceForImport', () => {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId,
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
|
|
@ -28,10 +28,12 @@ export const calculateRuleSourceForImport = ({
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId,
|
||||
isKnownPrebuiltRule,
|
||||
isRuleCustomizationEnabled,
|
||||
}: {
|
||||
rule: ValidatedRuleToImport;
|
||||
prebuiltRuleAssetsByRuleId: Record<string, PrebuiltRuleAsset>;
|
||||
isKnownPrebuiltRule: boolean;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}): { ruleSource: RuleSource; immutable: boolean } => {
|
||||
const assetWithMatchingVersion = prebuiltRuleAssetsByRuleId[rule.rule_id];
|
||||
// We convert here so that RuleSource calculation can
|
||||
|
@ -43,6 +45,7 @@ export const calculateRuleSourceForImport = ({
|
|||
rule: ruleResponseForImport,
|
||||
assetWithMatchingVersion,
|
||||
isKnownPrebuiltRule,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -15,6 +15,7 @@ describe('calculateRuleSourceFromAsset', () => {
|
|||
rule: getRulesSchemaMock(),
|
||||
assetWithMatchingVersion: undefined,
|
||||
isKnownPrebuiltRule: false,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -28,6 +29,7 @@ describe('calculateRuleSourceFromAsset', () => {
|
|||
rule: ruleToImport,
|
||||
assetWithMatchingVersion: undefined,
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -47,6 +49,7 @@ describe('calculateRuleSourceFromAsset', () => {
|
|||
// no other overwrites -> no differences
|
||||
}),
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
@ -65,6 +68,7 @@ describe('calculateRuleSourceFromAsset', () => {
|
|||
name: 'Customized name', // mock a customization
|
||||
}),
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
|
|
@ -24,10 +24,12 @@ export const calculateRuleSourceFromAsset = ({
|
|||
rule,
|
||||
assetWithMatchingVersion,
|
||||
isKnownPrebuiltRule,
|
||||
isRuleCustomizationEnabled,
|
||||
}: {
|
||||
rule: RuleResponse;
|
||||
assetWithMatchingVersion: PrebuiltRuleAsset | undefined;
|
||||
isKnownPrebuiltRule: boolean;
|
||||
isRuleCustomizationEnabled: boolean;
|
||||
}): RuleSource => {
|
||||
if (!isKnownPrebuiltRule) {
|
||||
return {
|
||||
|
@ -38,11 +40,15 @@ export const calculateRuleSourceFromAsset = ({
|
|||
if (assetWithMatchingVersion == null) {
|
||||
return {
|
||||
type: 'external',
|
||||
is_customized: true,
|
||||
is_customized: isRuleCustomizationEnabled ? true : false,
|
||||
};
|
||||
}
|
||||
|
||||
const isCustomized = calculateIsCustomized(assetWithMatchingVersion, rule);
|
||||
const isCustomized = calculateIsCustomized({
|
||||
baseRule: assetWithMatchingVersion,
|
||||
nextRule: rule,
|
||||
isRuleCustomizationEnabled,
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'external',
|
||||
|
|
|
@ -138,6 +138,7 @@ describe('ruleSourceImporter', () => {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId: { 'rule-1': expect.objectContaining({ rule_id: 'rule-1' }) },
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -166,6 +167,7 @@ describe('ruleSourceImporter', () => {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId: { 'rule-1': expect.objectContaining({ rule_id: 'rule-1' }) },
|
||||
isKnownPrebuiltRule: true,
|
||||
isRuleCustomizationEnabled: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -143,6 +143,8 @@ export class RuleSourceImporter implements IRuleSourceImporter {
|
|||
rule,
|
||||
prebuiltRuleAssetsByRuleId: this.matchingAssetsByRuleId,
|
||||
isKnownPrebuiltRule: this.availableRuleAssetIds.has(rule.rule_id),
|
||||
isRuleCustomizationEnabled:
|
||||
this.config.experimentalFeatures.prebuiltRulesCustomizationEnabled,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ export class RequestContextFactory implements IRequestContextFactory {
|
|||
actionsClient,
|
||||
savedObjectsClient: coreContext.savedObjects.client,
|
||||
mlAuthz,
|
||||
isRuleCustomizationEnabled: config.experimentalFeatures.prebuiltRulesCustomizationEnabled,
|
||||
});
|
||||
}),
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 { FtrConfigProviderContext } from '@kbn/test';
|
||||
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const functionalConfig = await readConfigFile(
|
||||
require.resolve('../../../../../../../config/ess/config.base.trial')
|
||||
);
|
||||
|
||||
const testConfig = {
|
||||
...functionalConfig.getAll(),
|
||||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName:
|
||||
'Rules Management - Prebuilt Rule Customization Disabled Integration Tests - ESS Env',
|
||||
},
|
||||
};
|
||||
|
||||
return testConfig;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../../../../../../../config/serverless/config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName:
|
||||
'Rules Management - Prebuilt Rule Customization Disabled Integration Tests - Serverless Env',
|
||||
},
|
||||
kbnTestServerArgs: [],
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../../../../ftr_provider_context';
|
||||
|
||||
export default ({ loadTestFile }: FtrProviderContext): void => {
|
||||
describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization Disabled', function () {
|
||||
loadTestFile(require.resolve('./is_customized_calculation'));
|
||||
});
|
||||
};
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* 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 expect from 'expect';
|
||||
import {
|
||||
BulkActionEditTypeEnum,
|
||||
BulkActionTypeEnum,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { deleteAllRules } from '../../../../../../../common/utils/security_solution';
|
||||
import { FtrProviderContext } from '../../../../../../ftr_provider_context';
|
||||
import {
|
||||
deleteAllPrebuiltRuleAssets,
|
||||
createRuleAssetSavedObject,
|
||||
createPrebuiltRuleAssetSavedObjects,
|
||||
installPrebuiltRules,
|
||||
} from '../../../../utils';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const securitySolutionApi = getService('securitySolutionApi');
|
||||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
|
||||
const ruleAsset = createRuleAssetSavedObject({
|
||||
rule_id: 'test-rule-id',
|
||||
});
|
||||
|
||||
describe('@ess @serverless @skipInServerlessMKI is_customized calculation with disabled customization', () => {
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
});
|
||||
|
||||
it('should set is_customized to "false" on prebuilt rule PATCH', async () => {
|
||||
await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]);
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
const { body: findResult } = await securitySolutionApi
|
||||
.findRules({
|
||||
query: {
|
||||
per_page: 1,
|
||||
filter: `alert.attributes.params.immutable: true`,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
const prebuiltRule = findResult.data[0];
|
||||
|
||||
// Check that the rule has been created and is not customized
|
||||
expect(prebuiltRule).not.toBeNull();
|
||||
expect(prebuiltRule.rule_source.is_customized).toEqual(false);
|
||||
|
||||
const { body } = await securitySolutionApi
|
||||
.patchRule({
|
||||
body: {
|
||||
rule_id: 'test-rule-id',
|
||||
name: 'some other rule name',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
// Check that the rule name has been updated and the rule is still not customized
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
name: 'some other rule name',
|
||||
})
|
||||
);
|
||||
expect(body.rule_source.is_customized).toEqual(false);
|
||||
});
|
||||
|
||||
it('should set is_customized to "false" on prebuilt rule UPDATE', async () => {
|
||||
await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]);
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
const { body: findResult } = await securitySolutionApi
|
||||
.findRules({
|
||||
query: {
|
||||
per_page: 1,
|
||||
filter: `alert.attributes.params.immutable: true`,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
const prebuiltRule = findResult.data[0];
|
||||
|
||||
// Check that the rule has been created and is not customized
|
||||
expect(prebuiltRule).not.toBeNull();
|
||||
expect(prebuiltRule.rule_source.is_customized).toEqual(false);
|
||||
|
||||
const { body } = await securitySolutionApi
|
||||
.updateRule({
|
||||
body: {
|
||||
...prebuiltRule,
|
||||
id: undefined, // id together with rule_id is not allowed
|
||||
name: 'some other rule name',
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
// Check that the rule name has been updated and the rule is still not customized
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
name: 'some other rule name',
|
||||
})
|
||||
);
|
||||
expect(body.rule_source.is_customized).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not allow prebuilt rule customization on import', async () => {
|
||||
await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]);
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
const { body: findResult } = await securitySolutionApi
|
||||
.findRules({
|
||||
query: {
|
||||
per_page: 1,
|
||||
filter: `alert.attributes.params.immutable: true`,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
const prebuiltRule = findResult.data[0];
|
||||
|
||||
// Check that the rule has been created and is not customized
|
||||
expect(prebuiltRule).not.toBeNull();
|
||||
expect(prebuiltRule.rule_source.is_customized).toEqual(false);
|
||||
|
||||
const ruleBuffer = Buffer.from(
|
||||
JSON.stringify({
|
||||
...prebuiltRule,
|
||||
name: 'some other rule name',
|
||||
})
|
||||
);
|
||||
|
||||
const { body } = await securitySolutionApi
|
||||
.importRules({ query: {} })
|
||||
.attach('file', ruleBuffer, 'rules.ndjson')
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200);
|
||||
|
||||
expect(body).toMatchObject({
|
||||
rules_count: 1,
|
||||
success: false,
|
||||
success_count: 0,
|
||||
errors: [
|
||||
{
|
||||
error: {
|
||||
message: expect.stringContaining('Importing prebuilt rules is not supported'),
|
||||
},
|
||||
rule_id: 'test-rule-id',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Check that the rule has not been customized
|
||||
const { body: importedRule } = await securitySolutionApi.readRule({
|
||||
query: { rule_id: prebuiltRule.rule_id },
|
||||
});
|
||||
expect(importedRule.rule_source.is_customized).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not allow rule customization on bulk edit', async () => {
|
||||
await createPrebuiltRuleAssetSavedObjects(es, [ruleAsset]);
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
const { body: findResult } = await securitySolutionApi
|
||||
.findRules({
|
||||
query: {
|
||||
per_page: 1,
|
||||
filter: `alert.attributes.params.immutable: true`,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
const prebuiltRule = findResult.data[0];
|
||||
|
||||
// Check that the rule has been created and is not customized
|
||||
expect(prebuiltRule).not.toBeNull();
|
||||
expect(prebuiltRule.rule_source.is_customized).toEqual(false);
|
||||
|
||||
const { body: bulkResult } = await securitySolutionApi
|
||||
.performRulesBulkAction({
|
||||
query: {},
|
||||
body: {
|
||||
ids: [prebuiltRule.id],
|
||||
action: BulkActionTypeEnum.edit,
|
||||
[BulkActionTypeEnum.edit]: [
|
||||
{
|
||||
type: BulkActionEditTypeEnum.add_tags,
|
||||
value: ['test'],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
.expect(500);
|
||||
|
||||
expect(bulkResult).toMatchObject(
|
||||
expect.objectContaining({
|
||||
attributes: expect.objectContaining({
|
||||
summary: {
|
||||
failed: 1,
|
||||
skipped: 0,
|
||||
succeeded: 0,
|
||||
total: 1,
|
||||
},
|
||||
errors: [expect.objectContaining({ message: "Elastic rule can't be edited" })],
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
// Check that the rule has not been customized
|
||||
const { body: ruleAfterUpdate } = await securitySolutionApi.readRule({
|
||||
query: { rule_id: prebuiltRule.rule_id },
|
||||
});
|
||||
expect(ruleAfterUpdate.rule_source.is_customized).toEqual(false);
|
||||
});
|
||||
});
|
||||
};
|
|
@ -17,7 +17,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName:
|
||||
'Rules Management - Prebuilt Rule Customization Integration Tests - ESS Env - Trial License',
|
||||
'Rules Management - Prebuilt Rule Customization Enabled Integration Tests - ESS Env',
|
||||
},
|
||||
};
|
||||
testConfig.kbnTestServer.serverArgs = testConfig.kbnTestServer.serverArgs.map((arg: string) => {
|
|
@ -11,7 +11,7 @@ export default createTestConfig({
|
|||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName:
|
||||
'Rules Management - Prebuilt Rule Customization Integration Tests - Serverless Env - Complete Tier',
|
||||
'Rules Management - Prebuilt Rule Customization Enabled Integration Tests - Serverless Env',
|
||||
},
|
||||
kbnTestServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
|
|
@ -8,7 +8,7 @@
|
|||
import { FtrProviderContext } from '../../../../../../ftr_provider_context';
|
||||
|
||||
export default ({ loadTestFile }: FtrProviderContext): void => {
|
||||
describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization', function () {
|
||||
describe('Rules Management - Prebuilt Rules - Prebuilt Rule Customization Enabled', function () {
|
||||
loadTestFile(require.resolve('./is_customized_calculation'));
|
||||
loadTestFile(require.resolve('./import_rules'));
|
||||
loadTestFile(require.resolve('./rules_export'));
|
|
@ -7,25 +7,21 @@
|
|||
|
||||
import expect from 'expect';
|
||||
|
||||
import { createRule, deleteAllRules } from '../../../../../../common/utils/security_solution';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
import {
|
||||
createHistoricalPrebuiltRuleAssetSavedObjects,
|
||||
createRuleAssetSavedObject,
|
||||
deleteAllPrebuiltRuleAssets,
|
||||
getCustomQueryRuleParams,
|
||||
getSimpleRule,
|
||||
getSimpleRuleOutput,
|
||||
getCustomQueryRuleParams,
|
||||
getSimpleRuleOutputWithoutRuleId,
|
||||
installPrebuiltRules,
|
||||
removeServerGeneratedProperties,
|
||||
removeServerGeneratedPropertiesIncludingRuleId,
|
||||
getSimpleRuleOutputWithoutRuleId,
|
||||
updateUsername,
|
||||
createHistoricalPrebuiltRuleAssetSavedObjects,
|
||||
installPrebuiltRules,
|
||||
createRuleAssetSavedObject,
|
||||
} from '../../../utils';
|
||||
import {
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
createRule,
|
||||
deleteAllAlerts,
|
||||
} from '../../../../../../common/utils/security_solution';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
|
@ -37,12 +33,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('@ess @serverless @serverlessQA patch_rules', () => {
|
||||
describe('patch rules', () => {
|
||||
beforeEach(async () => {
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
});
|
||||
|
||||
it('should patch a single rule property of name using a rule_id', async () => {
|
||||
|
@ -262,10 +254,6 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
describe('max signals', () => {
|
||||
afterEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
it('does NOT patch a rule when max_signals is less than 1', async () => {
|
||||
await securitySolutionApi.createRule({
|
||||
body: getCustomQueryRuleParams({ rule_id: 'rule-1', max_signals: 100 }),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue