Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ enabled:
- x-pack/test/cases_api_integration/security_and_spaces/config_trial.ts
- x-pack/test/cases_api_integration/security_and_spaces/config_no_public_base_url.ts
- x-pack/test/cases_api_integration/spaces_only/config.ts
- x-pack/test/cloud_security_posture_functional/config.ts
- x-pack/test/detection_engine_api_integration/basic/config.ts
- x-pack/test/detection_engine_api_integration/security_and_spaces/group1/config.ts
- x-pack/test/detection_engine_api_integration/security_and_spaces/group2/config.ts
Expand Down
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,8 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience
/x-pack/plugins/cloud_security_posture/ @elastic/kibana-cloud-security-posture
/x-pack/plugins/security_solution/public/cloud_security_posture @elastic/kibana-cloud-security-posture
/x-pack/test/api_integration/apis/cloud_security_posture/ @elastic/kibana-cloud-security-posture
/x-pack/test/cloud_security_posture_functional/ @elastic/kibana-cloud-security-posture


# Security Solution onboarding tour
/x-pack/plugins/security_solution/public/common/components/guided_onboarding @elastic/security-threat-hunting-explore
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/cloud_security_posture/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ interface BaseCspSetupStatus {
latestPackageVersion: string;
installedPackagePolicies: number;
healthyAgents: number;
isPluginInitialized: boolean;
}

interface CspSetupNotInstalledStatus extends BaseCspSetupStatus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ const FilterableCell: React.FC<{
}
`}
>
<div className="__filter_value eui-textTruncate">{children}</div>
<div className="__filter_value eui-textTruncate" data-test-subj="filter_cell_value">
{children}
</div>
<div
className="__filter_buttons"
css={css`
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/cloud_security_posture/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const createCspRequestHandlerContextMock = () => {
agentService: createMockAgentService(),
packagePolicyService: createPackagePolicyServiceMock(),
packageService: createMockPackageService(),
isPluginInitialized: () => false,
},
};
};
12 changes: 12 additions & 0 deletions x-pack/plugins/cloud_security_posture/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ export class CspPlugin
private readonly logger: Logger;
private isCloudEnabled?: boolean;

/**
* CSP is initialized when the Fleet package is installed.
* either directly after installation, or
* when the plugin is started and a package is present.
*/
#isInitialized: boolean = false;

constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}
Expand All @@ -75,6 +82,7 @@ export class CspPlugin
setupRoutes({
core,
logger: this.logger,
isPluginInitialized: () => this.#isInitialized,
});

const coreStartServices = core.getStartServices();
Expand Down Expand Up @@ -162,12 +170,16 @@ export class CspPlugin

public stop() {}

/**
* Initialization is idempotent and required for (re)creating indices and transforms.
*/
async initialize(core: CoreStart, taskManager: TaskManagerStartContract): Promise<void> {
this.logger.debug('initialize');
const esClient = core.elasticsearch.client.asInternalUser;
await initializeCspIndices(esClient, this.logger);
await initializeCspTransforms(esClient, this.logger);
await scheduleFindingsStatsTask(taskManager, this.logger);
this.#isInitialized = true;
}

async uninstallResources(taskManager: TaskManagerStartContract, logger: Logger): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import { defineGetCspStatusRoute } from './status/status';
export function setupRoutes({
core,
logger,
isPluginInitialized,
}: {
core: CoreSetup<CspServerPluginStartDeps, CspServerPluginStart>;
logger: Logger;
isPluginInitialized(): boolean;
}) {
const router = core.http.createRouter<CspRequestHandlerContext>();
defineGetComplianceDashboardRoute(router);
Expand Down Expand Up @@ -57,6 +59,7 @@ export function setupRoutes({
agentService: fleet.agentService,
packagePolicyService: fleet.packagePolicyService,
packageService: fleet.packageService,
isPluginInitialized,
};
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 0,
healthyAgents: 0,
installedPackageVersion: undefined,
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -159,6 +160,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 3,
healthyAgents: 0,
installedPackageVersion: '0.0.14',
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -208,6 +210,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 3,
healthyAgents: 1,
installedPackageVersion: '0.0.14',
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -245,6 +248,7 @@ describe('CspSetupStatus route', () => {
latestPackageVersion: '0.0.14',
installedPackagePolicies: 0,
healthyAgents: 0,
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -295,6 +299,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 1,
healthyAgents: 0,
installedPackageVersion: '0.0.14',
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -352,6 +357,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 1,
healthyAgents: 1,
installedPackageVersion: '0.0.14',
isPluginInitialized: false,
});
});

Expand Down Expand Up @@ -408,6 +414,7 @@ describe('CspSetupStatus route', () => {
installedPackagePolicies: 1,
healthyAgents: 1,
installedPackageVersion: '0.0.14',
isPluginInitialized: false,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { SavedObjectsClientContract } from '@kbn/core/server';
import type { AgentPolicyServiceInterface, AgentService } from '@kbn/fleet-plugin/server';
import moment from 'moment';
import { PackagePolicy } from '@kbn/fleet-plugin/common';
import { schema } from '@kbn/config-schema';
import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, STATUS_ROUTE_PATH } from '../../../common/constants';
import type { CspApiRequestHandlerContext, CspRouter } from '../../types';
import type { CspSetupStatus, CspStatusCode } from '../../../common/types';
Expand Down Expand Up @@ -73,6 +74,7 @@ const getCspStatus = async ({
packagePolicyService,
agentPolicyService,
agentService,
isPluginInitialized,
}: CspApiRequestHandlerContext): Promise<CspSetupStatus> => {
const [hasFindings, installation, latestCspPackage, installedPackagePolicies] = await Promise.all(
[
Expand Down Expand Up @@ -109,6 +111,7 @@ const getCspStatus = async ({
latestPackageVersion: latestCspPackageVersion,
healthyAgents,
installedPackagePolicies: installedPackagePoliciesTotal,
isPluginInitialized: isPluginInitialized(),
};

return {
Expand All @@ -117,21 +120,37 @@ const getCspStatus = async ({
healthyAgents,
installedPackagePolicies: installedPackagePoliciesTotal,
installedPackageVersion: installation?.install_version,
isPluginInitialized: isPluginInitialized(),
};
};

export const statusQueryParamsSchema = schema.object({
/**
* CSP Plugin initialization includes creating indices/transforms/tasks.
* Prior to this initialization, the plugin is not ready to index findings.
*/
check: schema.oneOf([schema.literal('all'), schema.literal('init')], { defaultValue: 'all' }),
});

export const defineGetCspStatusRoute = (router: CspRouter): void =>
router.get(
{
path: STATUS_ROUTE_PATH,
validate: false,
validate: { query: statusQueryParamsSchema },
options: {
tags: ['access:cloud-security-posture-read'],
},
},
async (context, _, response) => {
async (context, request, response) => {
const cspContext = await context.csp;
try {
if (request.query.check === 'init') {
return response.ok({
body: {
isPluginInitialized: cspContext.isPluginInitialized(),
},
});
}
const status = await getCspStatus(cspContext);
return response.ok({
body: status,
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/cloud_security_posture/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export interface CspApiRequestHandlerContext {
agentService: AgentService;
packagePolicyService: PackagePolicyClient;
packageService: PackageService;
isPluginInitialized(): boolean;
}

export type CspRequestHandlerContext = CustomRequestHandlerContext<{
Expand Down
34 changes: 34 additions & 0 deletions x-pack/test/cloud_security_posture_functional/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 { resolve } from 'path';
import type { FtrConfigProviderContext } from '@kbn/test';
import { pageObjects } from './page_objects';
import { getPreConfiguredFleetPackages, getPreConfiguredAgentPolicies } from './helpers';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xpackFunctionalConfig = await readConfigFile(
require.resolve('../functional/config.base.js')
);

return {
...xpackFunctionalConfig.getAll(),
pageObjects,
testFiles: [resolve(__dirname, './pages')],
junit: {
reportName: 'X-Pack Cloud Security Posture Functional Tests',
},
kbnTestServer: {
...xpackFunctionalConfig.get('kbnTestServer'),
serverArgs: [
...xpackFunctionalConfig.get('kbnTestServer.serverArgs'),
...getPreConfiguredFleetPackages(),
...getPreConfiguredAgentPolicies(),
],
},
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { GenericFtrProviderContext } from '@kbn/test';

import { pageObjects } from './page_objects';
import { services } from '../functional/services';

export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;
27 changes: 27 additions & 0 deletions x-pack/test/cloud_security_posture_functional/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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.
*/

const CLOUD_SECURITY_POSTURE_PACKAGE_NAME = 'cloud_security_posture';

/**
* flags to load kibana with fleet pre-configured to have 'cloud_security_posture' integration installed
*/
export const getPreConfiguredFleetPackages = () => [
`--xpack.fleet.packages.0.name=${CLOUD_SECURITY_POSTURE_PACKAGE_NAME}`,
`--xpack.fleet.packages.0.version=latest`,
];

/**
* flags to load kibana with pre-configured agent policy with a 'cloud_security_posture' package policy
*/
export const getPreConfiguredAgentPolicies = () => [
`--xpack.fleet.agentPolicies.0.id=agent-policy-csp`,
`--xpack.fleet.agentPolicies.0.name=example-agent-policy-csp`,
`--xpack.fleet.agentPolicies.0.package_policies.0.id=integration-policy-csp`,
`--xpack.fleet.agentPolicies.0.package_policies.0.name=example-integration-csp`,
`--xpack.fleet.agentPolicies.0.package_policies.0.package.name=${CLOUD_SECURITY_POSTURE_PACKAGE_NAME}`,
];
Loading