Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Osquery] Change prebuilt saved queries to include prebuilt flag #132651

Merged
merged 9 commits into from
May 23, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const EditSavedQueryPageComponent = () => {
useBreadcrumbs('saved_query_edit', { savedQueryName: savedQueryDetails?.attributes?.id ?? '' });

const elasticPrebuiltQuery = useMemo(
() => savedQueryDetails?.attributes?.version,
() => savedQueryDetails?.attributes?.prebuilt,
[savedQueryDetails]
);
const viewMode = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { isSavedQueryPrebuilt } from './utils';

export const deleteSavedQueryRoute = (router: IRouter) => {
export const deleteSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.delete(
{
path: '/internal/osquery/saved_query/{id}',
Expand All @@ -25,6 +27,11 @@ export const deleteSavedQueryRoute = (router: IRouter) => {
const coreContext = await context.core;
const savedObjectsClient = coreContext.savedObjects.client;

const isPrebuilt = await isSavedQueryPrebuilt(osqueryContext, request.params.id);
if (isPrebuilt) {
return response.conflict({ body: `Elastic prebuilt Saved query cannot be deleted.` });
}

await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, {
refresh: 'wait_for',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';

import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { convertECSMappingToObject } from '../utils';
import { getInstalledSavedQueriesMap } from './utils';

export const findSavedQueryRoute = (router: IRouter) => {
export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
path: '/internal/osquery/saved_query',
Expand All @@ -34,6 +37,7 @@ export const findSavedQueryRoute = (router: IRouter) => {

const savedQueries = await savedObjectsClient.find<{
ecs_mapping: Array<{ field: string; value: string }>;
prebuilt: boolean;
}>({
type: savedQuerySavedObjectType,
page: parseInt(request.query.pageIndex ?? '0', 10) + 1,
Expand All @@ -43,10 +47,13 @@ export const findSavedQueryRoute = (router: IRouter) => {
sortOrder: request.query.sortDirection ?? 'desc',
});

const prebuiltSavedQueriesMap = await getInstalledSavedQueriesMap(osqueryContext);
const savedObjects = savedQueries.saved_objects.map((savedObject) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const ecs_mapping = savedObject.attributes.ecs_mapping;

savedObject.attributes.prebuilt = !!prebuiltSavedQueriesMap[savedObject.id];

if (ecs_mapping) {
// @ts-expect-error update types
savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping);
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/osquery/server/routes/saved_query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

export const initSavedQueryRoutes = (router: IRouter, context: OsqueryAppContext) => {
createSavedQueryRoute(router, context);
deleteSavedQueryRoute(router);
findSavedQueryRoute(router);
readSavedQueryRoute(router);
deleteSavedQueryRoute(router, context);
findSavedQueryRoute(router, context);
readSavedQueryRoute(router, context);
updateSavedQueryRoute(router, context);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import { isSavedQueryPrebuilt } from './utils';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { convertECSMappingToObject } from '../utils';

export const readSavedQueryRoute = (router: IRouter) => {
export const readSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
path: '/internal/osquery/saved_query/{id}',
Expand All @@ -28,6 +30,7 @@ export const readSavedQueryRoute = (router: IRouter) => {

const savedQuery = await savedObjectsClient.get<{
ecs_mapping: Array<{ key: string; value: Record<string, object> }>;
prebuilt: boolean;
}>(savedQuerySavedObjectType, request.params.id);

if (savedQuery.attributes.ecs_mapping) {
Expand All @@ -37,6 +40,8 @@ export const readSavedQueryRoute = (router: IRouter) => {
);
}

savedQuery.attributes.prebuilt = await isSavedQueryPrebuilt(osqueryContext, savedQuery.id);

return response.ok({
body: savedQuery,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { filter } from 'lodash';
import { schema } from '@kbn/config-schema';

import { IRouter } from '@kbn/core/server';
import { isSavedQueryPrebuilt } from './utils';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
Expand Down Expand Up @@ -63,6 +64,12 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp
ecs_mapping,
} = request.body;

const isPrebuilt = await isSavedQueryPrebuilt(osqueryContext, request.params.id);

if (isPrebuilt) {
return response.conflict({ body: `Elastic prebuilt Saved query cannot be updated.` });
}

const conflictingEntries = await savedObjectsClient.find<{ id: string }>({
type: savedQuerySavedObjectType,
filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`,
Expand Down
54 changes: 54 additions & 0 deletions x-pack/plugins/osquery/server/routes/saved_query/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 { find, reduce } from 'lodash';
import { KibanaAssetReference } from '@kbn/fleet-plugin/common';

import { OSQUERY_INTEGRATION_NAME } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

const getInstallation = async (osqueryContext: OsqueryAppContext) =>
await osqueryContext.service
.getPackageService()
?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME);

export const getInstalledSavedQueriesMap = async (osqueryContext: OsqueryAppContext) => {
const installation = await getInstallation(osqueryContext);
if (installation) {
return reduce(
installation.installed_kibana,
// @ts-expect-error not sure why it shouts, but still it's properly typed
(acc: Record<string, KibanaAssetReference>, item: KibanaAssetReference) => {
if (item.type === savedQuerySavedObjectType) {
return { ...acc, [item.id]: item };
}
},
{}
);
}

return {};
};

export const isSavedQueryPrebuilt = async (
osqueryContext: OsqueryAppContext,
savedQueryId: string
) => {
const installation = await getInstallation(osqueryContext);

if (installation) {
const installationSavedQueries = find(
installation.installed_kibana,
(item) => item.type === savedQuerySavedObjectType && item.id === savedQueryId
);

return !!installationSavedQueries;
}

return false;
};