mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 10:23:14 -04:00
[Cloud Posture] add route handler context (#134774)
This commit is contained in:
parent
a0df571b2c
commit
f8bc451984
17 changed files with 233 additions and 380 deletions
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 {
|
|
||||||
AgentService,
|
|
||||||
PackageService,
|
|
||||||
AgentPolicyServiceInterface,
|
|
||||||
PackagePolicyServiceInterface,
|
|
||||||
} from '@kbn/fleet-plugin/server';
|
|
||||||
|
|
||||||
export interface CspAppServiceDependencies {
|
|
||||||
packageService: PackageService;
|
|
||||||
agentService: AgentService;
|
|
||||||
packagePolicyService: PackagePolicyServiceInterface;
|
|
||||||
agentPolicyService: AgentPolicyServiceInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CspAppService {
|
|
||||||
public agentService: AgentService | undefined;
|
|
||||||
public packageService: PackageService | undefined;
|
|
||||||
public packagePolicyService: PackagePolicyServiceInterface | undefined;
|
|
||||||
public agentPolicyService: AgentPolicyServiceInterface | undefined;
|
|
||||||
|
|
||||||
public start(dependencies: CspAppServiceDependencies) {
|
|
||||||
this.agentService = dependencies.agentService;
|
|
||||||
this.packageService = dependencies.packageService;
|
|
||||||
this.packagePolicyService = dependencies.packagePolicyService;
|
|
||||||
this.agentPolicyService = dependencies.agentPolicyService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public stop() {}
|
|
||||||
}
|
|
|
@ -5,13 +5,12 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ElasticsearchClient } from '@kbn/core/server';
|
import { ElasticsearchClient, type Logger } from '@kbn/core/server';
|
||||||
import { CspAppContext } from '../plugin';
|
|
||||||
import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../common/constants';
|
import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../common/constants';
|
||||||
|
|
||||||
export const isLatestFindingsIndexExists = async (
|
export const isLatestFindingsIndexExists = async (
|
||||||
esClient: ElasticsearchClient,
|
esClient: ElasticsearchClient,
|
||||||
logger: CspAppContext['logger']
|
logger: Logger
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const queryResult = await esClient.search({
|
const queryResult = await esClient.search({
|
||||||
|
|
36
x-pack/plugins/cloud_security_posture/server/mocks.ts
Normal file
36
x-pack/plugins/cloud_security_posture/server/mocks.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
import { coreMock } from '@kbn/core/server/mocks';
|
||||||
|
import {
|
||||||
|
createFleetRequestHandlerContextMock,
|
||||||
|
createMockAgentService,
|
||||||
|
createMockAgentPolicyService,
|
||||||
|
createPackagePolicyServiceMock,
|
||||||
|
createMockPackageService,
|
||||||
|
} from '@kbn/fleet-plugin/server/mocks';
|
||||||
|
import { mockAuthenticatedUser } from '@kbn/security-plugin/common/model/authenticated_user.mock';
|
||||||
|
|
||||||
|
export const createCspRequestHandlerContextMock = () => {
|
||||||
|
const coreMockRequestContext = coreMock.createRequestHandlerContext();
|
||||||
|
|
||||||
|
return {
|
||||||
|
core: coreMockRequestContext,
|
||||||
|
fleet: createFleetRequestHandlerContextMock(),
|
||||||
|
csp: {
|
||||||
|
user: mockAuthenticatedUser(),
|
||||||
|
logger: loggingSystemMock.createLogger(),
|
||||||
|
esClient: coreMockRequestContext.elasticsearch.client,
|
||||||
|
soClient: coreMockRequestContext.savedObjects.client,
|
||||||
|
agentPolicyService: createMockAgentPolicyService(),
|
||||||
|
agentService: createMockAgentService(),
|
||||||
|
packagePolicyService: createPackagePolicyServiceMock(),
|
||||||
|
packageService: createMockPackageService(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
|
@ -20,17 +20,14 @@ import {
|
||||||
TaskManagerSetupContract,
|
TaskManagerSetupContract,
|
||||||
TaskManagerStartContract,
|
TaskManagerStartContract,
|
||||||
} from '@kbn/task-manager-plugin/server';
|
} from '@kbn/task-manager-plugin/server';
|
||||||
import type { SecurityPluginSetup } from '@kbn/security-plugin/server';
|
|
||||||
import { CspAppService } from './lib/csp_app_services';
|
|
||||||
import type {
|
import type {
|
||||||
CspServerPluginSetup,
|
CspServerPluginSetup,
|
||||||
CspServerPluginStart,
|
CspServerPluginStart,
|
||||||
CspServerPluginSetupDeps,
|
CspServerPluginSetupDeps,
|
||||||
CspServerPluginStartDeps,
|
CspServerPluginStartDeps,
|
||||||
CspRequestHandlerContext,
|
|
||||||
CspServerPluginStartServices,
|
CspServerPluginStartServices,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { defineRoutes } from './routes';
|
import { setupRoutes } from './routes/setup_routes';
|
||||||
import { setupSavedObjects } from './saved_objects';
|
import { setupSavedObjects } from './saved_objects';
|
||||||
import { initializeCspIndices } from './create_indices/create_indices';
|
import { initializeCspIndices } from './create_indices/create_indices';
|
||||||
import { initializeCspTransforms } from './create_transforms/create_transforms';
|
import { initializeCspTransforms } from './create_transforms/create_transforms';
|
||||||
|
@ -48,12 +45,6 @@ import {
|
||||||
setupFindingsStatsTask,
|
setupFindingsStatsTask,
|
||||||
} from './tasks/findings_stats_task';
|
} from './tasks/findings_stats_task';
|
||||||
|
|
||||||
export interface CspAppContext {
|
|
||||||
logger: Logger;
|
|
||||||
service: CspAppService;
|
|
||||||
security: SecurityPluginSetup;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CspPlugin
|
export class CspPlugin
|
||||||
implements
|
implements
|
||||||
Plugin<
|
Plugin<
|
||||||
|
@ -69,24 +60,16 @@ export class CspPlugin
|
||||||
this.logger = initializerContext.logger.get();
|
this.logger = initializerContext.logger.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly CspAppService = new CspAppService();
|
|
||||||
|
|
||||||
public setup(
|
public setup(
|
||||||
core: CoreSetup<CspServerPluginStartDeps, CspServerPluginStart>,
|
core: CoreSetup<CspServerPluginStartDeps, CspServerPluginStart>,
|
||||||
plugins: CspServerPluginSetupDeps
|
plugins: CspServerPluginSetupDeps
|
||||||
): CspServerPluginSetup {
|
): CspServerPluginSetup {
|
||||||
const cspAppContext: CspAppContext = {
|
|
||||||
logger: this.logger,
|
|
||||||
service: this.CspAppService,
|
|
||||||
security: plugins.security,
|
|
||||||
};
|
|
||||||
|
|
||||||
setupSavedObjects(core.savedObjects);
|
setupSavedObjects(core.savedObjects);
|
||||||
|
|
||||||
const router = core.http.createRouter<CspRequestHandlerContext>();
|
setupRoutes({
|
||||||
|
core,
|
||||||
// Register server side APIs
|
logger: this.logger,
|
||||||
defineRoutes(router, cspAppContext);
|
});
|
||||||
|
|
||||||
const coreStartServices = core.getStartServices();
|
const coreStartServices = core.getStartServices();
|
||||||
this.setupCspTasks(plugins.taskManager, coreStartServices, this.logger);
|
this.setupCspTasks(plugins.taskManager, coreStartServices, this.logger);
|
||||||
|
@ -95,10 +78,6 @@ export class CspPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(core: CoreStart, plugins: CspServerPluginStartDeps): CspServerPluginStart {
|
public start(core: CoreStart, plugins: CspServerPluginStartDeps): CspServerPluginStart {
|
||||||
this.CspAppService.start({
|
|
||||||
...plugins.fleet,
|
|
||||||
});
|
|
||||||
|
|
||||||
plugins.fleet.fleetSetupCompleted().then(async () => {
|
plugins.fleet.fleetSetupCompleted().then(async () => {
|
||||||
const packageInfo = await plugins.fleet.packageService.asInternalUser.getInstallation(
|
const packageInfo = await plugins.fleet.packageService.asInternalUser.getInstallation(
|
||||||
CLOUD_SECURITY_POSTURE_PACKAGE_NAME
|
CLOUD_SECURITY_POSTURE_PACKAGE_NAME
|
||||||
|
|
|
@ -4,14 +4,7 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import {
|
import { httpServerMock, httpServiceMock, savedObjectsClientMock } from '@kbn/core/server/mocks';
|
||||||
httpServerMock,
|
|
||||||
httpServiceMock,
|
|
||||||
loggingSystemMock,
|
|
||||||
savedObjectsClientMock,
|
|
||||||
} from '@kbn/core/server/mocks';
|
|
||||||
import type { ElasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks';
|
|
||||||
import type { KibanaRequest } from '@kbn/core/server';
|
|
||||||
import {
|
import {
|
||||||
benchmarksQueryParamsSchema,
|
benchmarksQueryParamsSchema,
|
||||||
DEFAULT_BENCHMARKS_PER_PAGE,
|
DEFAULT_BENCHMARKS_PER_PAGE,
|
||||||
|
@ -34,21 +27,7 @@ import {
|
||||||
} from '@kbn/fleet-plugin/server/mocks';
|
} from '@kbn/fleet-plugin/server/mocks';
|
||||||
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
||||||
import { AgentPolicy } from '@kbn/fleet-plugin/common';
|
import { AgentPolicy } from '@kbn/fleet-plugin/common';
|
||||||
|
import { createCspRequestHandlerContextMock } from '../../mocks';
|
||||||
import { CspAppService } from '../../lib/csp_app_services';
|
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|
||||||
|
|
||||||
export const getMockCspContext = (mockEsClient: ElasticsearchClientMock): KibanaRequest => {
|
|
||||||
return {
|
|
||||||
core: {
|
|
||||||
elasticsearch: {
|
|
||||||
client: { asCurrentUser: mockEsClient },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fleet: { authz: { fleet: { all: false } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
function createMockAgentPolicy(props: Partial<AgentPolicy> = {}): AgentPolicy {
|
function createMockAgentPolicy(props: Partial<AgentPolicy> = {}): AgentPolicy {
|
||||||
return {
|
return {
|
||||||
|
@ -70,23 +49,14 @@ function createMockAgentPolicy(props: Partial<AgentPolicy> = {}): AgentPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('benchmarks API', () => {
|
describe('benchmarks API', () => {
|
||||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
logger = loggingSystemMock.createLogger();
|
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('validate the API route path', async () => {
|
it('validate the API route path', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineGetBenchmarksRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineGetBenchmarksRoute(router, cspContext);
|
|
||||||
|
|
||||||
const [config] = router.get.mock.calls[0];
|
const [config] = router.get.mock.calls[0];
|
||||||
|
|
||||||
|
@ -95,20 +65,12 @@ describe('benchmarks API', () => {
|
||||||
|
|
||||||
it('should accept to a user with fleet.all privilege', async () => {
|
it('should accept to a user with fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineGetBenchmarksRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineGetBenchmarksRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
@ -120,19 +82,13 @@ describe('benchmarks API', () => {
|
||||||
|
|
||||||
it('should reject to a user without fleet.all privilege', async () => {
|
it('should reject to a user without fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineGetBenchmarksRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineGetBenchmarksRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: false } } },
|
mockContext.fleet.authz.fleet.all = false;
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
|
|
|
@ -13,7 +13,6 @@ import {
|
||||||
CSP_RULE_SAVED_OBJECT_TYPE,
|
CSP_RULE_SAVED_OBJECT_TYPE,
|
||||||
} from '../../../common/constants';
|
} from '../../../common/constants';
|
||||||
import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark';
|
import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark';
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import type { Benchmark, CspRulesStatus } from '../../../common/types';
|
import type { Benchmark, CspRulesStatus } from '../../../common/types';
|
||||||
import type { CspRule } from '../../../common/schemas';
|
import type { CspRule } from '../../../common/schemas';
|
||||||
import {
|
import {
|
||||||
|
@ -130,7 +129,7 @@ const createBenchmarks = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defineGetBenchmarksRoute = (router: CspRouter, cspContext: CspAppContext): void =>
|
export const defineGetBenchmarksRoute = (router: CspRouter): void =>
|
||||||
router.get(
|
router.get(
|
||||||
{
|
{
|
||||||
path: BENCHMARKS_ROUTE_PATH,
|
path: BENCHMARKS_ROUTE_PATH,
|
||||||
|
@ -144,34 +143,29 @@ export const defineGetBenchmarksRoute = (router: CspRouter, cspContext: CspAppCo
|
||||||
return response.forbidden();
|
return response.forbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cspContext = await context.csp;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const soClient = (await context.core).savedObjects.client;
|
|
||||||
const { query } = request;
|
|
||||||
|
|
||||||
const agentService = cspContext.service.agentService;
|
|
||||||
const agentPolicyService = cspContext.service.agentPolicyService;
|
|
||||||
const packagePolicyService = cspContext.service.packagePolicyService;
|
|
||||||
|
|
||||||
if (!agentPolicyService || !agentService || !packagePolicyService) {
|
|
||||||
throw new Error(`Failed to get Fleet services`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cspPackagePolicies = await getCspPackagePolicies(
|
const cspPackagePolicies = await getCspPackagePolicies(
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
packagePolicyService,
|
cspContext.packagePolicyService,
|
||||||
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
||||||
query
|
request.query
|
||||||
);
|
);
|
||||||
|
|
||||||
const agentPolicies = await getCspAgentPolicies(
|
const agentPolicies = await getCspAgentPolicies(
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
cspPackagePolicies.items,
|
cspPackagePolicies.items,
|
||||||
agentPolicyService
|
cspContext.agentPolicyService
|
||||||
|
);
|
||||||
|
|
||||||
|
const enrichAgentPolicies = await addRunningAgentToAgentPolicy(
|
||||||
|
cspContext.agentService,
|
||||||
|
agentPolicies
|
||||||
);
|
);
|
||||||
|
|
||||||
const enrichAgentPolicies = await addRunningAgentToAgentPolicy(agentService, agentPolicies);
|
|
||||||
const benchmarks = await createBenchmarks(
|
const benchmarks = await createBenchmarks(
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
enrichAgentPolicies,
|
enrichAgentPolicies,
|
||||||
cspPackagePolicies.items
|
cspPackagePolicies.items
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,38 +4,22 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import { httpServerMock, httpServiceMock, loggingSystemMock } from '@kbn/core/server/mocks';
|
import { httpServerMock, httpServiceMock } from '@kbn/core/server/mocks';
|
||||||
import type { KibanaRequest } from '@kbn/core/server';
|
|
||||||
import { defineGetComplianceDashboardRoute } from './compliance_dashboard';
|
import { defineGetComplianceDashboardRoute } from './compliance_dashboard';
|
||||||
|
import { createCspRequestHandlerContextMock } from '../../mocks';
|
||||||
import { CspAppService } from '../../lib/csp_app_services';
|
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|
||||||
|
|
||||||
describe('compliance dashboard permissions API', () => {
|
describe('compliance dashboard permissions API', () => {
|
||||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
logger = loggingSystemMock.createLogger();
|
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept to a user with fleet.all privilege', async () => {
|
it('should accept to a user with fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineGetComplianceDashboardRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineGetComplianceDashboardRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
@ -47,20 +31,11 @@ describe('compliance dashboard permissions API', () => {
|
||||||
|
|
||||||
it('should reject to a user without fleet.all privilege', async () => {
|
it('should reject to a user without fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineGetComplianceDashboardRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineGetComplianceDashboardRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { transformError } from '@kbn/securitysolution-es-utils';
|
||||||
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
|
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
|
||||||
import type { ComplianceDashboardData } from '../../../common/types';
|
import type { ComplianceDashboardData } from '../../../common/types';
|
||||||
import { LATEST_FINDINGS_INDEX_DEFAULT_NS, STATS_ROUTE_PATH } from '../../../common/constants';
|
import { LATEST_FINDINGS_INDEX_DEFAULT_NS, STATS_ROUTE_PATH } from '../../../common/constants';
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { getGroupedFindingsEvaluation } from './get_grouped_findings_evaluation';
|
import { getGroupedFindingsEvaluation } from './get_grouped_findings_evaluation';
|
||||||
import { ClusterWithoutTrend, getClusters } from './get_clusters';
|
import { ClusterWithoutTrend, getClusters } from './get_clusters';
|
||||||
import { getStats } from './get_stats';
|
import { getStats } from './get_stats';
|
||||||
|
@ -33,10 +32,7 @@ const getClustersTrends = (clustersWithoutTrends: ClusterWithoutTrend[], trends:
|
||||||
const getSummaryTrend = (trends: Trends) =>
|
const getSummaryTrend = (trends: Trends) =>
|
||||||
trends.map(({ timestamp, summary }) => ({ timestamp, ...summary }));
|
trends.map(({ timestamp, summary }) => ({ timestamp, ...summary }));
|
||||||
|
|
||||||
export const defineGetComplianceDashboardRoute = (
|
export const defineGetComplianceDashboardRoute = (router: CspRouter): void =>
|
||||||
router: CspRouter,
|
|
||||||
cspContext: CspAppContext
|
|
||||||
): void =>
|
|
||||||
router.get(
|
router.get(
|
||||||
{
|
{
|
||||||
path: STATS_ROUTE_PATH,
|
path: STATS_ROUTE_PATH,
|
||||||
|
@ -46,8 +42,10 @@ export const defineGetComplianceDashboardRoute = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async (context, _, response) => {
|
async (context, _, response) => {
|
||||||
|
const cspContext = await context.csp;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
|
const esClient = cspContext.esClient.asCurrentUser;
|
||||||
|
|
||||||
const { id: pitId } = await esClient.openPointInTime({
|
const { id: pitId } = await esClient.openPointInTime({
|
||||||
index: LATEST_FINDINGS_INDEX_DEFAULT_NS,
|
index: LATEST_FINDINGS_INDEX_DEFAULT_NS,
|
||||||
|
|
|
@ -5,12 +5,7 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks';
|
import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks';
|
||||||
import {
|
import { savedObjectsClientMock, httpServiceMock, httpServerMock } from '@kbn/core/server/mocks';
|
||||||
savedObjectsClientMock,
|
|
||||||
httpServiceMock,
|
|
||||||
loggingSystemMock,
|
|
||||||
httpServerMock,
|
|
||||||
} from '@kbn/core/server/mocks';
|
|
||||||
import {
|
import {
|
||||||
createRulesConfig,
|
createRulesConfig,
|
||||||
defineUpdateRulesConfigRoute,
|
defineUpdateRulesConfigRoute,
|
||||||
|
@ -19,8 +14,6 @@ import {
|
||||||
updateAgentConfiguration,
|
updateAgentConfiguration,
|
||||||
} from './update_rules_configuration';
|
} from './update_rules_configuration';
|
||||||
|
|
||||||
import { CspAppService } from '../../lib/csp_app_services';
|
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
||||||
import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks';
|
import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks';
|
||||||
|
|
||||||
|
@ -29,37 +22,28 @@ import type { CspRule } from '../../../common/schemas';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ElasticsearchClient,
|
ElasticsearchClient,
|
||||||
KibanaRequest,
|
|
||||||
SavedObjectsClientContract,
|
SavedObjectsClientContract,
|
||||||
SavedObjectsFindResponse,
|
SavedObjectsFindResponse,
|
||||||
} from '@kbn/core/server';
|
} from '@kbn/core/server';
|
||||||
import { Chance } from 'chance';
|
import { Chance } from 'chance';
|
||||||
import { PackagePolicy, UpdatePackagePolicy } from '@kbn/fleet-plugin/common';
|
import { PackagePolicy, UpdatePackagePolicy } from '@kbn/fleet-plugin/common';
|
||||||
import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|
||||||
import { mockAuthenticatedUser } from '@kbn/security-plugin/common/model/authenticated_user.mock';
|
import { mockAuthenticatedUser } from '@kbn/security-plugin/common/model/authenticated_user.mock';
|
||||||
import { DeepPartial } from 'utility-types';
|
import { DeepPartial } from 'utility-types';
|
||||||
|
import { createCspRequestHandlerContextMock } from '../../mocks';
|
||||||
|
|
||||||
describe('Update rules configuration API', () => {
|
describe('Update rules configuration API', () => {
|
||||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
|
||||||
let mockEsClient: jest.Mocked<ElasticsearchClient>;
|
let mockEsClient: jest.Mocked<ElasticsearchClient>;
|
||||||
let mockSoClient: jest.Mocked<SavedObjectsClientContract>;
|
let mockSoClient: jest.Mocked<SavedObjectsClientContract>;
|
||||||
const chance = new Chance();
|
const chance = new Chance();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
logger = loggingSystemMock.createLogger();
|
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('validate the API route path', async () => {
|
it('validate the API route path', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineUpdateRulesConfigRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineUpdateRulesConfigRoute(router, cspContext);
|
|
||||||
|
|
||||||
const [config, _] = router.post.mock.calls[0];
|
const [config, _] = router.post.mock.calls[0];
|
||||||
|
|
||||||
|
@ -68,20 +52,12 @@ describe('Update rules configuration API', () => {
|
||||||
|
|
||||||
it('should accept to a user with fleet.all privilege', async () => {
|
it('should accept to a user with fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineUpdateRulesConfigRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineUpdateRulesConfigRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.post.mock.calls[0];
|
const [_, handler] = router.post.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
@ -93,20 +69,11 @@ describe('Update rules configuration API', () => {
|
||||||
|
|
||||||
it('should reject to a user without fleet.all privilege', async () => {
|
it('should reject to a user without fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspAppContextService = new CspAppService();
|
|
||||||
|
|
||||||
const cspContext: CspAppContext = {
|
defineUpdateRulesConfigRoute(router);
|
||||||
logger,
|
|
||||||
service: cspAppContextService,
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
defineUpdateRulesConfigRoute(router, cspContext);
|
|
||||||
const [_, handler] = router.post.mock.calls[0];
|
const [_, handler] = router.post.mock.calls[0];
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
} as unknown as KibanaRequest;
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { PackagePolicy, PackagePolicyConfigRecord } from '@kbn/fleet-plugin/comm
|
||||||
import { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
|
import { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server';
|
||||||
import { AuthenticatedUser } from '@kbn/security-plugin/common';
|
import { AuthenticatedUser } from '@kbn/security-plugin/common';
|
||||||
import { createCspRuleSearchFilterByPackagePolicy } from '../../../common/utils/helpers';
|
import { createCspRuleSearchFilterByPackagePolicy } from '../../../common/utils/helpers';
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import type { CspRule, CspRulesConfiguration } from '../../../common/schemas';
|
import type { CspRule, CspRulesConfiguration } from '../../../common/schemas';
|
||||||
import {
|
import {
|
||||||
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
||||||
|
@ -129,7 +129,7 @@ export const updateAgentConfiguration = async (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defineUpdateRulesConfigRoute = (router: CspRouter, cspContext: CspAppContext): void =>
|
export const defineUpdateRulesConfigRoute = (router: CspRouter): void =>
|
||||||
router.post(
|
router.post(
|
||||||
{
|
{
|
||||||
path: UPDATE_RULES_CONFIG_ROUTE_PATH,
|
path: UPDATE_RULES_CONFIG_ROUTE_PATH,
|
||||||
|
@ -139,33 +139,25 @@ export const defineUpdateRulesConfigRoute = (router: CspRouter, cspContext: CspA
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async (context, request, response) => {
|
async (context, request, response) => {
|
||||||
|
const cspContext = await context.csp;
|
||||||
|
|
||||||
if (!(await context.fleet).authz.fleet.all) {
|
if (!(await context.fleet).authz.fleet.all) {
|
||||||
return response.forbidden();
|
return response.forbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const coreContext = await context.core;
|
|
||||||
const esClient = coreContext.elasticsearch.client.asCurrentUser;
|
|
||||||
const soClient = coreContext.savedObjects.client;
|
|
||||||
const user = await cspContext.security.authc.getCurrentUser(request);
|
|
||||||
const packagePolicyService = cspContext.service.packagePolicyService;
|
|
||||||
const packagePolicyId = request.body.package_policy_id;
|
|
||||||
|
|
||||||
if (!packagePolicyService) {
|
|
||||||
throw new Error(`Failed to get Fleet services`);
|
|
||||||
}
|
|
||||||
const packagePolicy = await getPackagePolicy(
|
const packagePolicy = await getPackagePolicy(
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
packagePolicyService,
|
cspContext.packagePolicyService,
|
||||||
packagePolicyId
|
request.body.package_policy_id
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedPackagePolicy = await updateAgentConfiguration(
|
const updatedPackagePolicy = await updateAgentConfiguration(
|
||||||
packagePolicyService,
|
cspContext.packagePolicyService,
|
||||||
packagePolicy,
|
packagePolicy,
|
||||||
esClient,
|
cspContext.esClient.asCurrentUser,
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
user
|
cspContext.user
|
||||||
);
|
);
|
||||||
|
|
||||||
return response.ok({ body: updatedPackagePolicy });
|
return response.ok({ body: updatedPackagePolicy });
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import { Chance } from 'chance';
|
import { Chance } from 'chance';
|
||||||
import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks';
|
import {
|
||||||
|
elasticsearchClientMock,
|
||||||
|
ElasticsearchClientMock,
|
||||||
|
} from '@kbn/core-elasticsearch-client-server-mocks';
|
||||||
import type { ElasticsearchClient } from '@kbn/core/server';
|
import type { ElasticsearchClient } from '@kbn/core/server';
|
||||||
import { httpServerMock, httpServiceMock, loggingSystemMock } from '@kbn/core/server/mocks';
|
import { httpServerMock, httpServiceMock } from '@kbn/core/server/mocks';
|
||||||
import { DEFAULT_PIT_KEEP_ALIVE, defineEsPitRoute, esPitInputSchema } from './es_pit';
|
import { DEFAULT_PIT_KEEP_ALIVE, defineEsPitRoute, esPitInputSchema } from './es_pit';
|
||||||
import { CspAppService } from '../../lib/csp_app_services';
|
import { createCspRequestHandlerContextMock } from '../../mocks';
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|
||||||
|
|
||||||
describe('ES Point in time API endpoint', () => {
|
describe('ES Point in time API endpoint', () => {
|
||||||
const chance = new Chance();
|
const chance = new Chance();
|
||||||
|
@ -23,13 +24,8 @@ describe('ES Point in time API endpoint', () => {
|
||||||
|
|
||||||
it('validate the API route path', () => {
|
it('validate the API route path', () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspContext: CspAppContext = {
|
|
||||||
logger: loggingSystemMock.createLogger(),
|
|
||||||
service: new CspAppService(),
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
|
|
||||||
defineEsPitRoute(router, cspContext);
|
defineEsPitRoute(router);
|
||||||
|
|
||||||
const [config] = router.post.mock.calls[0];
|
const [config] = router.post.mock.calls[0];
|
||||||
expect(config.path).toEqual('/internal/cloud_security_posture/es_pit');
|
expect(config.path).toEqual('/internal/cloud_security_posture/es_pit');
|
||||||
|
@ -37,18 +33,10 @@ describe('ES Point in time API endpoint', () => {
|
||||||
|
|
||||||
it('should accept to a user with fleet.all privilege', async () => {
|
it('should accept to a user with fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspContext: CspAppContext = {
|
|
||||||
logger: loggingSystemMock.createLogger(),
|
|
||||||
service: new CspAppService(),
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
|
|
||||||
defineEsPitRoute(router, cspContext);
|
defineEsPitRoute(router);
|
||||||
|
|
||||||
const mockContext = {
|
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
const [context, req, res] = [mockContext, mockRequest, mockResponse];
|
||||||
|
@ -61,17 +49,11 @@ describe('ES Point in time API endpoint', () => {
|
||||||
|
|
||||||
it('should reject to a user without fleet.all privilege', async () => {
|
it('should reject to a user without fleet.all privilege', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspContext: CspAppContext = {
|
|
||||||
logger: loggingSystemMock.createLogger(),
|
|
||||||
service: new CspAppService(),
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
|
|
||||||
defineEsPitRoute(router, cspContext);
|
defineEsPitRoute(router);
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: false } } },
|
mockContext.fleet.authz.fleet.all = false;
|
||||||
};
|
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
const mockRequest = httpServerMock.createKibanaRequest();
|
const mockRequest = httpServerMock.createKibanaRequest();
|
||||||
|
@ -85,22 +67,15 @@ describe('ES Point in time API endpoint', () => {
|
||||||
|
|
||||||
it('should return the newly created PIT ID from ES', async () => {
|
it('should return the newly created PIT ID from ES', async () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const cspContext: CspAppContext = {
|
|
||||||
logger: loggingSystemMock.createLogger(),
|
|
||||||
service: new CspAppService(),
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
};
|
|
||||||
|
|
||||||
defineEsPitRoute(router, cspContext);
|
defineEsPitRoute(router);
|
||||||
|
|
||||||
const pitId = chance.string();
|
const pitId = chance.string();
|
||||||
mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser;
|
mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser;
|
||||||
mockEsClient.openPointInTime.mockImplementation(() => Promise.resolve({ id: pitId }));
|
mockEsClient.openPointInTime.mockImplementation(() => Promise.resolve({ id: pitId }));
|
||||||
|
|
||||||
const mockContext = {
|
const mockContext = createCspRequestHandlerContextMock();
|
||||||
fleet: { authz: { fleet: { all: true } } },
|
mockContext.core.elasticsearch.client.asCurrentUser = mockEsClient as ElasticsearchClientMock;
|
||||||
core: { elasticsearch: { client: { asCurrentUser: mockEsClient } } },
|
|
||||||
};
|
|
||||||
|
|
||||||
const indexName = chance.string();
|
const indexName = chance.string();
|
||||||
const keepAlive = chance.string();
|
const keepAlive = chance.string();
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import { schema } from '@kbn/config-schema';
|
import { schema } from '@kbn/config-schema';
|
||||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||||
import { ES_PIT_ROUTE_PATH } from '../../../common/constants';
|
import { ES_PIT_ROUTE_PATH } from '../../../common/constants';
|
||||||
import type { CspAppContext } from '../../plugin';
|
|
||||||
import type { CspRouter } from '../../types';
|
import type { CspRouter } from '../../types';
|
||||||
|
|
||||||
export const DEFAULT_PIT_KEEP_ALIVE = '1m';
|
export const DEFAULT_PIT_KEEP_ALIVE = '1m';
|
||||||
|
@ -18,7 +17,7 @@ export const esPitInputSchema = schema.object({
|
||||||
keep_alive: schema.string({ defaultValue: DEFAULT_PIT_KEEP_ALIVE }),
|
keep_alive: schema.string({ defaultValue: DEFAULT_PIT_KEEP_ALIVE }),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const defineEsPitRoute = (router: CspRouter, cspContext: CspAppContext): void =>
|
export const defineEsPitRoute = (router: CspRouter): void =>
|
||||||
router.post(
|
router.post(
|
||||||
{
|
{
|
||||||
path: ES_PIT_ROUTE_PATH,
|
path: ES_PIT_ROUTE_PATH,
|
||||||
|
@ -28,13 +27,14 @@ export const defineEsPitRoute = (router: CspRouter, cspContext: CspAppContext):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async (context, request, response) => {
|
async (context, request, response) => {
|
||||||
|
const cspContext = await context.csp;
|
||||||
|
|
||||||
if (!(await context.fleet).authz.fleet.all) {
|
if (!(await context.fleet).authz.fleet.all) {
|
||||||
return response.forbidden();
|
return response.forbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const coreContext = await context.core;
|
const esClient = cspContext.esClient.asCurrentUser;
|
||||||
const esClient = coreContext.elasticsearch.client.asCurrentUser;
|
|
||||||
const { id } = await esClient.openPointInTime({
|
const { id } = await esClient.openPointInTime({
|
||||||
index: request.query.index_name,
|
index: request.query.index_name,
|
||||||
keep_alive: request.query.keep_alive,
|
keep_alive: request.query.keep_alive,
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 { defineGetComplianceDashboardRoute } from './compliance_dashboard/compliance_dashboard';
|
|
||||||
import { defineGetBenchmarksRoute } from './benchmarks/benchmarks';
|
|
||||||
import { defineUpdateRulesConfigRoute } from './configuration/update_rules_configuration';
|
|
||||||
import { defineGetCspSetupStatusRoute } from './status/status';
|
|
||||||
import { defineEsPitRoute } from './es_pit/es_pit';
|
|
||||||
import { CspAppContext } from '../plugin';
|
|
||||||
import { CspRouter } from '../types';
|
|
||||||
|
|
||||||
export function defineRoutes(router: CspRouter, cspContext: CspAppContext) {
|
|
||||||
defineGetComplianceDashboardRoute(router, cspContext);
|
|
||||||
defineGetBenchmarksRoute(router, cspContext);
|
|
||||||
defineUpdateRulesConfigRoute(router, cspContext);
|
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
|
||||||
defineEsPitRoute(router, cspContext);
|
|
||||||
}
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* 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 type { CoreSetup, Logger } from '@kbn/core/server';
|
||||||
|
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
|
||||||
|
import type {
|
||||||
|
CspRequestHandlerContext,
|
||||||
|
CspServerPluginStart,
|
||||||
|
CspServerPluginStartDeps,
|
||||||
|
} from '../types';
|
||||||
|
import { PLUGIN_ID } from '../../common';
|
||||||
|
import { defineGetComplianceDashboardRoute } from './compliance_dashboard/compliance_dashboard';
|
||||||
|
import { defineGetBenchmarksRoute } from './benchmarks/benchmarks';
|
||||||
|
import { defineUpdateRulesConfigRoute } from './configuration/update_rules_configuration';
|
||||||
|
import { defineGetCspSetupStatusRoute } from './status/status';
|
||||||
|
import { defineEsPitRoute } from './es_pit/es_pit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Registers routes
|
||||||
|
* 2. Registers routes handler context
|
||||||
|
*/
|
||||||
|
export function setupRoutes({
|
||||||
|
core,
|
||||||
|
logger,
|
||||||
|
}: {
|
||||||
|
core: CoreSetup<CspServerPluginStartDeps, CspServerPluginStart>;
|
||||||
|
logger: Logger;
|
||||||
|
}) {
|
||||||
|
const router = core.http.createRouter<CspRequestHandlerContext>();
|
||||||
|
defineGetComplianceDashboardRoute(router);
|
||||||
|
defineGetBenchmarksRoute(router);
|
||||||
|
defineUpdateRulesConfigRoute(router);
|
||||||
|
defineGetCspSetupStatusRoute(router);
|
||||||
|
defineEsPitRoute(router);
|
||||||
|
|
||||||
|
core.http.registerRouteHandlerContext<CspRequestHandlerContext, typeof PLUGIN_ID>(
|
||||||
|
PLUGIN_ID,
|
||||||
|
async (context, request) => {
|
||||||
|
const [, { security, fleet }] = await core.getStartServices();
|
||||||
|
const coreContext = await context.core;
|
||||||
|
await fleet.fleetSetupCompleted();
|
||||||
|
|
||||||
|
let user: AuthenticatedUser | null = null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
get user() {
|
||||||
|
// We want to call getCurrentUser only when needed and only once
|
||||||
|
if (!user) {
|
||||||
|
user = security.authc.getCurrentUser(request);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
},
|
||||||
|
logger,
|
||||||
|
esClient: coreContext.elasticsearch.client,
|
||||||
|
soClient: coreContext.savedObjects.client,
|
||||||
|
agentPolicyService: fleet.agentPolicyService,
|
||||||
|
agentService: fleet.agentService,
|
||||||
|
packagePolicyService: fleet.packagePolicyService,
|
||||||
|
packageService: fleet.packageService,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -5,18 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CspAppContext } from '../../plugin';
|
|
||||||
import { defineGetCspSetupStatusRoute, INDEX_TIMEOUT_IN_MINUTES } from './status';
|
import { defineGetCspSetupStatusRoute, INDEX_TIMEOUT_IN_MINUTES } from './status';
|
||||||
import { httpServerMock, httpServiceMock, loggingSystemMock } from '@kbn/core/server/mocks';
|
import { httpServerMock, httpServiceMock } from '@kbn/core/server/mocks';
|
||||||
import type { ESSearchResponse } from '@kbn/core/types/elasticsearch';
|
import type { ESSearchResponse } from '@kbn/core/types/elasticsearch';
|
||||||
import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|
||||||
import {
|
|
||||||
createMockAgentPolicyService,
|
|
||||||
createMockAgentService,
|
|
||||||
createMockPackageService,
|
|
||||||
createPackagePolicyServiceMock,
|
|
||||||
xpackMocks,
|
|
||||||
} from '@kbn/fleet-plugin/server/mocks';
|
|
||||||
import {
|
import {
|
||||||
AgentClient,
|
AgentClient,
|
||||||
AgentPolicyServiceInterface,
|
AgentPolicyServiceInterface,
|
||||||
|
@ -32,6 +23,7 @@ import {
|
||||||
RegistryPackage,
|
RegistryPackage,
|
||||||
} from '@kbn/fleet-plugin/common';
|
} from '@kbn/fleet-plugin/common';
|
||||||
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
|
||||||
|
import { createCspRequestHandlerContextMock } from '../../mocks';
|
||||||
|
|
||||||
const mockCspPackageInfo: Installation = {
|
const mockCspPackageInfo: Installation = {
|
||||||
verification_status: 'verified',
|
verification_status: 'verified',
|
||||||
|
@ -65,43 +57,29 @@ const mockLatestCspPackageInfo: RegistryPackage = {
|
||||||
|
|
||||||
describe('CspSetupStatus route', () => {
|
describe('CspSetupStatus route', () => {
|
||||||
const router = httpServiceMock.createRouter();
|
const router = httpServiceMock.createRouter();
|
||||||
const logger: ReturnType<typeof loggingSystemMock.createLogger> =
|
let mockContext: ReturnType<typeof createCspRequestHandlerContextMock>;
|
||||||
loggingSystemMock.createLogger();
|
|
||||||
let mockContext: ReturnType<typeof xpackMocks.createRequestHandlerContext>;
|
|
||||||
let mockPackagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
|
let mockPackagePolicyService: jest.Mocked<PackagePolicyServiceInterface>;
|
||||||
let mockAgentPolicyService: jest.Mocked<AgentPolicyServiceInterface>;
|
let mockAgentPolicyService: jest.Mocked<AgentPolicyServiceInterface>;
|
||||||
let mockAgentService: jest.Mocked<AgentService>;
|
let mockAgentService: jest.Mocked<AgentService>;
|
||||||
let mockAgentClient: jest.Mocked<AgentClient>;
|
let mockAgentClient: jest.Mocked<AgentClient>;
|
||||||
let mockPackageService: PackageService;
|
let mockPackageService: PackageService;
|
||||||
let mockPackageClient: jest.Mocked<PackageClient>;
|
let mockPackageClient: jest.Mocked<PackageClient>;
|
||||||
let cspContext: CspAppContext;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|
||||||
mockContext = xpackMocks.createRequestHandlerContext();
|
mockContext = createCspRequestHandlerContextMock();
|
||||||
mockPackagePolicyService = createPackagePolicyServiceMock();
|
mockPackagePolicyService = mockContext.csp.packagePolicyService;
|
||||||
mockAgentPolicyService = createMockAgentPolicyService();
|
mockAgentPolicyService = mockContext.csp.agentPolicyService;
|
||||||
mockAgentService = createMockAgentService();
|
mockAgentService = mockContext.csp.agentService;
|
||||||
mockPackageService = createMockPackageService();
|
mockPackageService = mockContext.csp.packageService;
|
||||||
|
|
||||||
mockAgentClient = mockAgentService.asInternalUser as jest.Mocked<AgentClient>;
|
mockAgentClient = mockAgentService.asInternalUser as jest.Mocked<AgentClient>;
|
||||||
mockPackageClient = mockPackageService.asInternalUser as jest.Mocked<PackageClient>;
|
mockPackageClient = mockPackageService.asInternalUser as jest.Mocked<PackageClient>;
|
||||||
|
|
||||||
cspContext = {
|
|
||||||
logger,
|
|
||||||
service: {
|
|
||||||
agentService: mockAgentService,
|
|
||||||
agentPolicyService: mockAgentPolicyService,
|
|
||||||
packagePolicyService: mockPackagePolicyService,
|
|
||||||
packageService: mockPackageService,
|
|
||||||
},
|
|
||||||
security: securityMock.createSetup(),
|
|
||||||
} as unknown as CspAppContext;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('validate the API route path', async () => {
|
it('validate the API route path', async () => {
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
const [config, _] = router.get.mock.calls[0];
|
const [config, _] = router.get.mock.calls[0];
|
||||||
|
|
||||||
expect(config.path).toEqual('/internal/cloud_security_posture/status');
|
expect(config.path).toEqual('/internal/cloud_security_posture/status');
|
||||||
|
@ -123,7 +101,7 @@ describe('CspSetupStatus route', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
|
@ -162,7 +140,7 @@ describe('CspSetupStatus route', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
|
@ -210,7 +188,7 @@ describe('CspSetupStatus route', () => {
|
||||||
} as unknown as GetAgentStatusResponse['results']);
|
} as unknown as GetAgentStatusResponse['results']);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
|
@ -248,7 +226,7 @@ describe('CspSetupStatus route', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
const mockResponse = httpServerMock.createResponseFactory();
|
const mockResponse = httpServerMock.createResponseFactory();
|
||||||
|
@ -295,7 +273,7 @@ describe('CspSetupStatus route', () => {
|
||||||
} as unknown as GetAgentStatusResponse['results']);
|
} as unknown as GetAgentStatusResponse['results']);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
|
@ -349,7 +327,7 @@ describe('CspSetupStatus route', () => {
|
||||||
} as unknown as GetAgentStatusResponse['results']);
|
} as unknown as GetAgentStatusResponse['results']);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
|
@ -405,7 +383,7 @@ describe('CspSetupStatus route', () => {
|
||||||
} as unknown as GetAgentStatusResponse['results']);
|
} as unknown as GetAgentStatusResponse['results']);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
defineGetCspSetupStatusRoute(router, cspContext);
|
defineGetCspSetupStatusRoute(router);
|
||||||
|
|
||||||
const [_, handler] = router.get.mock.calls[0];
|
const [_, handler] = router.get.mock.calls[0];
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||||
import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
import type { Logger, ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||||
import type {
|
import type {
|
||||||
AgentPolicyServiceInterface,
|
AgentPolicyServiceInterface,
|
||||||
AgentService,
|
AgentService,
|
||||||
|
@ -16,7 +16,6 @@ import type {
|
||||||
import moment, { MomentInput } from 'moment';
|
import moment, { MomentInput } from 'moment';
|
||||||
import { PackagePolicy } from '@kbn/fleet-plugin/common';
|
import { PackagePolicy } from '@kbn/fleet-plugin/common';
|
||||||
import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, STATUS_ROUTE_PATH } from '../../../common/constants';
|
import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, STATUS_ROUTE_PATH } from '../../../common/constants';
|
||||||
import type { CspAppContext } from '../../plugin';
|
|
||||||
import type { CspRouter } from '../../types';
|
import type { CspRouter } from '../../types';
|
||||||
import type { CspSetupStatus, Status } from '../../../common/types';
|
import type { CspSetupStatus, Status } from '../../../common/types';
|
||||||
import {
|
import {
|
||||||
|
@ -71,7 +70,7 @@ const getStatus = (
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCspSetupStatus = async (
|
const getCspSetupStatus = async (
|
||||||
logger: CspAppContext['logger'],
|
logger: Logger,
|
||||||
esClient: ElasticsearchClient,
|
esClient: ElasticsearchClient,
|
||||||
soClient: SavedObjectsClientContract,
|
soClient: SavedObjectsClientContract,
|
||||||
packageService: PackageService,
|
packageService: PackageService,
|
||||||
|
@ -123,7 +122,7 @@ const getCspSetupStatus = async (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defineGetCspSetupStatusRoute = (router: CspRouter, cspContext: CspAppContext): void =>
|
export const defineGetCspSetupStatusRoute = (router: CspRouter): void =>
|
||||||
router.get(
|
router.get(
|
||||||
{
|
{
|
||||||
path: STATUS_ROUTE_PATH,
|
path: STATUS_ROUTE_PATH,
|
||||||
|
@ -133,27 +132,16 @@ export const defineGetCspSetupStatusRoute = (router: CspRouter, cspContext: CspA
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async (context, _, response) => {
|
async (context, _, response) => {
|
||||||
|
const cspContext = await context.csp;
|
||||||
try {
|
try {
|
||||||
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
|
|
||||||
const soClient = (await context.core).savedObjects.client;
|
|
||||||
|
|
||||||
const packageService = cspContext.service.packageService;
|
|
||||||
const agentService = cspContext.service.agentService;
|
|
||||||
const agentPolicyService = cspContext.service.agentPolicyService;
|
|
||||||
const packagePolicyService = cspContext.service.packagePolicyService;
|
|
||||||
|
|
||||||
if (!agentPolicyService || !agentService || !packagePolicyService || !packageService) {
|
|
||||||
throw new Error(`Failed to get Fleet services`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cspSetupStatus = await getCspSetupStatus(
|
const cspSetupStatus = await getCspSetupStatus(
|
||||||
cspContext.logger,
|
cspContext.logger,
|
||||||
esClient,
|
cspContext.esClient.asCurrentUser,
|
||||||
soClient,
|
cspContext.soClient,
|
||||||
packageService,
|
cspContext.packageService,
|
||||||
packagePolicyService,
|
cspContext.packagePolicyService,
|
||||||
agentPolicyService,
|
cspContext.agentPolicyService,
|
||||||
agentService
|
cspContext.agentService
|
||||||
);
|
);
|
||||||
|
|
||||||
const body: CspSetupStatus = cspSetupStatus;
|
const body: CspSetupStatus = cspSetupStatus;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
PluginSetup as DataPluginSetup,
|
PluginSetup as DataPluginSetup,
|
||||||
PluginStart as DataPluginStart,
|
PluginStart as DataPluginStart,
|
||||||
|
@ -13,15 +12,20 @@ import {
|
||||||
TaskManagerSetupContract,
|
TaskManagerSetupContract,
|
||||||
TaskManagerStartContract,
|
TaskManagerStartContract,
|
||||||
} from '@kbn/task-manager-plugin/server';
|
} from '@kbn/task-manager-plugin/server';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
RouteMethod,
|
|
||||||
KibanaResponseFactory,
|
|
||||||
RequestHandler,
|
|
||||||
IRouter,
|
IRouter,
|
||||||
CoreStart,
|
CoreStart,
|
||||||
|
CustomRequestHandlerContext,
|
||||||
|
Logger,
|
||||||
|
SavedObjectsClientContract,
|
||||||
|
IScopedClusterClient,
|
||||||
} from '@kbn/core/server';
|
} from '@kbn/core/server';
|
||||||
|
import type {
|
||||||
|
AgentService,
|
||||||
|
PackageService,
|
||||||
|
AgentPolicyServiceInterface,
|
||||||
|
PackagePolicyServiceInterface,
|
||||||
|
} from '@kbn/fleet-plugin/server';
|
||||||
import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server';
|
import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server';
|
||||||
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
|
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
|
||||||
|
|
||||||
|
@ -49,19 +53,22 @@ export interface CspServerPluginStartDeps {
|
||||||
export type CspServerPluginStartServices = Promise<
|
export type CspServerPluginStartServices = Promise<
|
||||||
[CoreStart, CspServerPluginStartDeps, CspServerPluginStart]
|
[CoreStart, CspServerPluginStartDeps, CspServerPluginStart]
|
||||||
>;
|
>;
|
||||||
export type CspRequestHandlerContext = FleetRequestHandlerContext;
|
|
||||||
|
|
||||||
/**
|
interface CspApiRequestHandlerContext {
|
||||||
* Convenience type for request handlers in CSP that includes the CspRequestHandlerContext type
|
user: ReturnType<SecurityPluginStart['authc']['getCurrentUser']>;
|
||||||
* @internal
|
logger: Logger;
|
||||||
*/
|
esClient: IScopedClusterClient;
|
||||||
export type CspRequestHandler<
|
soClient: SavedObjectsClientContract;
|
||||||
P = unknown,
|
agentPolicyService: AgentPolicyServiceInterface;
|
||||||
Q = unknown,
|
agentService: AgentService;
|
||||||
B = unknown,
|
packagePolicyService: PackagePolicyServiceInterface;
|
||||||
Method extends RouteMethod = any,
|
packageService: PackageService;
|
||||||
ResponseFactory extends KibanaResponseFactory = KibanaResponseFactory
|
}
|
||||||
> = RequestHandler<P, Q, B, CspRequestHandlerContext, Method, ResponseFactory>;
|
|
||||||
|
export type CspRequestHandlerContext = CustomRequestHandlerContext<{
|
||||||
|
csp: CspApiRequestHandlerContext;
|
||||||
|
fleet: FleetRequestHandlerContext['fleet'];
|
||||||
|
}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience type for routers in Csp that includes the CspRequestHandlerContext type
|
* Convenience type for routers in Csp that includes the CspRequestHandlerContext type
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue