[Cloud Security] update benchmark api (#158800)

This commit is contained in:
Ido Cohen 2023-07-02 12:53:13 +03:00 committed by GitHub
parent 6c710308b5
commit a5d4d9d948
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 67 deletions

View file

@ -9,10 +9,15 @@ import { PostureTypes, VulnSeverity } from './types';
export const STATUS_ROUTE_PATH = '/internal/cloud_security_posture/status';
export const STATS_ROUTE_PATH = '/internal/cloud_security_posture/stats/{policy_template}';
export const VULNERABILITIES_DASHBOARD_ROUTE_PATH =
'/internal/cloud_security_posture/vulnerabilities_dashboard';
export const BENCHMARKS_ROUTE_PATH = '/internal/cloud_security_posture/benchmarks';
export const BENCHMARKS_API_CURRENT_VERSION = '1';
export const FIND_CSP_RULE_TEMPLATE_ROUTE_PATH = '/internal/cloud_security_posture/rules/_find';
export const FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION = '1';
export const CLOUD_SECURITY_POSTURE_PACKAGE_NAME = 'cloud_security_posture';
// TODO: REMOVE CSP_LATEST_FINDINGS_DATA_VIEW and replace it with LATEST_FINDINGS_INDEX_PATTERN

View file

@ -56,7 +56,7 @@ export const benchmarksQueryParamsSchema = schema.object({
/**
* Benchmark filter
*/
benchmark_name: schema.maybe(schema.string()),
package_policy_name: schema.maybe(schema.string()),
});
export type BenchmarksQueryParams = TypeOf<typeof benchmarksQueryParamsSchema>;

View file

@ -111,7 +111,7 @@ export type PostureInput = typeof SUPPORTED_CLOUDBEAT_INPUTS[number];
export type CloudSecurityPolicyTemplate = typeof SUPPORTED_POLICY_TEMPLATES[number];
export type PosturePolicyTemplate = Extract<CloudSecurityPolicyTemplate, 'kspm' | 'cspm'>;
export interface BenchmarkResponse {
export interface GetBenchmarkResponse {
items: Benchmark[];
total: number;
page: number;

View file

@ -7,7 +7,7 @@
import { useQuery } from '@tanstack/react-query';
import type { ListResult } from '@kbn/fleet-plugin/common';
import { BENCHMARKS_ROUTE_PATH } from '../../../common/constants';
import { BENCHMARKS_API_CURRENT_VERSION, BENCHMARKS_ROUTE_PATH } from '../../../common/constants';
import type { BenchmarksQueryParams } from '../../../common/schemas/benchmark';
import { useKibana } from '../../common/hooks/use_kibana';
import type { Benchmark } from '../../../common/types';
@ -31,7 +31,7 @@ export const useCspBenchmarkIntegrations = ({
}: UseCspBenchmarkIntegrationsProps) => {
const { http } = useKibana().services;
const query: BenchmarksQueryParams = {
benchmark_name: name,
package_policy_name: name,
per_page: perPage,
page,
sort_field: sortField,
@ -40,7 +40,11 @@ export const useCspBenchmarkIntegrations = ({
return useQuery(
[QUERY_KEY, query],
() => http.get<ListResult<Benchmark>>(BENCHMARKS_ROUTE_PATH, { query }),
() =>
http.get<ListResult<Benchmark>>(BENCHMARKS_ROUTE_PATH, {
query,
version: BENCHMARKS_API_CURRENT_VERSION,
}),
{ keepPreviousData: true }
);
};

View file

@ -10,6 +10,7 @@ import { useKibana } from '../../common/hooks/use_kibana';
import {
CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE,
FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION,
FIND_CSP_RULE_TEMPLATE_ROUTE_PATH,
} from '../../../common/constants';
@ -27,7 +28,7 @@ export const useFindCspRuleTemplates = (
() => {
return http.get<GetCspRuleTemplateResponse>(FIND_CSP_RULE_TEMPLATE_ROUTE_PATH, {
query: { packagePolicyId, page, perPage },
version: '1',
version: FIND_CSP_RULE_TEMPLATE_API_CURRENT_VERSION,
});
}
);

View file

@ -105,8 +105,8 @@ export const getCspPackagePolicies = async (
? input.enabled
: input.enabled && input.policy_template === postureType
).length > 0 &&
(!queryParams.benchmark_name ||
pkg.name.toLowerCase().includes(queryParams.benchmark_name.toLowerCase()))
(!queryParams.package_policy_name ||
pkg.name.toLowerCase().includes(queryParams.package_policy_name.toLowerCase()))
);
const page = queryParams?.page ?? 1;

View file

@ -27,7 +27,7 @@ describe('benchmarks API', () => {
defineGetBenchmarksRoute(router);
const [config] = router.get.mock.calls[0];
const [config] = router.versioned.get.mock.calls[0];
expect(config.path).toEqual('/internal/cloud_security_posture/benchmarks');
});
@ -37,7 +37,9 @@ describe('benchmarks API', () => {
defineGetBenchmarksRoute(router);
const [_, handler] = router.get.mock.calls[0];
const versionedRouter = router.versioned.get.mock.results[0].value;
const handler = versionedRouter.addVersion.mock.calls[0][1];
const mockContext = createCspRequestHandlerContextMock();
const mockResponse = httpServerMock.createResponseFactory();
@ -54,7 +56,9 @@ describe('benchmarks API', () => {
defineGetBenchmarksRoute(router);
const [_, handler] = router.get.mock.calls[0];
const versionedRouter = router.versioned.get.mock.results[0].value;
const handler = versionedRouter.addVersion.mock.calls[0][1];
const mockContext = createCspRequestHandlerContextMock();
mockContext.fleet.authz.fleet.all = false;
@ -78,15 +82,15 @@ describe('benchmarks API', () => {
});
});
it('expect to find benchmark_name', async () => {
it('expect to find package_policy_name', async () => {
const validatedQuery = benchmarksQueryParamsSchema.validate({
benchmark_name: 'my_cis_benchmark',
package_policy_name: 'my_cis_benchmark',
});
expect(validatedQuery).toMatchObject({
page: 1,
per_page: DEFAULT_BENCHMARKS_PER_PAGE,
benchmark_name: 'my_cis_benchmark',
package_policy_name: 'my_cis_benchmark',
});
});

View file

@ -15,7 +15,7 @@ import {
POSTURE_TYPE_ALL,
} from '../../../common/constants';
import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark';
import type { Benchmark } from '../../../common/types';
import type { Benchmark, GetBenchmarkResponse } from '../../../common/types';
import {
getBenchmarkFromPackagePolicy,
getBenchmarkTypeFilter,
@ -84,63 +84,74 @@ const createBenchmarks = (
);
};
export const defineGetBenchmarksRoute = (router: CspRouter): void =>
router.get(
{
export const defineGetBenchmarksRoute = (router: CspRouter) =>
router.versioned
.get({
access: 'internal',
path: BENCHMARKS_ROUTE_PATH,
validate: { query: benchmarksQueryParamsSchema },
options: {
tags: ['access:cloud-security-posture-read'],
},
},
async (context, request, response) => {
if (!(await context.fleet).authz.fleet.all) {
return response.forbidden();
}
})
.addVersion(
{
version: '1',
validate: {
request: {
query: benchmarksQueryParamsSchema,
},
},
},
async (context, request, response) => {
if (!(await context.fleet).authz.fleet.all) {
return response.forbidden();
}
const cspContext = await context.csp;
const cspContext = await context.csp;
try {
const cspPackagePolicies = await getCspPackagePolicies(
cspContext.soClient,
cspContext.packagePolicyService,
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
request.query,
POSTURE_TYPE_ALL
);
try {
const cspPackagePolicies = await getCspPackagePolicies(
cspContext.soClient,
cspContext.packagePolicyService,
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
request.query,
POSTURE_TYPE_ALL
);
const agentPolicies = await getCspAgentPolicies(
cspContext.soClient,
cspPackagePolicies.items,
cspContext.agentPolicyService
);
const agentPolicies = await getCspAgentPolicies(
cspContext.soClient,
cspPackagePolicies.items,
cspContext.agentPolicyService
);
const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies(
cspContext.agentService,
agentPolicies,
cspContext.logger
);
const agentStatusesByAgentPolicyId = await getAgentStatusesByAgentPolicies(
cspContext.agentService,
agentPolicies,
cspContext.logger
);
const benchmarks = await createBenchmarks(
cspContext.soClient,
agentPolicies,
agentStatusesByAgentPolicyId,
cspPackagePolicies.items
);
const benchmarks = await createBenchmarks(
cspContext.soClient,
agentPolicies,
agentStatusesByAgentPolicyId,
cspPackagePolicies.items
);
return response.ok({
body: {
const getBenchmarkResponse: GetBenchmarkResponse = {
...cspPackagePolicies,
items: benchmarks,
},
});
} catch (err) {
const error = transformError(err);
cspContext.logger.error(`Failed to fetch benchmarks ${err}`);
return response.customError({
body: { message: error.message },
statusCode: error.statusCode,
});
};
return response.ok({
body: getBenchmarkResponse,
});
} catch (err) {
const error = transformError(err);
cspContext.logger.error(`Failed to fetch benchmarks ${err}`);
return response.customError({
body: { message: error.message },
statusCode: error.statusCode,
});
}
}
}
);
);

View file

@ -5,8 +5,9 @@
* 2.0.
*/
import expect from '@kbn/expect';
import type { BenchmarkResponse } from '@kbn/cloud-security-posture-plugin/common/types';
import type { GetBenchmarkResponse } from '@kbn/cloud-security-posture-plugin/common/types';
import type { SuperTest, Test } from 'supertest';
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
@ -91,8 +92,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it(`Should return non-empty array filled with Rules if user has CSP integrations`, async () => {
const { body: res }: { body: BenchmarkResponse } = await supertest
const { body: res }: { body: GetBenchmarkResponse } = await supertest
.get(`/internal/cloud_security_posture/benchmarks`)
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set('kbn-xsrf', 'xxxx')
.expect(200);
@ -101,8 +103,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it(`Should return array size 2 when we set per page to be only 2 (total element is still 3)`, async () => {
const { body: res }: { body: BenchmarkResponse } = await supertest
const { body: res }: { body: GetBenchmarkResponse } = await supertest
.get(`/internal/cloud_security_posture/benchmarks?per_page=2`)
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set('kbn-xsrf', 'xxxx')
.expect(200);
@ -111,8 +114,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it(`Should return array size 2 when we set per page to be only 2 (total element is still 3)`, async () => {
const { body: res }: { body: BenchmarkResponse } = await supertest
const { body: res }: { body: GetBenchmarkResponse } = await supertest
.get(`/internal/cloud_security_posture/benchmarks?per_page=2&page=2`)
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set('kbn-xsrf', 'xxxx')
.expect(200);
@ -121,8 +125,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it(`Should return empty array when we set page to be above the last page number`, async () => {
const { body: res }: { body: BenchmarkResponse } = await supertest
const { body: res }: { body: GetBenchmarkResponse } = await supertest
.get(`/internal/cloud_security_posture/benchmarks?per_page=2&page=3`)
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set('kbn-xsrf', 'xxxx')
.expect(200);