mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution][Detections] Implement endpoint for fetching installed Fleet integrations (#132667)
**Addresses partially:** https://github.com/elastic/security-team/issues/2856, https://github.com/elastic/security-team/issues/3624 (internal tickets) ## Summary Adds a new detections endpoint that returns installed Fleet integrations. It is to be used on the Rule Management and Rule Details pages (see https://github.com/elastic/kibana/pull/131475 for context and screenshots). This endpoint is `internal` - no need to document it. ``` GET /internal/detection_engine/fleet/integrations/installed ``` ```json { "installed_integrations": [ { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "billing", "integration_title": "AWS Billing", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "cloudtrail", "integration_title": "AWS CloudTrail", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "cloudwatch", "integration_title": "AWS CloudWatch", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "dynamodb", "integration_title": "Amazon DynamoDB", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "ebs", "integration_title": "Amazon EBS", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "ec2", "integration_title": "Amazon EC2", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "elb", "integration_title": "AWS ELB", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "lambda", "integration_title": "AWS Lambda", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "natgateway", "integration_title": "Amazon NAT Gateway", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "firewall", "integration_title": "AWS Network Firewall", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "rds", "integration_title": "Amazon RDS", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "s3", "integration_title": "Amazon S3", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "s3_storage_lens", "integration_title": "Amazon S3 Storage Lens", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "sns", "integration_title": "Amazon SNS", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "sqs", "integration_title": "Amazon SQS", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "transitgateway", "integration_title": "AWS Transit Gateway", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "usage", "integration_title": "AWS Usage", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "vpcflow", "integration_title": "Amazon VPC", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "vpn", "integration_title": "Amazon VPN", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "waf", "integration_title": "AWS WAF", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "route53", "integration_title": "AWS Route 53", "is_enabled": false }, { "package_name": "aws", "package_title": "AWS", "package_version": "1.16.1", "integration_name": "cloudfront", "integration_title": "Amazon CloudFront", "is_enabled": true }, { "package_name": "system", "package_title": "System", "package_version": "1.13.0", "is_enabled": true } ] } ``` ## Next steps - Test with users with different privileges (non-superusers). Fleet privileges: none, read, all. Security Solution privileges. SO privileges. - Add filtering by `package_name` and `is_enabled` (will be done in a separate PR). - Add test coverage (will be done in a separate PR). ### Checklist Delete any items that are not applicable to this PR. - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
93de448327
commit
dcf83f9f85
10 changed files with 508 additions and 2 deletions
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './installed_integrations';
|
||||
export * from './rule_monitoring';
|
||||
export * from './rule_params';
|
||||
export * from './schemas';
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Installed package
|
||||
|
||||
/**
|
||||
* Basic information about an installed Fleet package.
|
||||
*/
|
||||
export interface InstalledPackageBasicInfo {
|
||||
/**
|
||||
* Name is a unique package id within a given cluster.
|
||||
* There can't be 2 or more different packages with the same name.
|
||||
* @example 'aws'
|
||||
*/
|
||||
package_name: string;
|
||||
|
||||
/**
|
||||
* Title is a user-friendly name of the package that we show in the UI.
|
||||
* @example 'AWS'
|
||||
*/
|
||||
package_title: string;
|
||||
|
||||
/**
|
||||
* Version of the package. Semver-compatible.
|
||||
* @example '1.2.3'
|
||||
*/
|
||||
package_version: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about an installed Fleet package including its integrations.
|
||||
*
|
||||
* @example
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integrations: [
|
||||
* {
|
||||
* integration_name: 'billing',
|
||||
* integration_title: 'AWS Billing',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudtrail',
|
||||
* integration_title: 'AWS CloudTrail',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudwatch',
|
||||
* integration_title: 'AWS CloudWatch',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudfront',
|
||||
* integration_title: 'Amazon CloudFront',
|
||||
* is_enabled: true
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
export interface InstalledPackage extends InstalledPackageBasicInfo {
|
||||
integrations: InstalledIntegrationBasicInfo[];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Installed integration
|
||||
|
||||
/**
|
||||
* Basic information about an installed Fleet integration.
|
||||
* An integration belongs to a package. A package can contain one or many integrations.
|
||||
*/
|
||||
export interface InstalledIntegrationBasicInfo {
|
||||
/**
|
||||
* Name identifies an integration within its package.
|
||||
* @example 'cloudtrail'
|
||||
*/
|
||||
integration_name: string;
|
||||
|
||||
/**
|
||||
* Title is a user-friendly name of the integration that we show in the UI.
|
||||
* @example 'AWS CloudTrail'
|
||||
*/
|
||||
integration_title: string;
|
||||
|
||||
/**
|
||||
* Whether this integration is enabled or not in at least one package policy in Fleet.
|
||||
*/
|
||||
is_enabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about an installed Fleet integration including info about its package.
|
||||
*
|
||||
* @example
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integration_name: 'cloudtrail',
|
||||
* integration_title: 'AWS CloudTrail',
|
||||
* is_enabled: false
|
||||
* }
|
||||
*
|
||||
* @example
|
||||
* {
|
||||
* package_name: 'system',
|
||||
* package_title: 'System',
|
||||
* package_version: '1.13.0',
|
||||
* is_enabled: true
|
||||
* }
|
||||
*/
|
||||
export interface InstalledIntegration extends InstalledPackageBasicInfo {
|
||||
/**
|
||||
* Name identifies an integration within its package.
|
||||
* Undefined when package name === integration name. This indicates that it's the only integration
|
||||
* within this package.
|
||||
* @example 'cloudtrail'
|
||||
* @example undefined
|
||||
*/
|
||||
integration_name?: string;
|
||||
|
||||
/**
|
||||
* Title is a user-friendly name of the integration that we show in the UI.
|
||||
* Undefined when package name === integration name. This indicates that it's the only integration
|
||||
* within this package.
|
||||
* @example 'AWS CloudTrail'
|
||||
* @example undefined
|
||||
*/
|
||||
integration_title?: string;
|
||||
|
||||
/**
|
||||
* Whether this integration is enabled or not in at least one package policy in Fleet.
|
||||
*/
|
||||
is_enabled: boolean;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Arrays of installed packages and integrations
|
||||
|
||||
/**
|
||||
* An array of installed packages with their integrations.
|
||||
* This is a hierarchical way of representing installed integrations.
|
||||
*
|
||||
* @example
|
||||
* [
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integrations: [
|
||||
* {
|
||||
* integration_name: 'billing',
|
||||
* integration_title: 'AWS Billing',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudtrail',
|
||||
* integration_title: 'AWS CloudTrail',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudwatch',
|
||||
* integration_title: 'AWS CloudWatch',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* integration_name: 'cloudfront',
|
||||
* integration_title: 'Amazon CloudFront',
|
||||
* is_enabled: true
|
||||
* }
|
||||
* ]
|
||||
* },
|
||||
* {
|
||||
* package_name: 'system',
|
||||
* package_title: 'System',
|
||||
* package_version: '1.13.0',
|
||||
* integrations: [
|
||||
* {
|
||||
* integration_name: 'system',
|
||||
* integration_title: 'System logs and metrics',
|
||||
* is_enabled: true
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
export type InstalledPackageArray = InstalledPackage[];
|
||||
|
||||
/**
|
||||
* An array of installed integrations with info about their packages.
|
||||
* This is a flattened way of representing installed integrations.
|
||||
*
|
||||
* @example
|
||||
* [
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integration_name: 'billing',
|
||||
* integration_title: 'AWS Billing',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integration_name: 'cloudtrail',
|
||||
* integration_title: 'AWS CloudTrail',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integration_name: 'cloudwatch',
|
||||
* integration_title: 'AWS CloudWatch',
|
||||
* is_enabled: false
|
||||
* },
|
||||
* {
|
||||
* package_name: 'aws',
|
||||
* package_title: 'AWS',
|
||||
* package_version: '1.16.1',
|
||||
* integration_name: 'cloudfront',
|
||||
* integration_title: 'Amazon CloudFront',
|
||||
* is_enabled: true
|
||||
* },
|
||||
* {
|
||||
* package_name: 'system',
|
||||
* package_title: 'System',
|
||||
* package_version: '1.13.0',
|
||||
* is_enabled: true
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
export type InstalledIntegrationArray = InstalledIntegration[];
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { InstalledIntegrationArray } from '../common';
|
||||
|
||||
export interface GetInstalledIntegrationsResponse {
|
||||
installed_integrations: InstalledIntegrationArray;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import type { MockedKeys } from '@kbn/utility-types/jest';
|
||||
import type { AwaitedProperties } from '@kbn/utility-types';
|
||||
import type { KibanaRequest } from '@kbn/core/server';
|
||||
import { coreMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server';
|
||||
|
@ -31,6 +32,7 @@ import type {
|
|||
SecuritySolutionApiRequestHandlerContext,
|
||||
SecuritySolutionRequestHandlerContext,
|
||||
} from '../../../../types';
|
||||
|
||||
import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint/service/authz';
|
||||
import { EndpointAuthz } from '../../../../../common/endpoint/types/authz';
|
||||
|
||||
|
@ -125,6 +127,14 @@ const createSecuritySolutionRequestContextMock = (
|
|||
getRuleDataService: jest.fn(() => clients.ruleDataService),
|
||||
getRuleExecutionLog: jest.fn(() => clients.ruleExecutionLog),
|
||||
getExceptionListClient: jest.fn(() => clients.lists.exceptionListClient),
|
||||
getInternalFleetServices: jest.fn(() => {
|
||||
// TODO: Mock EndpointInternalFleetServicesInterface and return the mocked object.
|
||||
throw new Error('Not implemented');
|
||||
}),
|
||||
getScopedFleetServices: jest.fn((req: KibanaRequest) => {
|
||||
// TODO: Mock EndpointScopedFleetServicesInterface and return the mocked object.
|
||||
throw new Error('Not implemented');
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import { DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL } from '../../../../../../common/constants';
|
||||
import { GetInstalledIntegrationsResponse } from '../../../../../../common/detection_engine/schemas/response/get_installed_integrations_response_schema';
|
||||
import { buildSiemResponse } from '../../utils';
|
||||
import { createInstalledIntegrationSet } from './installed_integration_set';
|
||||
|
||||
/**
|
||||
* Returns an array of installed Fleet integrations and their packages.
|
||||
*/
|
||||
export const getInstalledIntegrationsRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.get(
|
||||
{
|
||||
path: DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL,
|
||||
validate: {},
|
||||
options: {
|
||||
tags: ['access:securitySolution'],
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const ctx = await context.resolve(['core', 'securitySolution']);
|
||||
const fleet = ctx.securitySolution.getInternalFleetServices();
|
||||
const soClient = ctx.core.savedObjects.client;
|
||||
const set = createInstalledIntegrationSet();
|
||||
|
||||
const packagePolicies = await fleet.packagePolicy.list(soClient, {});
|
||||
|
||||
packagePolicies.items.forEach((policy) => {
|
||||
set.addPackagePolicy(policy);
|
||||
});
|
||||
|
||||
const registryPackages = await Promise.all(
|
||||
set.getPackages().map((packageInfo) => {
|
||||
return fleet.packages.getRegistryPackage(
|
||||
packageInfo.package_name,
|
||||
packageInfo.package_version
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
registryPackages.forEach((registryPackage) => {
|
||||
set.addRegistryPackage(registryPackage.packageInfo);
|
||||
});
|
||||
|
||||
const installedIntegrations = set.getIntegrations();
|
||||
|
||||
const body: GetInstalledIntegrationsResponse = {
|
||||
installed_integrations: installedIntegrations,
|
||||
};
|
||||
|
||||
return response.ok({ body });
|
||||
} catch (err) {
|
||||
const error = transformError(err);
|
||||
return siemResponse.error({
|
||||
body: error.message,
|
||||
statusCode: error.statusCode,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* 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 { flatten } from 'lodash';
|
||||
import { PackagePolicy, RegistryPackage } from '@kbn/fleet-plugin/common';
|
||||
import {
|
||||
InstalledIntegration,
|
||||
InstalledIntegrationArray,
|
||||
InstalledIntegrationBasicInfo,
|
||||
InstalledPackage,
|
||||
InstalledPackageArray,
|
||||
InstalledPackageBasicInfo,
|
||||
} from '../../../../../../common/detection_engine/schemas/common';
|
||||
|
||||
export interface IInstalledIntegrationSet {
|
||||
addPackagePolicy(policy: PackagePolicy): void;
|
||||
addRegistryPackage(registryPackage: RegistryPackage): void;
|
||||
|
||||
getPackages(): InstalledPackageArray;
|
||||
getIntegrations(): InstalledIntegrationArray;
|
||||
}
|
||||
|
||||
type PackageMap = Map<string, PackageInfo>;
|
||||
|
||||
interface PackageInfo extends InstalledPackageBasicInfo {
|
||||
integrations: Map<string, InstalledIntegrationBasicInfo>;
|
||||
}
|
||||
|
||||
export const createInstalledIntegrationSet = (): IInstalledIntegrationSet => {
|
||||
const packageMap: PackageMap = new Map<string, PackageInfo>([]);
|
||||
|
||||
const addPackagePolicy = (policy: PackagePolicy): void => {
|
||||
const packageInfo = getPackageInfoFromPolicy(policy);
|
||||
const integrationsInfo = getIntegrationsInfoFromPolicy(policy);
|
||||
const packageKey = `${packageInfo.package_name}:${packageInfo.package_version}`;
|
||||
const existingPackageInfo = packageMap.get(packageKey);
|
||||
|
||||
if (existingPackageInfo == null) {
|
||||
const integrationsMap = new Map<string, InstalledIntegrationBasicInfo>();
|
||||
integrationsInfo.forEach((integration) => {
|
||||
addIntegrationToMap(integrationsMap, integration);
|
||||
});
|
||||
|
||||
packageMap.set(packageKey, {
|
||||
...packageInfo,
|
||||
integrations: integrationsMap,
|
||||
});
|
||||
} else {
|
||||
integrationsInfo.forEach((integration) => {
|
||||
addIntegrationToMap(existingPackageInfo.integrations, integration);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const addRegistryPackage = (registryPackage: RegistryPackage): void => {
|
||||
const policyTemplates = registryPackage.policy_templates ?? [];
|
||||
const packageKey = `${registryPackage.name}:${registryPackage.version}`;
|
||||
const existingPackageInfo = packageMap.get(packageKey);
|
||||
|
||||
if (existingPackageInfo != null) {
|
||||
for (const integration of existingPackageInfo.integrations.values()) {
|
||||
const policyTemplate = policyTemplates.find((t) => t.name === integration.integration_name);
|
||||
if (policyTemplate != null) {
|
||||
integration.integration_title = policyTemplate.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getPackages = (): InstalledPackageArray => {
|
||||
const packages = Array.from(packageMap.values());
|
||||
return packages.map((packageInfo): InstalledPackage => {
|
||||
const integrations = Array.from(packageInfo.integrations.values());
|
||||
return { ...packageInfo, integrations };
|
||||
});
|
||||
};
|
||||
|
||||
const getIntegrations = (): InstalledIntegrationArray => {
|
||||
const packages = Array.from(packageMap.values());
|
||||
return flatten(
|
||||
packages.map((packageInfo): InstalledIntegrationArray => {
|
||||
const integrations = Array.from(packageInfo.integrations.values());
|
||||
return integrations.map((integrationInfo): InstalledIntegration => {
|
||||
return packageInfo.package_name === integrationInfo.integration_name
|
||||
? {
|
||||
package_name: packageInfo.package_name,
|
||||
package_title: packageInfo.package_title,
|
||||
package_version: packageInfo.package_version,
|
||||
is_enabled: integrationInfo.is_enabled,
|
||||
}
|
||||
: {
|
||||
package_name: packageInfo.package_name,
|
||||
package_title: packageInfo.package_title,
|
||||
package_version: packageInfo.package_version,
|
||||
integration_name: integrationInfo.integration_name,
|
||||
integration_title: integrationInfo.integration_title,
|
||||
is_enabled: integrationInfo.is_enabled,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
addPackagePolicy,
|
||||
addRegistryPackage,
|
||||
getPackages,
|
||||
getIntegrations,
|
||||
};
|
||||
};
|
||||
|
||||
const getPackageInfoFromPolicy = (policy: PackagePolicy): InstalledPackageBasicInfo => {
|
||||
return {
|
||||
package_name: normalizeString(policy.package?.name),
|
||||
package_title: normalizeString(policy.package?.title),
|
||||
package_version: normalizeString(policy.package?.version),
|
||||
};
|
||||
};
|
||||
|
||||
const getIntegrationsInfoFromPolicy = (policy: PackagePolicy): InstalledIntegrationBasicInfo[] => {
|
||||
return policy.inputs.map((input) => {
|
||||
return {
|
||||
integration_name: normalizeString(input.policy_template),
|
||||
integration_title: '', // this gets initialized later in addRegistryPackage()
|
||||
is_enabled: input.enabled,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const normalizeString = (raw: string | null | undefined): string => {
|
||||
return (raw ?? '').trim();
|
||||
};
|
||||
|
||||
const addIntegrationToMap = (
|
||||
map: Map<string, InstalledIntegrationBasicInfo>,
|
||||
integration: InstalledIntegrationBasicInfo
|
||||
): void => {
|
||||
if (!map.has(integration.integration_name) || integration.is_enabled) {
|
||||
map.set(integration.integration_name, integration);
|
||||
}
|
||||
};
|
|
@ -147,7 +147,14 @@ export class Plugin implements ISecuritySolutionPlugin {
|
|||
const eventLogService = plugins.eventLog;
|
||||
registerEventLogProvider(eventLogService);
|
||||
|
||||
const requestContextFactory = new RequestContextFactory({ config, logger, core, plugins });
|
||||
const requestContextFactory = new RequestContextFactory({
|
||||
config,
|
||||
logger,
|
||||
core,
|
||||
plugins,
|
||||
endpointAppContextService: this.endpointAppContextService,
|
||||
});
|
||||
|
||||
const router = core.http.createRouter<SecuritySolutionRequestHandlerContext>();
|
||||
core.http.registerRouteHandlerContext<SecuritySolutionRequestHandlerContext, typeof APP_ID>(
|
||||
APP_ID,
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
getEndpointAuthzInitialState,
|
||||
} from '../common/endpoint/service/authz';
|
||||
import { licenseService } from './lib/license';
|
||||
import { EndpointAppContextService } from './endpoint/endpoint_app_context_services';
|
||||
|
||||
export interface IRequestContextFactory {
|
||||
create(
|
||||
|
@ -43,6 +44,7 @@ interface ConstructorOptions {
|
|||
logger: Logger;
|
||||
core: SecuritySolutionPluginCoreSetupDependencies;
|
||||
plugins: SecuritySolutionPluginSetupDependencies;
|
||||
endpointAppContextService: EndpointAppContextService;
|
||||
}
|
||||
|
||||
export class RequestContextFactory implements IRequestContextFactory {
|
||||
|
@ -57,7 +59,7 @@ export class RequestContextFactory implements IRequestContextFactory {
|
|||
request: KibanaRequest
|
||||
): Promise<SecuritySolutionApiRequestHandlerContext> {
|
||||
const { options, appClientFactory } = this;
|
||||
const { config, logger, core, plugins } = options;
|
||||
const { config, logger, core, plugins, endpointAppContextService } = options;
|
||||
const { lists, ruleRegistry, security } = plugins;
|
||||
|
||||
const [, startPlugins] = await core.getStartServices();
|
||||
|
@ -122,6 +124,12 @@ export class RequestContextFactory implements IRequestContextFactory {
|
|||
const username = security?.authc.getCurrentUser(request)?.username || 'elastic';
|
||||
return lists.getExceptionListClient(coreContext.savedObjects.client, username);
|
||||
},
|
||||
|
||||
getInternalFleetServices: memoize(() => endpointAppContextService.getInternalFleetServices()),
|
||||
|
||||
getScopedFleetServices: memoize((req: KibanaRequest) =>
|
||||
endpointAppContextService.getScopedFleetServices(req)
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ import { legacyCreateLegacyNotificationRoute } from '../lib/detection_engine/rou
|
|||
import { createSourcererDataViewRoute, getSourcererDataViewRoute } from '../lib/sourcerer/routes';
|
||||
import { ITelemetryReceiver } from '../lib/telemetry/receiver';
|
||||
import { telemetryDetectionRulesPreviewRoute } from '../lib/detection_engine/routes/telemetry/telemetry_detection_rules_preview_route';
|
||||
import { getInstalledIntegrationsRoute } from '../lib/detection_engine/routes/fleet/get_installed_integrations/get_installed_integrations_route';
|
||||
|
||||
export const initRoutes = (
|
||||
router: SecuritySolutionPluginRouter,
|
||||
|
@ -118,6 +119,8 @@ export const initRoutes = (
|
|||
|
||||
getRuleExecutionEventsRoute(router);
|
||||
|
||||
getInstalledIntegrationsRoute(router);
|
||||
|
||||
createTimelinesRoute(router, config, security);
|
||||
patchTimelinesRoute(router, config, security);
|
||||
importRulesRoute(router, config, ml);
|
||||
|
|
|
@ -9,6 +9,7 @@ import type {
|
|||
IRouter,
|
||||
CustomRequestHandlerContext,
|
||||
CoreRequestHandlerContext,
|
||||
KibanaRequest,
|
||||
} from '@kbn/core/server';
|
||||
import type { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server';
|
||||
import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server';
|
||||
|
@ -22,6 +23,10 @@ import { ConfigType } from './config';
|
|||
import { IRuleExecutionLogForRoutes } from './lib/detection_engine/rule_execution_log';
|
||||
import { FrameworkRequest } from './lib/framework';
|
||||
import { EndpointAuthz } from '../common/endpoint/types/authz';
|
||||
import {
|
||||
EndpointInternalFleetServicesInterface,
|
||||
EndpointScopedFleetServicesInterface,
|
||||
} from './endpoint/services/fleet';
|
||||
|
||||
export { AppClient };
|
||||
|
||||
|
@ -35,6 +40,8 @@ export interface SecuritySolutionApiRequestHandlerContext {
|
|||
getRuleDataService: () => IRuleDataService;
|
||||
getRuleExecutionLog: () => IRuleExecutionLogForRoutes;
|
||||
getExceptionListClient: () => ExceptionListClient | null;
|
||||
getInternalFleetServices: () => EndpointInternalFleetServicesInterface;
|
||||
getScopedFleetServices: (req: KibanaRequest) => EndpointScopedFleetServicesInterface;
|
||||
}
|
||||
|
||||
export type SecuritySolutionRequestHandlerContext = CustomRequestHandlerContext<{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue