= ({ agentId, formType = 'simple' }) => {
const permissions = useKibana().services.application.capabilities.osquery;
- const agentId = metadata?.info?.agent?.id ?? undefined;
- const {
- data: agentData,
- isFetched: agentFetched,
- isLoading,
- } = useAgentDetails({
- agentId,
- silent: true,
- skip: !agentId,
- });
- const {
- data: agentPolicyData,
- isFetched: policyFetched,
- isError: policyError,
- isLoading: policyLoading,
- } = useAgentPolicy({
- policyId: agentData?.policy_id,
- skip: !agentData,
- silent: true,
- });
-
- const osqueryAvailable = useMemo(() => {
- if (policyError) return false;
-
- const osqueryPackageInstalled = find(agentPolicyData?.package_policies, [
- 'package.name',
- OSQUERY_INTEGRATION_NAME,
- ]);
- return osqueryPackageInstalled?.enabled;
- }, [agentPolicyData?.package_policies, policyError]);
- if (!(permissions.runSavedQueries || permissions.writeLiveQueries)) {
- return (
+ const emptyPrompt = useMemo(
+ () => (
}
- title={Permissions denied
}
+ title={
+
+ {i18n.translate('xpack.osquery.action.shortEmptyTitle', {
+ defaultMessage: 'Osquery is not available',
+ })}
+
+ }
titleSize="xs"
body={
- To access this page, ask your administrator for osquery Kibana
- privileges.
+ {i18n.translate('xpack.osquery.action.empty', {
+ defaultMessage:
+ 'An Elastic Agent is not installed on this host. To run queries, install Elastic Agent on the host, and then add the Osquery Manager integration to the agent policy in Fleet.',
+ })}
}
/>
- );
- }
+ ),
+ []
+ );
+ const { osqueryAvailable, agentFetched, isLoading, policyFetched, policyLoading, agentData } =
+ useIsOsqueryAvailable(agentId);
- if (isLoading) {
- return ;
+ if (!agentId || (agentFetched && !agentData)) {
+ return emptyPrompt;
}
- if (!agentId || (agentFetched && !agentData)) {
+ if (!(permissions.runSavedQueries || permissions.writeLiveQueries)) {
return (
}
- title={Osquery is not available
}
+ title={
+
+ {i18n.translate('xpack.osquery.action.permissionDenied', {
+ defaultMessage: 'Permission denied',
+ })}
+
+ }
titleSize="xs"
body={
- An Elastic Agent is not installed on this host. To run queries, install Elastic Agent on
- the host, and then add the Osquery Manager integration to the agent policy in Fleet.
+ To access this page, ask your administrator for osquery Kibana
+ privileges.
}
/>
);
}
+ if (isLoading) {
+ return ;
+ }
+
if (!policyFetched && policyLoading) {
return ;
}
@@ -104,12 +90,20 @@ const OsqueryActionComponent: React.FC = ({ metadata }) => {
return (
}
- title={Osquery is not available
}
+ title={
+
+ {i18n.translate('xpack.osquery.action.shortEmptyTitle', {
+ defaultMessage: 'Osquery is not available',
+ })}
+
+ }
titleSize="xs"
body={
- The Osquery Manager integration is not added to the agent policy. To run queries on the
- host, add the Osquery Manager integration to the agent policy in Fleet.
+ {i18n.translate('xpack.osquery.action.unavailable', {
+ defaultMessage:
+ 'The Osquery Manager integration is not added to the agent policy. To run queries on the host, add the Osquery Manager integration to the agent policy in Fleet.',
+ })}
}
/>
@@ -120,30 +114,38 @@ const OsqueryActionComponent: React.FC = ({ metadata }) => {
return (
}
- title={Osquery is not available
}
+ title={
+
+ {i18n.translate('xpack.osquery.action.shortEmptyTitle', {
+ defaultMessage: 'Osquery is not available',
+ })}
+
+ }
titleSize="xs"
body={
- To run queries on this host, the Elastic Agent must be active. Check the status of this
- agent in Fleet.
+ {i18n.translate('xpack.osquery.action.agentStatus', {
+ defaultMessage:
+ 'To run queries on this host, the Elastic Agent must be active. Check the status of this agent in Fleet.',
+ })}
}
/>
);
}
- return ;
+ return ;
};
-export const OsqueryAction = React.memo(OsqueryActionComponent);
+const OsqueryAction = React.memo(OsqueryActionComponent);
// @ts-expect-error update types
-const OsqueryActionWrapperComponent = ({ services, ...props }) => (
+const OsqueryActionWrapperComponent = ({ services, agentId, formType }) => (
-
+
diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts
new file mode 100644
index 0000000000000..595296e4d7b60
--- /dev/null
+++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available.ts
@@ -0,0 +1,46 @@
+/*
+ * 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 { useMemo } from 'react';
+import { find } from 'lodash';
+import { useAgentDetails } from '../../agents/use_agent_details';
+import { useAgentPolicy } from '../../agent_policies';
+import { OSQUERY_INTEGRATION_NAME } from '../../../common';
+
+export const useIsOsqueryAvailable = (agentId?: string) => {
+ const {
+ data: agentData,
+ isFetched: agentFetched,
+ isLoading,
+ } = useAgentDetails({
+ agentId,
+ silent: true,
+ skip: !agentId,
+ });
+ const {
+ data: agentPolicyData,
+ isFetched: policyFetched,
+ isError: policyError,
+ isLoading: policyLoading,
+ } = useAgentPolicy({
+ policyId: agentData?.policy_id,
+ skip: !agentData,
+ silent: true,
+ });
+
+ const osqueryAvailable = useMemo(() => {
+ if (policyError) return false;
+
+ const osqueryPackageInstalled = find(agentPolicyData?.package_policies, [
+ 'package.name',
+ OSQUERY_INTEGRATION_NAME,
+ ]);
+ return osqueryPackageInstalled?.enabled;
+ }, [agentPolicyData?.package_policies, policyError]);
+
+ return { osqueryAvailable, agentFetched, isLoading, policyFetched, policyLoading, agentData };
+};
diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.test.ts b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.test.ts
new file mode 100644
index 0000000000000..c293e4c75a910
--- /dev/null
+++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.test.ts
@@ -0,0 +1,55 @@
+/*
+ * 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 { useKibana } from '../../common/lib/kibana';
+import { useIsOsqueryAvailableSimple } from './use_is_osquery_available_simple';
+import { renderHook } from '@testing-library/react-hooks';
+import { createStartServicesMock } from '../../../../triggers_actions_ui/public/common/lib/kibana/kibana_react.mock';
+import { OSQUERY_INTEGRATION_NAME } from '../../../common';
+import { httpServiceMock } from '../../../../../../src/core/public/mocks';
+
+jest.mock('../../common/lib/kibana');
+
+const response = {
+ item: {
+ policy_id: '4234234234',
+ package_policies: [
+ {
+ package: { name: OSQUERY_INTEGRATION_NAME },
+ enabled: true,
+ },
+ ],
+ },
+};
+
+describe('UseIsOsqueryAvailableSimple', () => {
+ const mockedHttp = httpServiceMock.createStartContract();
+ mockedHttp.get.mockResolvedValue(response);
+ beforeAll(() => {
+ (useKibana as jest.Mock).mockImplementation(() => {
+ const mockStartServicesMock = createStartServicesMock();
+
+ return {
+ services: {
+ ...mockStartServicesMock,
+ http: mockedHttp,
+ },
+ };
+ });
+ });
+ it('should expect response from API and return enabled flag', async () => {
+ const { result, waitForValueToChange } = renderHook(() =>
+ useIsOsqueryAvailableSimple({
+ agentId: '3242332',
+ })
+ );
+
+ expect(result.current).toBe(false);
+ await waitForValueToChange(() => result.current);
+
+ expect(result.current).toBe(true);
+ });
+});
diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx
new file mode 100644
index 0000000000000..efe34b51ea0a3
--- /dev/null
+++ b/x-pack/plugins/osquery/public/shared_components/osquery_action/use_is_osquery_available_simple.tsx
@@ -0,0 +1,43 @@
+/*
+ * 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 { useEffect, useState } from 'react';
+
+import { find } from 'lodash';
+import { useKibana } from '../../common/lib/kibana';
+import { OSQUERY_INTEGRATION_NAME } from '../../../common';
+import { AgentPolicy, FleetServerAgent, NewPackagePolicy } from '../../../../fleet/common';
+
+interface IProps {
+ agentId: string;
+}
+
+export const useIsOsqueryAvailableSimple = ({ agentId }: IProps) => {
+ const { http } = useKibana().services;
+ const [isAvailable, setIsAvailable] = useState(false);
+ useEffect(() => {
+ (async () => {
+ try {
+ const { item: agentInfo }: { item: FleetServerAgent } = await http.get(
+ `/internal/osquery/fleet_wrapper/agents/${agentId}`
+ );
+ const { item: packageInfo }: { item: AgentPolicy } = await http.get(
+ `/internal/osquery/fleet_wrapper/agent_policies/${agentInfo.policy_id}/`
+ );
+ const osqueryPackageInstalled = find(packageInfo?.package_policies, [
+ 'package.name',
+ OSQUERY_INTEGRATION_NAME,
+ ]) as NewPackagePolicy;
+ setIsAvailable(osqueryPackageInstalled.enabled);
+ } catch (err) {
+ return;
+ }
+ })();
+ }, [agentId, http]);
+
+ return isAvailable;
+};
diff --git a/x-pack/plugins/osquery/public/types.ts b/x-pack/plugins/osquery/public/types.ts
index fd21b39d25504..91095b6f169c1 100644
--- a/x-pack/plugins/osquery/public/types.ts
+++ b/x-pack/plugins/osquery/public/types.ts
@@ -22,6 +22,7 @@ import { getLazyOsqueryAction } from './shared_components';
export interface OsqueryPluginSetup {}
export interface OsqueryPluginStart {
OsqueryAction?: ReturnType;
+ isOsqueryAvailable: (props: { agentId: string }) => boolean;
}
export interface AppPluginStartDependencies {
diff --git a/x-pack/plugins/security_solution/kibana.json b/x-pack/plugins/security_solution/kibana.json
index ba289e48fd6a2..36edfd43d5ea5 100644
--- a/x-pack/plugins/security_solution/kibana.json
+++ b/x-pack/plugins/security_solution/kibana.json
@@ -39,7 +39,8 @@
"lists",
"home",
"telemetry",
- "dataViewFieldEditor"
+ "dataViewFieldEditor",
+ "osquery"
],
"server": true,
"ui": true,
diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_action_item.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_action_item.tsx
new file mode 100644
index 0000000000000..ca61e2f3ebf6d
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_action_item.tsx
@@ -0,0 +1,26 @@
+/*
+ * 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 React from 'react';
+import { EuiContextMenuItem } from '@elastic/eui';
+import { ACTION_OSQUERY } from './translations';
+
+interface IProps {
+ handleClick: () => void;
+}
+
+export const OsqueryActionItem = ({ handleClick }: IProps) => {
+ return (
+
+ {ACTION_OSQUERY}
+
+ );
+};
diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx
new file mode 100644
index 0000000000000..3262fc36abf75
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx
@@ -0,0 +1,58 @@
+/*
+ * 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 React from 'react';
+import styled from 'styled-components';
+import { EuiFlyout, EuiFlyoutFooter, EuiFlyoutBody, EuiFlyoutHeader } from '@elastic/eui';
+import { useKibana } from '../../../common/lib/kibana';
+import { OsqueryEventDetailsFooter } from './osquery_flyout_footer';
+import { OsqueryEventDetailsHeader } from './osquery_flyout_header';
+import { ACTION_OSQUERY } from './translations';
+
+const OsqueryActionWrapper = styled.div`
+ padding: 8px;
+`;
+
+export interface OsqueryFlyoutProps {
+ agentId: string;
+ onClose: () => void;
+}
+
+export const OsqueryFlyout: React.FC = ({ agentId, onClose }) => {
+ const {
+ services: { osquery },
+ } = useKibana();
+
+ // @ts-expect-error
+ const { OsqueryAction } = osquery;
+ return (
+
+
+ {ACTION_OSQUERY}}
+ handleClick={onClose}
+ data-test-subj="flyout-header-osquery"
+ />
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+OsqueryFlyout.displayName = 'OsqueryFlyout';
diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_footer.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_footer.tsx
new file mode 100644
index 0000000000000..77cade0e04042
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_footer.tsx
@@ -0,0 +1,28 @@
+/*
+ * 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 React from 'react';
+import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n-react';
+
+interface EventDetailsFooterProps {
+ handleClick: () => void;
+}
+
+export const OsqueryEventDetailsFooterComponent = ({ handleClick }: EventDetailsFooterProps) => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export const OsqueryEventDetailsFooter = React.memo(OsqueryEventDetailsFooterComponent);
diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx
new file mode 100644
index 0000000000000..7a0f7f15f3e74
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout_header.tsx
@@ -0,0 +1,30 @@
+/*
+ * 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 React from 'react';
+import { EuiButtonEmpty, EuiText, EuiTitle } from '@elastic/eui';
+import { BACK_TO_ALERT_DETAILS } from './translations';
+
+interface IProps {
+ primaryText: React.ReactElement;
+ handleClick: () => void;
+}
+
+const OsqueryEventDetailsHeaderComponent: React.FC = ({ primaryText, handleClick }) => {
+ return (
+ <>
+
+
+ {BACK_TO_ALERT_DETAILS}
+
+
+ {primaryText}
+ >
+ );
+};
+
+export const OsqueryEventDetailsHeader = React.memo(OsqueryEventDetailsHeaderComponent);
diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/translations.ts b/x-pack/plugins/security_solution/public/detections/components/osquery/translations.ts
new file mode 100644
index 0000000000000..d3c92ebdf44e2
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/osquery/translations.ts
@@ -0,0 +1,22 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+
+export const BACK_TO_ALERT_DETAILS = i18n.translate(
+ 'xpack.securitySolution.alertsView.osqueryBackToAlertDetails',
+ {
+ defaultMessage: 'Alert Details',
+ }
+);
+
+export const ACTION_OSQUERY = i18n.translate(
+ 'xpack.securitySolution.alertsView.osqueryAlertTitle',
+ {
+ defaultMessage: 'Run Osquery',
+ }
+);
diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx
index 938022b5aac5e..8aa8986d3e563 100644
--- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx
@@ -78,6 +78,7 @@ describe('take action dropdown', () => {
refetch: jest.fn(),
refetchFlyoutData: jest.fn(),
timelineId: TimelineId.active,
+ onOsqueryClick: jest.fn(),
};
beforeAll(() => {
@@ -89,8 +90,11 @@ describe('take action dropdown', () => {
...mockStartServicesMock,
timelines: { ...mockTimelines },
cases: mockCasesContract(),
+ osquery: {
+ isOsqueryAvailable: jest.fn().mockReturnValue(true),
+ },
application: {
- capabilities: { siem: { crud_alerts: true, read_alerts: true } },
+ capabilities: { siem: { crud_alerts: true, read_alerts: true }, osquery: true },
},
},
};
@@ -190,6 +194,13 @@ describe('take action dropdown', () => {
).toEqual('Investigate in timeline');
});
});
+ test('should render "Run Osquery"', async () => {
+ await waitFor(() => {
+ expect(wrapper.find('[data-test-subj="osquery-action-item"]').first().text()).toEqual(
+ 'Run Osquery'
+ );
+ });
+ });
});
describe('should correctly enable/disable the "Add Endpoint event filter" button', () => {
diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
index 4a35fdd6a1381..94b9327bb439a 100644
--- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
@@ -5,8 +5,8 @@
* 2.0.
*/
-import React, { useState, useCallback, useMemo } from 'react';
-import { EuiContextMenuPanel, EuiButton, EuiPopover } from '@elastic/eui';
+import React, { useCallback, useMemo, useState } from 'react';
+import { EuiButton, EuiContextMenuPanel, EuiPopover } from '@elastic/eui';
import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types';
import { TimelineEventsDetailsItem } from '../../../../common/search_strategy';
import { TAKE_ACTION } from '../alerts_table/alerts_utility_bar/translations';
@@ -23,6 +23,8 @@ import { isAlertFromEndpointAlert } from '../../../common/utils/endpoint_alert_c
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
import { useUserPrivileges } from '../../../common/components/user_privileges';
import { useAddToCaseActions } from '../alerts_table/timeline_actions/use_add_to_case_actions';
+import { useKibana } from '../../../common/lib/kibana';
+import { OsqueryActionItem } from '../osquery/osquery_action_item';
interface ActionsData {
alertStatus: Status;
@@ -45,6 +47,7 @@ export interface TakeActionDropdownProps {
refetch: (() => void) | undefined;
refetchFlyoutData: () => Promise;
timelineId: string;
+ onOsqueryClick: (id: string) => void;
}
export const TakeActionDropdown = React.memo(
@@ -61,6 +64,7 @@ export const TakeActionDropdown = React.memo(
refetch,
refetchFlyoutData,
timelineId,
+ onOsqueryClick,
}: TakeActionDropdownProps) => {
const tGridEnabled = useIsExperimentalFeatureEnabled('tGridEnabled');
const { loading: canAccessEndpointManagementLoading, canAccessEndpointManagement } =
@@ -70,6 +74,7 @@ export const TakeActionDropdown = React.memo(
() => !canAccessEndpointManagementLoading && canAccessEndpointManagement,
[canAccessEndpointManagement, canAccessEndpointManagementLoading]
);
+ const { osquery } = useKibana().services;
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
@@ -97,6 +102,11 @@ export const TakeActionDropdown = React.memo(
const isEndpointEvent = useMemo(() => isEvent && isAgentEndpoint, [isEvent, isAgentEndpoint]);
+ const agentId = useMemo(
+ () => getFieldValue({ category: 'agent', field: 'agent.id' }, detailsData),
+ [detailsData]
+ );
+
const togglePopoverHandler = useCallback(() => {
setIsPopoverOpen(!isPopoverOpen);
}, [isPopoverOpen]);
@@ -166,6 +176,23 @@ export const TakeActionDropdown = React.memo(
onInvestigateInTimelineAlertClick: closePopoverHandler,
});
+ const osqueryAvailable = osquery?.isOsqueryAvailable({
+ agentId,
+ });
+
+ const handleOnOsqueryClick = useCallback(() => {
+ onOsqueryClick(agentId);
+ setIsPopoverOpen(false);
+ }, [onOsqueryClick, setIsPopoverOpen, agentId]);
+
+ const osqueryActionItem = useMemo(
+ () =>
+ OsqueryActionItem({
+ handleClick: handleOnOsqueryClick,
+ }),
+ [handleOnOsqueryClick]
+ );
+
const alertsActionItems = useMemo(
() =>
!isEvent && actionsData.ruleId
@@ -196,13 +223,16 @@ export const TakeActionDropdown = React.memo(
...(tGridEnabled ? addToCaseActionItems : []),
...alertsActionItems,
...hostIsolationActionItems,
+ ...(osqueryAvailable ? [osqueryActionItem] : []),
...investigateInTimelineActionItems,
],
[
tGridEnabled,
- alertsActionItems,
addToCaseActionItems,
+ alertsActionItems,
hostIsolationActionItems,
+ osqueryAvailable,
+ osqueryActionItem,
investigateInTimelineActionItems,
]
);
@@ -220,7 +250,6 @@ export const TakeActionDropdown = React.memo(
);
}, [togglePopoverHandler]);
-
return items.length && !loadingEventDetails && ecsData ? (
(null);
+
+ const closeOsqueryFlyout = useCallback(() => {
+ setOsqueryFlyoutOpenWithAgentId(null);
+ }, [setOsqueryFlyoutOpenWithAgentId]);
+
return (
<>
@@ -128,6 +137,7 @@ export const EventDetailsFooterComponent = React.memo(
refetch={refetchAll}
indexName={expandedEvent.indexName}
timelineId={timelineId}
+ onOsqueryClick={setOsqueryFlyoutOpenWithAgentId}
/>
)}