Skip to content

Commit

Permalink
[Cloud Security] Rules Combo Box filters Custom component (elastic#17…
Browse files Browse the repository at this point in the history
…5175)

## Summary

This PR is for updating the current find rule API to allow multi select
and search on section and rule numbers
it also add a custom component for the section and rule number filter
also some small UI fixes
<img width="1486" alt="Screenshot 2024-01-24 at 4 22 35 AM"
src="https://github.com/elastic/kibana/assets/8703149/c78987a0-b4a8-4dcc-b1fb-71ade0853340">
  • Loading branch information
animehart authored and lcawl committed Jan 26, 2024
1 parent ca180e8 commit 00c4646
Show file tree
Hide file tree
Showing 20 changed files with 633 additions and 82 deletions.
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>;
29 changes: 14 additions & 15 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 @@ -99,8 +112,6 @@ export const findCspBenchmarkRuleRequestSchema = schema.object({
ruleNumber: schema.maybe(schema.string()),
});

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({
/**
* 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
35 changes: 31 additions & 4 deletions x-pack/plugins/cloud_security_posture/common/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type {
RuleSection,
} from '../types_old';
import type { BenchmarkRuleSelectParams, BenchmarksCisId } from '../types/latest';
import type { BenchmarkRuleSelectParams as BenchmarkRuleSelectParamsV1 } from '../types/rules/v4';

/**
* @example
Expand Down Expand Up @@ -205,11 +206,11 @@ export const getBenchmarkApplicableTo = (benchmarkId: BenchmarksCisId) => {
};

export const getBenchmarkFilterQuery = (
id: BenchmarkId,
version?: string,
selectParams?: BenchmarkRuleSelectParams
benchmarkId: BenchmarkId,
benchmarkVersion?: string,
selectParams?: BenchmarkRuleSelectParamsV1
): 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}"`;
const baseQuery = `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id:${benchmarkId} AND ${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.version:"v${benchmarkVersion}"`;
const sectionQuery = selectParams?.section
? ` AND ${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.section: "${selectParams.section}"`
: '';
Expand All @@ -218,3 +219,29 @@ export const getBenchmarkFilterQuery = (
: '';
return baseQuery + sectionQuery + ruleNumberQuery;
};

export const getBenchmarkFilterQueryV2 = (
benchmarkId: BenchmarkId,
benchmarkVersion?: string,
selectParams?: BenchmarkRuleSelectParams
): string => {
const baseQuery = `${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.id:${benchmarkId} AND ${CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE}.attributes.metadata.benchmark.version:"v${benchmarkVersion}"`;

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

0 comments on commit 00c4646

Please sign in to comment.