Skip to content

Commit

Permalink
Merge branch 'main' into internal-system-user
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzad31 committed Jun 14, 2023
2 parents 44b7fdb + a2bd9a7 commit 6cb9946
Show file tree
Hide file tree
Showing 134 changed files with 3,957 additions and 2,290 deletions.
3 changes: 2 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -920,6 +920,7 @@ x-pack/test/observability_functional @elastic/actionable-observability
/src/dev/ @elastic/kibana-operations
/src/setup_node_env/ @elastic/kibana-operations
/src/cli/keystore/ @elastic/kibana-operations
/src/cli/serve/ @elastic/kibana-operations
/.ci/es-snapshots/ @elastic/kibana-operations
/.github/workflows/ @elastic/kibana-operations
/vars/ @elastic/kibana-operations
Expand Down Expand Up @@ -947,8 +948,8 @@ x-pack/test/observability_functional @elastic/actionable-observability
# Core
/config/kibana.yml @elastic/kibana-core
/typings/ @elastic/kibana-core
/x-pack/test/saved_objects_field_count/ @elastic/kibana-core
/test/analytics @elastic/kibana-core
/x-pack/test/saved_objects_field_count/ @elastic/kibana-core
#CC# /src/core/server/csp/ @elastic/kibana-core
#CC# /src/plugins/saved_objects/ @elastic/kibana-core
#CC# /x-pack/plugins/cloud/ @elastic/kibana-core
Expand Down
2 changes: 1 addition & 1 deletion docs/developer/plugin/plugin-tooling.asciidoc
Expand Up @@ -9,7 +9,7 @@ We recommend that you kick-start your plugin by generating it with the {kib-repo

["source","shell"]
-----------
node scripts/generate_plugin my_plugin_name # replace "my_plugin_name" with your desired plugin name
node scripts/generate_plugin
-----------

[discrete]
Expand Down
Expand Up @@ -111,7 +111,7 @@ export class CoreVersionedRoute implements VersionedRoute {

if (!this.hasVersion(req) && (this.isInternal || this.router.isDev)) {
return res.badRequest({
body: `Please specify a version. Available versions: ${this.versionsToString()}`,
body: `Please specify a version via ${ELASTIC_HTTP_VERSION_HEADER} header. Available versions: ${this.versionsToString()}`,
});
}

Expand Down
Expand Up @@ -21,9 +21,9 @@ import type {
KibanaResponseFactory,
} from '@kbn/core-http-server';
import { CoreKibanaRequest } from '@kbn/core-http-router-server-internal';
import { createVersionedRouterMock } from './versioned_router.mock';
import { createVersionedRouterMock, type MockedVersionedRouter } from './versioned_router.mock';

export type RouterMock = jest.Mocked<IRouter<any>>;
export type RouterMock = jest.Mocked<IRouter<any>> & { versioned: MockedVersionedRouter };

function createRouterMock({ routerPath = '' }: { routerPath?: string } = {}): RouterMock {
return {
Expand Down
Expand Up @@ -13,7 +13,9 @@ const createMockVersionedRoute = (): VersionedRoute => {
return api;
};

export const createVersionedRouterMock = (): jest.Mocked<VersionedRouter<any>> => ({
export type MockedVersionedRouter = jest.Mocked<VersionedRouter<any>>;

export const createVersionedRouterMock = (): MockedVersionedRouter => ({
delete: jest.fn((_) => createMockVersionedRoute()),
get: jest.fn((_) => createMockVersionedRoute()),
patch: jest.fn((_) => createMockVersionedRoute()),
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-optimizer/limits.yml
Expand Up @@ -95,7 +95,7 @@ pageLoadAssetSize:
monitoring: 80000
navigation: 37269
newsfeed: 42228
observability: 100000
observability: 105500
observabilityOnboarding: 19573
observabilityShared: 52256
osquery: 107090
Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/cloud_security_posture/common/schemas/stats.ts
@@ -0,0 +1,18 @@
/*
* 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 } from '@kbn/config-schema';
import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../constants';

// this pages follows versioning interface strategy https://docs.elastic.dev/kibana-dev-docs/versioning-interfaces

export const getComplianceDashboardSchema = schema.object({
policy_template: schema.oneOf([
schema.literal(CSPM_POLICY_TEMPLATE),
schema.literal(KSPM_POLICY_TEMPLATE),
]),
});
3 changes: 3 additions & 0 deletions x-pack/plugins/cloud_security_posture/common/types.ts
Expand Up @@ -11,6 +11,7 @@ import { SUPPORTED_CLOUDBEAT_INPUTS, SUPPORTED_POLICY_TEMPLATES } from './consta
import { CspRuleTemplateMetadata } from './schemas/csp_rule_template_metadata';
import { CspRuleTemplate } from './schemas';
import { findCspRuleTemplateRequest } from './schemas/csp_rule_template_api/get_csp_rule_template';
import { getComplianceDashboardSchema } from './schemas/stats';

export type Evaluation = 'passed' | 'failed' | 'NA';

Expand Down Expand Up @@ -119,6 +120,8 @@ export interface BenchmarkResponse {

export type GetCspRuleTemplateRequest = TypeOf<typeof findCspRuleTemplateRequest>;

export type GetComplianceDashboardRequest = TypeOf<typeof getComplianceDashboardSchema>;

export interface GetCspRuleTemplateResponse {
items: CspRuleTemplate[];
total: number;
Expand Down
Expand Up @@ -28,7 +28,7 @@ export const useCspmStatsApi = (
const { http } = useKibana().services;
return useQuery(
getCspmStatsKey,
() => http.get<ComplianceDashboardData>(getStatsRoute(CSPM_POLICY_TEMPLATE)),
() => http.get<ComplianceDashboardData>(getStatsRoute(CSPM_POLICY_TEMPLATE), { version: '1' }),
options
);
};
Expand All @@ -39,7 +39,7 @@ export const useKspmStatsApi = (
const { http } = useKibana().services;
return useQuery(
getKspmStatsKey,
() => http.get<ComplianceDashboardData>(getStatsRoute(KSPM_POLICY_TEMPLATE)),
() => http.get<ComplianceDashboardData>(getStatsRoute(KSPM_POLICY_TEMPLATE), { version: '1' }),
options
);
};
Expand Up @@ -17,7 +17,10 @@ describe('compliance dashboard permissions API', () => {
const router = httpServiceMock.createRouter();

defineGetComplianceDashboardRoute(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();
Expand All @@ -33,7 +36,10 @@ describe('compliance dashboard permissions API', () => {
const router = httpServiceMock.createRouter();

defineGetComplianceDashboardRoute(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();
Expand Down
Expand Up @@ -7,16 +7,15 @@

import { transformError } from '@kbn/securitysolution-es-utils';
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
import { schema } from '@kbn/config-schema';
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
import { getComplianceDashboardSchema } from '../../../common/schemas/stats';
import { getSafePostureTypeRuntimeMapping } from '../../../common/runtime_mappings/get_safe_posture_type_runtime_mapping';
import type { PosturePolicyTemplate, ComplianceDashboardData } from '../../../common/types';
import {
CSPM_POLICY_TEMPLATE,
KSPM_POLICY_TEMPLATE,
LATEST_FINDINGS_INDEX_DEFAULT_NS,
STATS_ROUTE_PATH,
} from '../../../common/constants';
import type {
PosturePolicyTemplate,
ComplianceDashboardData,
GetComplianceDashboardRequest,
} from '../../../common/types';
import { LATEST_FINDINGS_INDEX_DEFAULT_NS, STATS_ROUTE_PATH } from '../../../common/constants';
import { getGroupedFindingsEvaluation } from './get_grouped_findings_evaluation';
import { ClusterWithoutTrend, getClusters } from './get_clusters';
import { getStats } from './get_stats';
Expand All @@ -40,82 +39,79 @@ const getClustersTrends = (clustersWithoutTrends: ClusterWithoutTrend[], trends:
const getSummaryTrend = (trends: Trends) =>
trends.map(({ timestamp, summary }) => ({ timestamp, ...summary }));

const queryParamsSchema = {
params: schema.object({
policy_template: schema.oneOf([
schema.literal(CSPM_POLICY_TEMPLATE),
schema.literal(KSPM_POLICY_TEMPLATE),
]),
}),
};

export const defineGetComplianceDashboardRoute = (router: CspRouter): void =>
router.get(
{
export const defineGetComplianceDashboardRoute = (router: CspRouter) =>
router.versioned
.get({
access: 'internal',
path: STATS_ROUTE_PATH,
validate: queryParamsSchema,
options: {
tags: ['access:cloud-security-posture-read'],
},
},
async (context, request, response) => {
const cspContext = await context.csp;

try {
const esClient = cspContext.esClient.asCurrentUser;

const { id: pitId } = await esClient.openPointInTime({
index: LATEST_FINDINGS_INDEX_DEFAULT_NS,
keep_alive: '30s',
});

const policyTemplate = request.params.policy_template as PosturePolicyTemplate;

// runtime mappings create the `safe_posture_type` field, which equals to `kspm` or `cspm` based on the value and existence of the `posture_type` field which was introduced at 8.7
// the `query` is then being passed to our getter functions to filter per posture type even for older findings before 8.7
const runtimeMappings: MappingRuntimeFields = getSafePostureTypeRuntimeMapping();
const query: QueryDslQueryContainer = {
bool: {
filter: [{ term: { safe_posture_type: policyTemplate } }],
})
.addVersion(
{
version: '1',
validate: {
request: {
params: getComplianceDashboardSchema,
},
};

const [stats, groupedFindingsEvaluation, clustersWithoutTrends, trends] = await Promise.all(
[
getStats(esClient, query, pitId, runtimeMappings),
getGroupedFindingsEvaluation(esClient, query, pitId, runtimeMappings),
getClusters(esClient, query, pitId, runtimeMappings),
getTrends(esClient, policyTemplate),
]
);

// Try closing the PIT, if it fails we can safely ignore the error since it closes itself after the keep alive
// ends. Not waiting on the promise returned from the `closePointInTime` call to avoid delaying the request
esClient.closePointInTime({ id: pitId }).catch((err) => {
cspContext.logger.warn(`Could not close PIT for stats endpoint: ${err}`);
});

const clusters = getClustersTrends(clustersWithoutTrends, trends);
const trend = getSummaryTrend(trends);

const body: ComplianceDashboardData = {
stats,
groupedFindingsEvaluation,
clusters,
trend,
};

return response.ok({
body,
});
} catch (err) {
const error = transformError(err);
cspContext.logger.error(`Error while fetching CSP stats: ${err}`);

return response.customError({
body: { message: error.message },
statusCode: error.statusCode,
});
},
},
async (context, request, response) => {
const cspContext = await context.csp;

try {
const esClient = cspContext.esClient.asCurrentUser;

const { id: pitId } = await esClient.openPointInTime({
index: LATEST_FINDINGS_INDEX_DEFAULT_NS,
keep_alive: '30s',
});

const params: GetComplianceDashboardRequest = request.params;
const policyTemplate = params.policy_template as PosturePolicyTemplate;

// runtime mappings create the `safe_posture_type` field, which equals to `kspm` or `cspm` based on the value and existence of the `posture_type` field which was introduced at 8.7
// the `query` is then being passed to our getter functions to filter per posture type even for older findings before 8.7
const runtimeMappings: MappingRuntimeFields = getSafePostureTypeRuntimeMapping();
const query: QueryDslQueryContainer = {
bool: {
filter: [{ term: { safe_posture_type: policyTemplate } }],
},
};

const [stats, groupedFindingsEvaluation, clustersWithoutTrends, trends] =
await Promise.all([
getStats(esClient, query, pitId, runtimeMappings),
getGroupedFindingsEvaluation(esClient, query, pitId, runtimeMappings),
getClusters(esClient, query, pitId, runtimeMappings),
getTrends(esClient, policyTemplate),
]);

// Try closing the PIT, if it fails we can safely ignore the error since it closes itself after the keep alive
// ends. Not waiting on the promise returned from the `closePointInTime` call to avoid delaying the request
esClient.closePointInTime({ id: pitId }).catch((err) => {
cspContext.logger.warn(`Could not close PIT for stats endpoint: ${err}`);
});

const clusters = getClustersTrends(clustersWithoutTrends, trends);
const trend = getSummaryTrend(trends);

const body: ComplianceDashboardData = {
stats,
groupedFindingsEvaluation,
clusters,
trend,
};

return response.ok({
body,
});
} catch (err) {
const error = transformError(err);
cspContext.logger.error(`Error while fetching CSP stats: ${err}`);

return response.customError({
body: { message: error.message },
statusCode: error.statusCode,
});
}
}
}
);
);

0 comments on commit 6cb9946

Please sign in to comment.