Skip to content

Commit

Permalink
[Osquery] Fix issue with plugin initialization (#100208) (#104562)
Browse files Browse the repository at this point in the history
Co-authored-by: Patryk Kopyciński <patryk.kopycinski@elastic.co>
  • Loading branch information
kibanamachine and patrykkopycinski authored Jul 7, 2021
1 parent cb899fe commit 04dbcec
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 79 deletions.
16 changes: 2 additions & 14 deletions x-pack/plugins/fleet/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import type {
PluginInitializerContext,
SavedObjectsServiceStart,
HttpServiceSetup,
SavedObjectsClientContract,
RequestHandlerContext,
KibanaRequest,
} from 'kibana/server';
Expand All @@ -30,12 +29,7 @@ import type {
} from '../../encrypted_saved_objects/server';
import type { SecurityPluginSetup, SecurityPluginStart } from '../../security/server';
import type { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import type {
EsAssetReference,
FleetConfigType,
NewPackagePolicy,
UpdatePackagePolicy,
} from '../common';
import type { FleetConfigType, NewPackagePolicy, UpdatePackagePolicy } from '../common';
import { INTEGRATIONS_PLUGIN_ID } from '../common';
import type { CloudSetup } from '../../cloud/server';

Expand Down Expand Up @@ -309,13 +303,7 @@ export class FleetPlugin
}),
esIndexPatternService: new ESIndexPatternSavedObjectService(),
packageService: {
getInstalledEsAssetReferences: async (
savedObjectsClient: SavedObjectsClientContract,
pkgName: string
): Promise<EsAssetReference[]> => {
const installation = await getInstallation({ savedObjectsClient, pkgName });
return installation?.installed_es || [];
},
getInstallation,
},
agentService: {
getAgent: getAgentById,
Expand Down
8 changes: 3 additions & 5 deletions x-pack/plugins/fleet/server/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
import type { KibanaRequest } from 'kibana/server';
import type { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server';

import type { AgentStatus, Agent, EsAssetReference } from '../types';
import type { AgentStatus, Agent } from '../types';

import type { getAgentById, getAgentsByKuery } from './agents';
import type { agentPolicyService } from './agent_policy';
import * as settingsService from './settings';
import type { getInstallation } from './epm/packages';

export { ESIndexPatternSavedObjectService } from './es_index_pattern';
export { getRegistryUrl } from './epm/registry/registry_url';
Expand All @@ -33,10 +34,7 @@ export interface ESIndexPatternService {
*/

export interface PackageService {
getInstalledEsAssetReferences(
savedObjectsClient: SavedObjectsClientContract,
pkgName: string
): Promise<EsAssetReference[]>;
getInstallation: typeof getInstallation;
}

/**
Expand Down
40 changes: 19 additions & 21 deletions x-pack/plugins/osquery/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ import { Storage } from '../../../../src/plugins/kibana_utils/public';
import {
OsqueryPluginSetup,
OsqueryPluginStart,
// SetupPlugins,
StartPlugins,
AppPluginStartDependencies,
} from './types';
import { OSQUERY_INTEGRATION_NAME, PLUGIN_NAME } from '../common';
import { epmRouteService, GetPackagesResponse } from '../../fleet/common';
import { Installation } from '../../fleet/common';
import {
LazyOsqueryManagedPolicyCreateImportExtension,
LazyOsqueryManagedPolicyEditExtension,
Expand All @@ -47,12 +46,9 @@ export function toggleOsqueryPlugin(
}

http
.fetch<GetPackagesResponse>(epmRouteService.getListPath(), { query: { experimental: true } })
.then(({ response }) => {
const installed = response.find(
(integration) =>
integration?.name === OSQUERY_INTEGRATION_NAME && integration?.status === 'installed'
);
.fetch<Installation | undefined>(`/internal/osquery/status`)
.then((response) => {
const installed = response?.install_status === 'installed';

if (installed && registerExtension) {
registerExtension({
Expand Down Expand Up @@ -137,24 +133,26 @@ export class OsqueryPlugin implements Plugin<OsqueryPluginSetup, OsqueryPluginSt
packs: boolean;
}>();

if (!config.enabled) {
return {};
}

if (plugins.fleet) {
const { registerExtension } = plugins.fleet;

if (config.enabled) {
toggleOsqueryPlugin(this.appUpdater$, core.http, registerExtension);
toggleOsqueryPlugin(this.appUpdater$, core.http, registerExtension);

registerExtension({
package: OSQUERY_INTEGRATION_NAME,
view: 'package-policy-create',
Component: LazyOsqueryManagedPolicyCreateImportExtension,
});
registerExtension({
package: OSQUERY_INTEGRATION_NAME,
view: 'package-policy-create',
Component: LazyOsqueryManagedPolicyCreateImportExtension,
});

registerExtension({
package: OSQUERY_INTEGRATION_NAME,
view: 'package-policy-edit',
Component: LazyOsqueryManagedPolicyEditExtension,
});
}
registerExtension({
package: OSQUERY_INTEGRATION_NAME,
view: 'package-policy-edit',
Component: LazyOsqueryManagedPolicyEditExtension,
});
} else {
this.appUpdater$.next(() => ({
status: AppStatus.inaccessible,
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/osquery/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { IRouter } from '../../../../../src/core/server';
import { initActionRoutes } from './action';
import { OsqueryAppContext } from '../lib/osquery_app_context_services';
import { initSavedQueryRoutes } from './saved_query';
import { initStatusRoutes } from './status';
import { initPackRoutes } from './pack';

export const defineRoutes = (router: IRouter, context: OsqueryAppContext) => {
const config = context.config();

initActionRoutes(router, context);
initStatusRoutes(router, context);

if (config.packs) {
initPackRoutes(router);
Expand Down
35 changes: 35 additions & 0 deletions x-pack/plugins/osquery/server/routes/status/create_status_route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 { OSQUERY_INTEGRATION_NAME } from '../../../common';
import { IRouter } from '../../../../../../src/core/server';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

export const createStatusRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
path: '/internal/osquery/status',
validate: false,
},
async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const isSuperUser = osqueryContext.security.authc
.getCurrentUser(request)
?.roles.includes('superuser');

if (!isSuperUser) {
return response.ok({ body: undefined });
}

const packageInfo = await osqueryContext.service
.getPackageService()
?.getInstallation({ savedObjectsClient: soClient, pkgName: OSQUERY_INTEGRATION_NAME });

return response.ok({ body: packageInfo });
}
);
};
14 changes: 14 additions & 0 deletions x-pack/plugins/osquery/server/routes/status/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 { IRouter } from '../../../../../../src/core/server';
import { createStatusRoute } from './create_status_route';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

export const initStatusRoutes = (router: IRouter, context: OsqueryAppContext) => {
createStatusRoute(router, context);
};
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ export const createMetadataService = (packageService: PackageService): MetadataS
}

if (version === MetadataQueryStrategyVersions.VERSION_2 || !version) {
const assets = await packageService.getInstalledEsAssetReferences(
savedObjectsClient,
'endpoint'
);
const assets =
(await packageService.getInstallation({ savedObjectsClient, pkgName: 'endpoint' }))
?.installed_es ?? [];
const expectedTransformAssets = assets.filter(
(ref) =>
ref.type === ElasticsearchAssetType.transform &&
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/server/endpoint/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export const createMockEndpointAppContextServiceStartContract = (): jest.Mocked<

export const createMockPackageService = (): jest.Mocked<PackageService> => {
return {
getInstalledEsAssetReferences: jest.fn(),
getInstallation: jest.fn(),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,29 @@ describe('Host Isolation', () => {
endpointAppContextService = new EndpointAppContextService();
const mockSavedObjectClient = savedObjectsClientMock.create();
const mockPackageService = createMockPackageService();
mockPackageService.getInstalledEsAssetReferences.mockReturnValue(
Promise.resolve([
{
id: 'logs-endpoint.events.security',
type: ElasticsearchAssetType.indexTemplate,
},
{
id: `${metadataTransformPrefix}-0.16.0-dev.0`,
type: ElasticsearchAssetType.transform,
},
])
mockPackageService.getInstallation.mockReturnValue(
Promise.resolve({
installed_kibana: [],
package_assets: [],
es_index_patterns: {},
name: '',
version: '',
install_status: 'installed',
install_version: '',
install_started_at: '',
install_source: 'registry',
installed_es: [
{
dupa: true,
id: 'logs-endpoint.events.security',
type: ElasticsearchAssetType.indexTemplate,
},
{
id: `${metadataTransformPrefix}-0.16.0-dev.0`,
type: ElasticsearchAssetType.transform,
},
],
})
);
licenseEmitter = new Subject();
licenseService = new LicenseService();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ import {
} from '../../endpoint_app_context_services';
import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__';
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';
import {
Agent,
ElasticsearchAssetType,
EsAssetReference,
} from '../../../../../fleet/common/types/models';
import { Agent, ElasticsearchAssetType } from '../../../../../fleet/common/types/models';
import { createV1SearchResponse, createV2SearchResponse } from './support/test_support';
import { PackageService } from '../../../../../fleet/server/services';
import {
Expand Down Expand Up @@ -106,9 +102,7 @@ describe('test endpoint route', () => {
beforeEach(() => {
endpointAppContextService = new EndpointAppContextService();
mockPackageService = createMockPackageService();
mockPackageService.getInstalledEsAssetReferences.mockReturnValue(
Promise.resolve(([] as unknown) as EsAssetReference[])
);
mockPackageService.getInstallation.mockReturnValue(Promise.resolve(undefined));
endpointAppContextService.start({ ...startContract, packageService: mockPackageService });
mockAgentService = startContract.agentService!;

Expand Down Expand Up @@ -196,17 +190,28 @@ describe('test endpoint route', () => {
beforeEach(() => {
endpointAppContextService = new EndpointAppContextService();
mockPackageService = createMockPackageService();
mockPackageService.getInstalledEsAssetReferences.mockReturnValue(
Promise.resolve([
{
id: 'logs-endpoint.events.security',
type: ElasticsearchAssetType.indexTemplate,
},
{
id: `${metadataTransformPrefix}-0.16.0-dev.0`,
type: ElasticsearchAssetType.transform,
},
])
mockPackageService.getInstallation.mockReturnValue(
Promise.resolve({
installed_kibana: [],
package_assets: [],
es_index_patterns: {},
name: '',
version: '',
install_status: 'installed',
install_version: '',
install_started_at: '',
install_source: 'registry',
installed_es: [
{
id: 'logs-endpoint.events.security',
type: ElasticsearchAssetType.indexTemplate,
},
{
id: `${metadataTransformPrefix}-0.16.0-dev.0`,
type: ElasticsearchAssetType.transform,
},
],
})
);
endpointAppContextService.start({ ...startContract, packageService: mockPackageService });
mockAgentService = startContract.agentService!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import {
import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__';
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';
import { parseExperimentalConfigValue } from '../../../../common/experimental_features';
import { Agent, EsAssetReference } from '../../../../../fleet/common/types/models';
import { Agent } from '../../../../../fleet/common/types/models';
import { createV1SearchResponse } from './support/test_support';
import { PackageService } from '../../../../../fleet/server/services';
import type { SecuritySolutionPluginRouter } from '../../../types';
Expand Down Expand Up @@ -82,9 +82,7 @@ describe('test endpoint route v1', () => {
mockResponse = httpServerMock.createResponseFactory();
endpointAppContextService = new EndpointAppContextService();
mockPackageService = createMockPackageService();
mockPackageService.getInstalledEsAssetReferences.mockReturnValue(
Promise.resolve(([] as unknown) as EsAssetReference[])
);
mockPackageService.getInstallation.mockReturnValue(Promise.resolve(undefined));
startContract = createMockEndpointAppContextServiceStartContract();
endpointAppContextService.start({ ...startContract, packageService: mockPackageService });
mockAgentService = startContract.agentService!;
Expand Down

0 comments on commit 04dbcec

Please sign in to comment.