Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cloud Security] Rules Combo Box filters Custom component #175175

Merged
merged 14 commits into from
Jan 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * as rulesV1 from './rules/v1';
export * as rulesV2 from './rules/v2';
export * as rulesV3 from './rules/v3';
export * as rulesV4 from './rules/v4';
export * as rulesV5 from './rules/v5';

export * as benchmarkV1 from './benchmarks/v1';
export * as benchmarkV2 from './benchmarks/v2';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
* 2.0.
*/

export * from './rules/v4';
export * from './rules/v5';
export * from './benchmarks/v2';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import { schema, TypeOf } from '@kbn/config-schema';

// Since version 8.3.0

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;

export const cspBenchmarkRuleSchema = schema.object({
audit: schema.string(),
benchmark: schema.object({ name: schema.string(), version: schema.string() }),
Expand All @@ -26,5 +29,3 @@ export const cspBenchmarkRuleSchema = schema.object({
tags: schema.arrayOf(schema.string()),
version: schema.string(),
});

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import { schema, TypeOf } from '@kbn/config-schema';

// Since version 8.4.0

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;

export const cspBenchmarkRuleMetadataSchema = schema.object({
audit: schema.string(),
benchmark: schema.object({
Expand Down Expand Up @@ -34,5 +37,3 @@ export const cspBenchmarkRuleSchema = schema.object({
metadata: cspBenchmarkRuleMetadataSchema,
muted: schema.boolean(),
});

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;
19 changes: 10 additions & 9 deletions x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@
import { schema, TypeOf } from '@kbn/config-schema';
import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../../constants';

const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25;
export const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25;

// Since version 8.7.0

export type FindCspBenchmarkRuleRequest = TypeOf<typeof findCspBenchmarkRuleRequestSchema>;

export type CspBenchmarkRuleMetadata = TypeOf<typeof cspBenchmarkRuleMetadataSchema>;

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;

export type PageUrlParams = Record<'policyId' | 'packagePolicyId', string>;

export const cspBenchmarkRuleMetadataSchema = schema.object({
audit: schema.string(),
benchmark: schema.object({
Expand All @@ -37,14 +46,10 @@ export const cspBenchmarkRuleMetadataSchema = schema.object({
version: schema.string(),
});

export type CspBenchmarkRuleMetadata = TypeOf<typeof cspBenchmarkRuleMetadataSchema>;

export const cspBenchmarkRuleSchema = schema.object({
metadata: cspBenchmarkRuleMetadataSchema,
});

export type CspBenchmarkRule = TypeOf<typeof cspBenchmarkRuleSchema>;

export const findCspBenchmarkRuleRequestSchema = schema.object({
/**
* An Elasticsearch simple_query_string
Expand Down Expand Up @@ -125,13 +130,9 @@ export const findCspBenchmarkRuleRequestSchema = schema.object({
section: schema.maybe(schema.string()),
});

export type FindCspBenchmarkRuleRequest = TypeOf<typeof findCspBenchmarkRuleRequestSchema>;

export interface FindCspBenchmarkRuleResponse {
items: CspBenchmarkRule[];
total: number;
page: number;
perPage: number;
}

export type PageUrlParams = Record<'policyId' | 'packagePolicyId', string>;
33 changes: 16 additions & 17 deletions x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { schema, TypeOf } from '@kbn/config-schema';
import { BenchmarksCisId } from '../latest';
import { DEFAULT_BENCHMARK_RULES_PER_PAGE } from './v3';
export type {
cspBenchmarkRuleMetadataSchema,
CspBenchmarkRuleMetadata,
Expand All @@ -15,7 +16,19 @@ export type {
FindCspBenchmarkRuleResponse,
} from './v3';

const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25;
export type FindCspBenchmarkRuleRequest = TypeOf<typeof findCspBenchmarkRuleRequestSchema>;

export type RulesToUpdate = TypeOf<typeof rulesToUpdate>;

export type CspBenchmarkRulesBulkActionRequestSchema = TypeOf<
typeof cspBenchmarkRulesBulkActionRequestSchema
>;

export type RuleStateAttributes = TypeOf<typeof ruleStateAttributes>;

export type CspBenchmarkRulesStates = TypeOf<typeof rulesStates>;

export type CspSettings = TypeOf<typeof cspSettingsSchema>;

export const findCspBenchmarkRuleRequestSchema = schema.object({
/**
Expand Down Expand Up @@ -95,12 +108,10 @@ export const findCspBenchmarkRuleRequestSchema = schema.object({
/**
* rule section
*/
section: schema.maybe(schema.string()),
ruleNumber: schema.maybe(schema.string()),
section: schema.maybe(schema.arrayOf(schema.string())),
ruleNumber: schema.maybe(schema.arrayOf(schema.string())),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason to modify the pervious version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh good catch this wasnt supposed to be modified

});

export type FindCspBenchmarkRuleRequest = TypeOf<typeof findCspBenchmarkRuleRequestSchema>;

export interface BenchmarkRuleSelectParams {
section?: string;
ruleNumber?: string;
Expand All @@ -125,12 +136,6 @@ export const cspBenchmarkRulesBulkActionRequestSchema = schema.object({
rules: rulesToUpdate,
});

export type RulesToUpdate = TypeOf<typeof rulesToUpdate>;

export type CspBenchmarkRulesBulkActionRequestSchema = TypeOf<
typeof cspBenchmarkRulesBulkActionRequestSchema
>;

export interface CspBenchmarkRulesBulkActionResponse {
updated_benchmark_rules: CspBenchmarkRulesStates;
disabled_detection_rules?: string[];
Expand All @@ -145,18 +150,12 @@ const ruleStateAttributes = schema.object({
rule_id: schema.string(),
});

export type RuleStateAttributes = TypeOf<typeof ruleStateAttributes>;

const rulesStates = schema.recordOf(schema.string(), ruleStateAttributes);

export type CspBenchmarkRulesStates = TypeOf<typeof rulesStates>;

export const cspSettingsSchema = schema.object({
rules: rulesStates,
});

export type CspSettings = TypeOf<typeof cspSettingsSchema>;

export interface BulkActionBenchmarkRulesResponse {
updatedBenchmarkRulesStates: CspBenchmarkRulesStates;
disabledDetectionRules: string[];
Expand Down
120 changes: 120 additions & 0 deletions x-pack/plugins/cloud_security_posture/common/types/rules/v5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';
import { DEFAULT_BENCHMARK_RULES_PER_PAGE } from './v3';

export type {
cspBenchmarkRuleMetadataSchema,
CspBenchmarkRuleMetadata,
cspBenchmarkRuleSchema,
CspBenchmarkRule,
FindCspBenchmarkRuleResponse,
} from './v3';
export type {
PageUrlParams,
rulesToUpdate,
CspBenchmarkRulesBulkActionRequestSchema,
CspBenchmarkRulesBulkActionResponse,
RuleStateAttributes,
CspBenchmarkRulesStates,
cspSettingsSchema,
CspSettings,
BulkActionBenchmarkRulesResponse,
} from './v4';

export type FindCspBenchmarkRuleRequest = TypeOf<typeof findCspBenchmarkRuleRequestSchema>;

export const findCspBenchmarkRuleRequestSchema = schema.object({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you highlight what is new here that requires a new version?

Copy link
Contributor Author

@animehart animehart Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just ruleNumber and section, previously its only string because we can only filter using 1 rule number and 1 cis section. now its an array because can filter using multiple rule number and cis section

/**
* An Elasticsearch simple_query_string
*/
search: schema.maybe(schema.string()),

/**
* The page of objects to return
*/
page: schema.number({ defaultValue: 1, min: 1 }),

/**
* The number of objects to include in each page
*/
perPage: schema.number({ defaultValue: DEFAULT_BENCHMARK_RULES_PER_PAGE, min: 0 }),

/**
* Fields to retrieve from CspBenchmarkRule saved object
*/
fields: schema.maybe(schema.arrayOf(schema.string())),

/**
* The fields to perform the parsed query against.
* Valid fields are fields which mapped to 'text' in cspBenchmarkRuleSavedObjectMapping
*/
searchFields: schema.arrayOf(
schema.oneOf([schema.literal('metadata.name.text'), schema.literal('metadata.section.text')]),
{ defaultValue: ['metadata.name.text'] }
),

/**
* Sort Field
*/
sortField: schema.oneOf(
[
schema.literal('metadata.name'),
schema.literal('metadata.section'),
schema.literal('metadata.id'),
schema.literal('metadata.version'),
schema.literal('metadata.benchmark.id'),
schema.literal('metadata.benchmark.name'),
schema.literal('metadata.benchmark.posture_type'),
schema.literal('metadata.benchmark.version'),
schema.literal('metadata.benchmark.rule_number'),
],
{
defaultValue: 'metadata.benchmark.rule_number',
}
),

/**
* The order to sort by
*/
sortOrder: schema.oneOf([schema.literal('asc'), schema.literal('desc')], {
defaultValue: 'asc',
}),

/**
* benchmark id
*/
benchmarkId: schema.maybe(
schema.oneOf([
schema.literal('cis_k8s'),
schema.literal('cis_eks'),
schema.literal('cis_aws'),
schema.literal('cis_azure'),
schema.literal('cis_gcp'),
])
),

/**
* benchmark version
*/
benchmarkVersion: schema.maybe(schema.string()),

/**
* rule section
*/
section: schema.maybe(
schema.oneOf([schema.string(), schema.arrayOf(schema.string(), { minSize: 1 })])
),
ruleNumber: schema.maybe(
schema.oneOf([schema.string(), schema.arrayOf(schema.string(), { minSize: 1 })])
),
});

export interface BenchmarkRuleSelectParams {
section?: string[];
ruleNumber?: string[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
*/

import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
import { getBenchmarkFromPackagePolicy, getBenchmarkFilter, cleanupCredentials } from './helpers';
import {
getBenchmarkFromPackagePolicy,
getBenchmarkFilter,
cleanupCredentials,
getBenchmarkFilterQueryV2,
} from './helpers';

describe('test helper methods', () => {
it('get default integration type from inputs with multiple enabled types', () => {
Expand Down Expand Up @@ -70,6 +75,44 @@ describe('test helper methods', () => {
);
});

it('get benchmark filter query based on a benchmark Id, version', () => {
const typeFilter = getBenchmarkFilterQueryV2('cis_eks', '1.0.1');
expect(typeFilter).toMatch(
'csp-rule-template.attributes.metadata.benchmark.id:cis_eks AND csp-rule-template.attributes.metadata.benchmark.version:"v1.0.1"'
);
});

it('get benchmark filter query based on a benchmark Id, version and multiple sections and rule numbers', () => {
const mockSelectParams = {
section: ['section_1', 'section_2'],
ruleNumber: ['1a', '2b', '3c'],
};
const typeFilter = getBenchmarkFilterQueryV2('cis_eks', '1.0.1', mockSelectParams);
expect(typeFilter).toMatch(
'csp-rule-template.attributes.metadata.benchmark.id:cis_eks AND csp-rule-template.attributes.metadata.benchmark.version:"v1.0.1" AND (csp-rule-template.attributes.metadata.section: "section_1" OR csp-rule-template.attributes.metadata.section: "section_2") AND (csp-rule-template.attributes.metadata.benchmark.rule_number: "1a" OR csp-rule-template.attributes.metadata.benchmark.rule_number: "2b" OR csp-rule-template.attributes.metadata.benchmark.rule_number: "3c")'
);
});

it('get benchmark filter query based on a benchmark Id, version and just sections', () => {
const mockSelectParams = {
section: ['section_1', 'section_2'],
};
const typeFilter = getBenchmarkFilterQueryV2('cis_eks', '1.0.1', mockSelectParams);
expect(typeFilter).toMatch(
'csp-rule-template.attributes.metadata.benchmark.id:cis_eks AND csp-rule-template.attributes.metadata.benchmark.version:"v1.0.1" AND (csp-rule-template.attributes.metadata.section: "section_1" OR csp-rule-template.attributes.metadata.section: "section_2")'
);
});

it('get benchmark filter query based on a benchmark Id, version and just rule numbers', () => {
const mockSelectParams = {
ruleNumber: ['1a', '2b', '3c'],
};
const typeFilter = getBenchmarkFilterQueryV2('cis_eks', '1.0.1', mockSelectParams);
expect(typeFilter).toMatch(
'csp-rule-template.attributes.metadata.benchmark.id:cis_eks AND csp-rule-template.attributes.metadata.benchmark.version:"v1.0.1" AND (csp-rule-template.attributes.metadata.benchmark.rule_number: "1a" OR csp-rule-template.attributes.metadata.benchmark.rule_number: "2b" OR csp-rule-template.attributes.metadata.benchmark.rule_number: "3c")'
);
});

describe('cleanupCredentials', () => {
it('cleans unused aws credential methods, except role_arn when using assume_role', () => {
const mockPackagePolicy = createPackagePolicyMock();
Expand Down
26 changes: 26 additions & 0 deletions x-pack/plugins/cloud_security_posture/common/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,29 @@ export const getBenchmarkFilterQuery = (
: '';
return baseQuery + sectionQuery + ruleNumberQuery;
};

export const getBenchmarkFilterQueryV2 = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we get the same params and return a string, why do we need a new version?

Copy link
Contributor Author

@animehart animehart Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously we only accept string for the rule number and section filter, but now since we add ability to filter based on multiple rule number and/or section we use array instead of string

id: BenchmarkId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
id: BenchmarkId,
benchmarkId: BenchmarkId,

version?: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
version?: string,
benchmarkVersion?: string,

selectParams?: BenchmarkRuleSelectParams
): string => {
const baseQuery = `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id:${id} AND ${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.version:"v${version}"`;

let sectionQuery = '';
let ruleNumberQuery = '';
if (selectParams?.section) {
const sectionParamsArr = selectParams.section?.map(
(params) => `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.section: "${params}"`
);
sectionQuery = ' AND (' + sectionParamsArr.join(' OR ') + ')';
}
if (selectParams?.ruleNumber) {
const ruleNumbersParamsArr = selectParams.ruleNumber?.map(
(params) =>
`${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.rule_number: "${params}"`
);
ruleNumberQuery = ' AND (' + ruleNumbersParamsArr.join(' OR ') + ')';
}

return baseQuery + sectionQuery + ruleNumberQuery;
};
Loading