Skip to content

Commit

Permalink
[SIEM] Server NP Followup (#64010)
Browse files Browse the repository at this point in the history
* Remove unused file

This was moved to a constant in common/constants.

* Remove unused types

Omit is now part of Typescript, and Pick3 is unused.

* Define and export SIEM's plugin contracts

They're empty for now.

* Import config type from config file

Instead of our plugin index, which could only cause circular
dependencies.

* SiemClient API uses getter function instead of direct property access

* Add public mock for SiemClient

* Fix typo in extract-mitre-attacks script

We were backgrounding the process (&) instead of ANDing it with the
linting. Whoops!

* Remove missed instance of old siemClient API

I missed this one when grepping, but typescript and CI saved me.

* Use our client mock in our test suite

This was causing some test failures as I forgot to update the client mock

* Update script following updates to the output's usage

This was changed in #55883 but the
script was not updated accordingly.
  • Loading branch information
rylnd committed Apr 21, 2020
1 parent 5a55c9a commit ff5971a
Show file tree
Hide file tree
Showing 29 changed files with 61 additions and 51 deletions.
15 changes: 0 additions & 15 deletions x-pack/plugins/siem/common/default_index_pattern.ts

This file was deleted.

6 changes: 0 additions & 6 deletions x-pack/plugins/siem/common/utility_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@

import { ReactNode } from 'react';

export type Pick3<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]> = {
[P1 in K1]: { [P2 in K2]: { [P3 in K3]: T[K1][K2][P3] } };
};

export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

// This type is for typing EuiDescriptionList
export interface DescriptionList {
title: NonNullable<ReactNode>;
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/siem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"license": "Elastic-License",
"scripts": {
"extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js & node ../../../scripts/eslint ../../legacy/plugins/siem/public/pages/detection_engine/mitre/mitre_tactics_techniques.ts --fix",
"extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ../../legacy/plugins/siem/public/pages/detection_engine/mitre/mitre_tactics_techniques.ts --fix",
"build-graphql-types": "node scripts/generate_types_from_graphql.js",
"cypress:open": "cypress open --config-file ./cypress/cypress.json",
"cypress:run": "cypress run --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../node_modules/.bin/mochawesome-merge --reportDir ../../../target/kibana-siem/cypress/results > ../../../target/kibana-siem/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-siem/cypress/results/output.json --reportDir ../../../target/kibana-siem/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-siem/cypress/results/*.xml ../../../target/junit/ && exit $status;",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ async function main() {
.replace(/}"/g, '}')
.replace(/"{/g, '{')};
export const techniques = ${JSON.stringify(techniques, null, 2)};
export const technique = ${JSON.stringify(techniques, null, 2)};
export const techniquesOptions: MitreTechniquesOptions[] =
${JSON.stringify(getTechniquesOptions(techniques), null, 2)
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/siem/server/client/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createMockConfig } from '../lib/detection_engine/routes/__mocks__';
import { SiemClient } from './client';

describe('SiemClient', () => {
describe('#signalsIndex', () => {
describe('#getSignalsIndex', () => {
it('returns the index scoped to the specified spaceId', () => {
const mockConfig = {
...createMockConfig(),
Expand All @@ -18,7 +18,7 @@ describe('SiemClient', () => {
const spaceId = 'fooSpace';
const client = new SiemClient(spaceId, mockConfig);

expect(client.signalsIndex).toEqual('mockSignalsIndex-fooSpace');
expect(client.getSignalsIndex()).toEqual('mockSignalsIndex-fooSpace');
});
});
});
6 changes: 4 additions & 2 deletions x-pack/plugins/siem/server/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { ConfigType } from '..';
import { ConfigType } from '../config';

export class SiemClient {
public readonly signalsIndex: string;
private readonly signalsIndex: string;

constructor(private spaceId: string, private config: ConfigType) {
const configuredSignalsIndex = this.config.signalsIndex;

this.signalsIndex = `${configuredSignalsIndex}-${this.spaceId}`;
}

public getSignalsIndex = (): string => this.signalsIndex;
}
2 changes: 1 addition & 1 deletion x-pack/plugins/siem/server/client/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { KibanaRequest } from '../../../../../src/core/server';
import { SiemClient } from './client';
import { ConfigType } from '..';
import { ConfigType } from '../config';

interface SetupDependencies {
getSpaceId?: (request: KibanaRequest) => string | undefined;
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/siem/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { PluginInitializerContext } from '../../../../src/core/server';
import { Plugin } from './plugin';
import { Plugin, PluginSetup, PluginStart } from './plugin';
import { configSchema, ConfigType } from './config';

export const plugin = (context: PluginInitializerContext) => {
Expand All @@ -14,4 +14,4 @@ export const plugin = (context: PluginInitializerContext) => {

export const config = { schema: configSchema };

export { ConfigType };
export { ConfigType, Plugin, PluginSetup, PluginStart };
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import {
import { alertsClientMock } from '../../../../../../alerting/server/mocks';
import { actionsClientMock } from '../../../../../../actions/server/mocks';
import { licensingMock } from '../../../../../../licensing/server/mocks';
import { siemMock } from '../../../../mocks';

const createMockClients = () => ({
actionsClient: actionsClientMock.create(),
alertsClient: alertsClientMock.create(),
clusterClient: elasticsearchServiceMock.createScopedClusterClient(),
licensing: { license: licensingMock.createLicenseMock() },
savedObjectsClient: savedObjectsClientMock.create(),
siemClient: { signalsIndex: 'mockSignalsIndex' },
siemClient: siemMock.createClient(),
});

const createRequestContextMock = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const createIndexRoute = (router: IRouter) => {
return siemResponse.error({ statusCode: 404 });
}

const index = siemClient.signalsIndex;
const index = siemClient.getSignalsIndex();
const indexExists = await getIndexExists(callCluster, index);
if (indexExists) {
return siemResponse.error({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const deleteIndexRoute = (router: IRouter) => {
}

const callCluster = clusterClient.callAsCurrentUser;
const index = siemClient.signalsIndex;
const index = siemClient.getSignalsIndex();
const indexExists = await getIndexExists(callCluster, index);

if (!indexExists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const readIndexRoute = (router: IRouter) => {
return siemResponse.error({ statusCode: 404 });
}

const index = siemClient.signalsIndex;
const index = siemClient.getSignalsIndex();
const indexExists = await getIndexExists(clusterClient.callAsCurrentUser, index);

if (indexExists) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const readPrivilegesRoute = (
return siemResponse.error({ statusCode: 404 });
}

const index = siemClient.signalsIndex;
const index = siemClient.getSignalsIndex();
const clusterPrivileges = await readPrivileges(clusterClient.callAsCurrentUser, index);
const privileges = merge(clusterPrivileges, {
is_authenticated: security?.authc.isAuthenticated(request) ?? false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const addPrepackedRulesRoute = (router: IRouter) => {
const rulesToInstall = getRulesToInstall(rulesFromFileSystem, prepackagedRules);
const rulesToUpdate = getRulesToUpdate(rulesFromFileSystem, prepackagedRules);

const { signalsIndex } = siemClient;
const signalsIndex = siemClient.getSignalsIndex();
if (rulesToInstall.length !== 0 || rulesToUpdate.length !== 0) {
const signalsIndexExists = await getIndexExists(
clusterClient.callAsCurrentUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const createRulesBulkRoute = (router: IRouter) => {
try {
validateLicenseForRuleType({ license: context.licensing.license, ruleType: type });

const finalIndex = outputIndex ?? siemClient.signalsIndex;
const finalIndex = outputIndex ?? siemClient.getSignalsIndex();
const indexExists = await getIndexExists(clusterClient.callAsCurrentUser, finalIndex);
if (!indexExists) {
return createBulkErrorObject({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const createRulesRoute = (router: IRouter): void => {
return siemResponse.error({ statusCode: 404 });
}

const finalIndex = outputIndex ?? siemClient.signalsIndex;
const finalIndex = outputIndex ?? siemClient.getSignalsIndex();
const indexExists = await getIndexExists(clusterClient.callAsCurrentUser, finalIndex);
if (!indexExists) {
return siemResponse.error({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { IRouter } from '../../../../../../../../src/core/server';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { ConfigType } from '../../../..';
import { ConfigType } from '../../../../config';
import { ExportRulesRequestParams } from '../../rules/types';
import { getNonPackagedRulesCount } from '../../rules/get_existing_prepackaged_rules';
import { exportRulesSchema, exportRulesQuerySchema } from '../schemas/export_rules_schema';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ describe('import_rules_route', () => {
});

test('returns an error if the index does not exist', async () => {
clients.siemClient.getSignalsIndex.mockReturnValue('mockSignalsIndex');
clients.clusterClient.callAsCurrentUser.mockResolvedValue(getEmptyIndex());
const response = await server.inject(request, context);
expect(response.status).toEqual(200);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { extname } from 'path';
import { IRouter } from '../../../../../../../../src/core/server';
import { createPromiseFromStreams } from '../../../../../../../../src/legacy/utils/streams';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { ConfigType } from '../../../..';
import { ConfigType } from '../../../../config';
import { createRules } from '../../rules/create_rules';
import { ImportRulesRequestParams } from '../../rules/types';
import { readRules } from '../../rules/read_rules';
Expand Down Expand Up @@ -147,7 +147,7 @@ export const importRulesRoute = (router: IRouter, config: ConfigType) => {
ruleType: type,
});

const signalsIndex = siemClient.signalsIndex;
const signalsIndex = siemClient.getSignalsIndex();
const indexExists = await getIndexExists(
clusterClient.callAsCurrentUser,
signalsIndex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const updateRulesBulkRoute = (router: IRouter) => {
version,
exceptions_list,
} = payloadRule;
const finalIndex = outputIndex ?? siemClient.signalsIndex;
const finalIndex = outputIndex ?? siemClient.getSignalsIndex();
const idOrRuleIdOrUnknown = id ?? ruleId ?? '(unknown id)';
try {
validateLicenseForRuleType({ license: context.licensing.license, ruleType: type });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const updateRulesRoute = (router: IRouter) => {
return siemResponse.error({ statusCode: 404 });
}

const finalIndex = outputIndex ?? siemClient.signalsIndex;
const finalIndex = outputIndex ?? siemClient.getSignalsIndex();
const rule = await updateRules({
alertsClient,
actionsClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const setSignalsStatusRoute = (router: IRouter) => {
}
try {
const result = await clusterClient.callAsCurrentUser('updateByQuery', {
index: siemClient.signalsIndex,
index: siemClient.getSignalsIndex(),
body: {
script: {
source: `ctx._source.signal.status = '${status}'`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const querySignalsRoute = (router: IRouter) => {

try {
const result = await clusterClient.callAsCurrentUser('search', {
index: siemClient.signalsIndex,
index: siemClient.getSignalsIndex(),
body: { query, aggs, _source, track_total_hits, size },
ignoreUnavailable: true,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { set as _set } from 'lodash/fp';

import { TIMELINE_EXPORT_URL } from '../../../../common/constants';
import { IRouter } from '../../../../../../../src/core/server';
import { ConfigType } from '../../..';
import { ConfigType } from '../../../config';
import { transformError, buildSiemResponse } from '../../detection_engine/routes/utils';

import { getExportTimelineByObjectIds } from './utils/export_timelines';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { IRouter } from '../../../../../../../src/core/server';
import { SetupPlugins } from '../../../plugin';
import { ImportTimelinesPayloadSchemaRt } from './schemas/import_timelines_schema';
import { importRulesSchema } from '../../detection_engine/routes/schemas/response/import_rules_schema';
import { ConfigType } from '../../..';
import { ConfigType } from '../../../config';

import { Timeline } from '../saved_object';
import { validate } from '../../detection_engine/routes/rules/validate';
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/siem/server/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { AuthenticatedUser } from '../../../security/public';
import { RequestHandlerContext } from '../../../../../src/core/server';
export { ConfigType as Configuration } from '../';
export { ConfigType as Configuration } from '../config';

import { Authentications } from './authentications';
import { Events } from './events';
Expand Down
17 changes: 17 additions & 0 deletions x-pack/plugins/siem/server/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { SiemClient } from './types';

type SiemClientMock = jest.Mocked<SiemClient>;
const createSiemClientMock = (): SiemClientMock =>
(({
getSignalsIndex: jest.fn(),
} as unknown) as SiemClientMock);

export const siemMock = {
createClient: createSiemClientMock,
};
14 changes: 12 additions & 2 deletions x-pack/plugins/siem/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n';
import {
CoreSetup,
CoreStart,
Plugin as IPlugin,
PluginInitializerContext,
Logger,
} from '../../../../src/core/server';
Expand Down Expand Up @@ -61,7 +62,12 @@ export interface StartPlugins {
alerting: AlertingStart;
}

export class Plugin {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface PluginSetup {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface PluginStart {}

export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, StartPlugins> {
readonly name = 'siem';
private readonly logger: Logger;
private readonly config$: Observable<ConfigType>;
Expand Down Expand Up @@ -204,7 +210,11 @@ export class Plugin {

const libs = compose(core, plugins, this.context.env.mode.prod);
initServer(libs);

return {};
}

public start(core: CoreStart, plugins: StartPlugins) {}
public start(core: CoreStart, plugins: StartPlugins) {
return {};
}
}
2 changes: 1 addition & 1 deletion x-pack/plugins/siem/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { getPrepackagedRulesStatusRoute } from '../lib/detection_engine/routes/r
import { importTimelinesRoute } from '../lib/timeline/routes/import_timelines_route';
import { exportTimelinesRoute } from '../lib/timeline/routes/export_timelines_route';
import { SetupPlugins } from '../plugin';
import { ConfigType } from '..';
import { ConfigType } from '../config';

export const initRoutes = (
router: IRouter,
Expand Down

0 comments on commit ff5971a

Please sign in to comment.