Migrates security solution usage collector es client from legacy to new (#86853)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Christiane (Tina) Heiligers 2021-01-04 14:17:56 -07:00 committed by GitHub
parent afc2c51f43
commit 8b2690723b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 34 deletions

View file

@ -78,12 +78,12 @@ export const registerCollector: RegisterCollector = ({
},
},
isReady: () => kibanaIndex.length > 0,
fetch: async ({ callCluster }: CollectorFetchContext): Promise<UsageData> => {
fetch: async ({ esClient }: CollectorFetchContext): Promise<UsageData> => {
const savedObjectsClient = await getInternalSavedObjectsClient(core);
const [detections, endpoints] = await Promise.allSettled([
fetchDetectionsUsage(
kibanaIndex,
callCluster,
esClient,
ml,
(savedObjectsClient as unknown) as SavedObjectsClientContract
),

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { LegacyAPICaller, SavedObjectsClientContract } from '../../../../../../src/core/server';
import { ElasticsearchClient, SavedObjectsClientContract } from '../../../../../../src/core/server';
import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks';
import { mlServicesMock } from '../../lib/machine_learning/mocks';
import {
@ -16,22 +16,17 @@ import { fetchDetectionsUsage } from './index';
describe('Detections Usage', () => {
describe('fetchDetectionsUsage()', () => {
let callClusterMock: jest.Mocked<LegacyAPICaller>;
let esClientMock: jest.Mocked<ElasticsearchClient>;
let savedObjectsClientMock: jest.Mocked<SavedObjectsClientContract>;
let mlMock: ReturnType<typeof mlServicesMock.create>;
beforeEach(() => {
callClusterMock = elasticsearchServiceMock.createLegacyClusterClient().callAsInternalUser;
esClientMock = elasticsearchServiceMock.createClusterClient().asInternalUser;
mlMock = mlServicesMock.create();
});
it('returns zeroed counts if both calls are empty', async () => {
const result = await fetchDetectionsUsage(
'',
callClusterMock,
mlMock,
savedObjectsClientMock
);
const result = await fetchDetectionsUsage('', esClientMock, mlMock, savedObjectsClientMock);
expect(result).toEqual({
detection_rules: {
@ -58,13 +53,9 @@ describe('Detections Usage', () => {
});
it('tallies rules data given rules results', async () => {
(callClusterMock as jest.Mock).mockResolvedValue(getMockRulesResponse());
const result = await fetchDetectionsUsage(
'',
callClusterMock,
mlMock,
savedObjectsClientMock
);
(esClientMock.search as jest.Mock).mockResolvedValue({ body: getMockRulesResponse() });
const result = await fetchDetectionsUsage('', esClientMock, mlMock, savedObjectsClientMock);
expect(result).toEqual(
expect.objectContaining({
@ -92,12 +83,7 @@ describe('Detections Usage', () => {
jobsSummary: mockJobSummary,
});
const result = await fetchDetectionsUsage(
'',
callClusterMock,
mlMock,
savedObjectsClientMock
);
const result = await fetchDetectionsUsage('', esClientMock, mlMock, savedObjectsClientMock);
expect(result).toEqual(
expect.objectContaining({

View file

@ -4,12 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { SearchParams } from 'elasticsearch';
import {
LegacyAPICaller,
ElasticsearchClient,
SavedObjectsClientContract,
KibanaRequest,
SearchResponse,
} from '../../../../../../src/core/server';
import { MlPluginSetup } from '../../../../ml/server';
import { SIGNALS_ID, INTERNAL_IMMUTABLE_KEY } from '../../../common/constants';
@ -22,6 +21,26 @@ interface DetectionsMetric {
isEnabled: boolean;
}
interface RuleSearchBody {
query: {
bool: {
filter: {
term: { [key: string]: string };
};
};
};
}
interface RuleSearchParams {
body: RuleSearchBody;
filterPath: string[];
ignoreUnavailable: boolean;
index: string;
size: number;
}
interface RuleSearchResult {
alert: { enabled: boolean; tags: string[] };
}
const isElasticRule = (tags: string[]) => tags.includes(`${INTERNAL_IMMUTABLE_KEY}:true`);
/**
@ -135,10 +154,10 @@ const updateMlJobsUsage = (jobMetric: DetectionsMetric, usage: MlJobsUsage): MlJ
export const getRulesUsage = async (
index: string,
callCluster: LegacyAPICaller
esClient: ElasticsearchClient
): Promise<DetectionRulesUsage> => {
let rulesUsage: DetectionRulesUsage = initialRulesUsage;
const ruleSearchOptions: SearchParams = {
const ruleSearchOptions: RuleSearchParams = {
body: { query: { bool: { filter: { term: { 'alert.alertTypeId': SIGNALS_ID } } } } },
filterPath: ['hits.hits._source.alert.enabled', 'hits.hits._source.alert.tags'],
ignoreUnavailable: true,
@ -147,8 +166,7 @@ export const getRulesUsage = async (
};
try {
const ruleResults = await callCluster<{ alert: { enabled: boolean; tags: string[] } }>(
'search',
const { body: ruleResults } = await esClient.search<SearchResponse<RuleSearchResult>>(
ruleSearchOptions
);

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { LegacyAPICaller, SavedObjectsClientContract } from '../../../../../../src/core/server';
import { ElasticsearchClient, SavedObjectsClientContract } from '../../../../../../src/core/server';
import {
getMlJobsUsage,
getRulesUsage,
@ -40,12 +40,12 @@ export const defaultDetectionsUsage = {
export const fetchDetectionsUsage = async (
kibanaIndex: string,
callCluster: LegacyAPICaller,
esClient: ElasticsearchClient,
ml: MlPluginSetup | undefined,
savedObjectClient: SavedObjectsClientContract
): Promise<DetectionsUsage> => {
const [rulesUsage, mlJobsUsage] = await Promise.allSettled([
getRulesUsage(kibanaIndex, callCluster),
getRulesUsage(kibanaIndex, esClient),
getMlJobsUsage(ml, savedObjectClient),
]);