mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Osquery] Fix running pack live RBAC (#138228)
This commit is contained in:
parent
ddf0545e38
commit
a7b0a86974
10 changed files with 111 additions and 48 deletions
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isArray, isEmpty, pickBy } from 'lodash';
|
||||
import { isArray, isEmpty, pickBy, map } from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiBasicTable,
|
||||
|
@ -23,6 +23,7 @@ import { useAllLiveQueries } from './use_all_live_queries';
|
|||
import type { SearchHit } from '../../common/search_strategy';
|
||||
import { Direction } from '../../common/search_strategy';
|
||||
import { useRouterNavigate, useKibana } from '../common/lib/kibana';
|
||||
import { usePacks } from '../packs/use_packs';
|
||||
|
||||
const EMPTY_ARRAY: SearchHit[] = [];
|
||||
|
||||
|
@ -44,6 +45,8 @@ const ActionsTableComponent = () => {
|
|||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [pageSize, setPageSize] = useState(20);
|
||||
|
||||
const { data: packsData } = usePacks({});
|
||||
|
||||
const { data: actionsData } = useAllLiveQueries({
|
||||
activePage: pageIndex,
|
||||
limit: pageSize,
|
||||
|
@ -131,9 +134,22 @@ const ActionsTableComponent = () => {
|
|||
},
|
||||
[push]
|
||||
);
|
||||
|
||||
const existingPackIds = useMemo(() => map(packsData?.data ?? [], 'id'), [packsData]);
|
||||
|
||||
const isPlayButtonAvailable = useCallback(
|
||||
() => !!(permissions.runSavedQueries || permissions.writeLiveQueries),
|
||||
[permissions.runSavedQueries, permissions.writeLiveQueries]
|
||||
(item) => {
|
||||
if (item.fields.pack_id?.length) {
|
||||
return (
|
||||
existingPackIds.includes(item.fields.pack_id[0]) &&
|
||||
permissions.runSavedQueries &&
|
||||
permissions.readPacks
|
||||
);
|
||||
}
|
||||
|
||||
return !!(permissions.runSavedQueries || permissions.writeLiveQueries);
|
||||
},
|
||||
[permissions, existingPackIds]
|
||||
);
|
||||
|
||||
const columns = useMemo(
|
||||
|
|
|
@ -47,6 +47,13 @@ export const useLogsDataView = (payload?: UseLogsDataView) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (!dataView) {
|
||||
dataView = await dataViews.create({
|
||||
title: 'logs-osquery_manager.result*',
|
||||
timeFieldName: '@timestamp',
|
||||
});
|
||||
}
|
||||
|
||||
return dataView as LogsDataView;
|
||||
},
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,7 @@ let osqueryTables: TablesJSON | null = null;
|
|||
export const getOsqueryTables = () => {
|
||||
if (!osqueryTables) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
osqueryTables = normalizeTables(require('../common/schemas/osquery/v5.2.2.json'));
|
||||
osqueryTables = normalizeTables(require('../common/schemas/osquery/v5.4.0.json'));
|
||||
}
|
||||
|
||||
return osqueryTables;
|
||||
|
|
|
@ -53,7 +53,7 @@ const StyledEuiCard = styled(EuiCard)`
|
|||
color: ${(props) => props.theme.eui.euiTextSubduedColor};
|
||||
}
|
||||
|
||||
button[role='switch'] {
|
||||
> button[role='switch'] {
|
||||
left: auto;
|
||||
height: 100% !important;
|
||||
width: 80px;
|
||||
|
@ -61,9 +61,10 @@ const StyledEuiCard = styled(EuiCard)`
|
|||
border-radius: 0 5px 5px 0;
|
||||
|
||||
> span {
|
||||
svg {
|
||||
> svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
// hide the label
|
||||
|
@ -111,12 +112,25 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
addToTimeline,
|
||||
}) => {
|
||||
const permissions = useKibana().services.application.capabilities.osquery;
|
||||
const canRunPacks = useMemo(
|
||||
() =>
|
||||
!!((permissions.runSavedQueries || permissions.writeLiveQueries) && permissions.readPacks),
|
||||
[permissions]
|
||||
);
|
||||
|
||||
const canRunSingleQuery = useMemo(
|
||||
() =>
|
||||
!!(
|
||||
permissions.writeLiveQueries ||
|
||||
(permissions.runSavedQueries && permissions.readSavedQueries)
|
||||
),
|
||||
[permissions]
|
||||
);
|
||||
|
||||
const [advancedContentState, setAdvancedContentState] =
|
||||
useState<EuiAccordionProps['forceState']>('closed');
|
||||
const [showSavedQueryFlyout, setShowSavedQueryFlyout] = useState(false);
|
||||
const [queryType, setQueryType] = useState<string>(() =>
|
||||
defaultValue?.packId ? 'pack' : 'query'
|
||||
);
|
||||
const [queryType, setQueryType] = useState<string>('query');
|
||||
const [isLive, setIsLive] = useState(false);
|
||||
|
||||
const handleShowSaveQueryFlyout = useCallback(() => setShowSavedQueryFlyout(true), []);
|
||||
|
@ -278,7 +292,7 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
[permissions.readSavedQueries, permissions.runSavedQueries]
|
||||
);
|
||||
|
||||
const { data: packsData } = usePacks({});
|
||||
const { data: packsData, isFetched: isPackDataFetched } = usePacks({});
|
||||
|
||||
const selectedPackData = useMemo(
|
||||
() => (packId?.length ? find(packsData?.data, { id: packId[0] }) : null),
|
||||
|
@ -425,22 +439,60 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
|
||||
useEffect(() => {
|
||||
if (defaultValue) {
|
||||
updateFieldValues({
|
||||
agentSelection: defaultValue.agentSelection,
|
||||
query: defaultValue.query,
|
||||
savedQueryId: defaultValue.savedQueryId,
|
||||
ecs_mapping: defaultValue.ecs_mapping
|
||||
? map(defaultValue.ecs_mapping, (value, key) => ({
|
||||
key,
|
||||
result: {
|
||||
type: Object.keys(value)[0],
|
||||
value: Object.values(value)[0],
|
||||
},
|
||||
}))
|
||||
: undefined,
|
||||
});
|
||||
if (defaultValue.agentSelection) {
|
||||
updateFieldValues({
|
||||
agentSelection: defaultValue.agentSelection,
|
||||
});
|
||||
}
|
||||
|
||||
if (defaultValue?.packId && canRunPacks) {
|
||||
setQueryType('pack');
|
||||
|
||||
if (!isPackDataFetched) return;
|
||||
const selectedPackOption = find(packsData?.data, ['id', defaultValue.packId]);
|
||||
if (selectedPackOption) {
|
||||
updateFieldValues({
|
||||
packId: [defaultValue.packId],
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (defaultValue?.query && canRunSingleQuery) {
|
||||
updateFieldValues({
|
||||
query: defaultValue.query,
|
||||
savedQueryId: defaultValue.savedQueryId,
|
||||
ecs_mapping: defaultValue.ecs_mapping
|
||||
? map(defaultValue.ecs_mapping, (value, key) => ({
|
||||
key,
|
||||
result: {
|
||||
type: Object.keys(value)[0],
|
||||
value: Object.values(value)[0],
|
||||
},
|
||||
}))
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (canRunSingleQuery) {
|
||||
return setQueryType('query');
|
||||
}
|
||||
|
||||
if (canRunPacks) {
|
||||
return setQueryType('pack');
|
||||
}
|
||||
}
|
||||
}, [defaultValue, updateFieldValues]);
|
||||
}, [
|
||||
canRunPacks,
|
||||
canRunSingleQuery,
|
||||
defaultValue,
|
||||
isPackDataFetched,
|
||||
packsData?.data,
|
||||
updateFieldValues,
|
||||
]);
|
||||
|
||||
const queryCardSelectable = useMemo(
|
||||
() => ({
|
||||
|
@ -460,24 +512,6 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
[queryType]
|
||||
);
|
||||
|
||||
const canRunPacks = useMemo(
|
||||
() =>
|
||||
!!((permissions.runSavedQueries || permissions.writeLiveQueries) && permissions.readPacks),
|
||||
[permissions]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultValue?.packId) {
|
||||
setQueryType('pack');
|
||||
const selectedPackOption = find(packsData?.data, ['id', defaultValue.packId]);
|
||||
if (selectedPackOption) {
|
||||
updateFieldValues({
|
||||
packId: [defaultValue.packId],
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [defaultValue, packsData, updateFieldValues]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLive(() => !(liveQueryDetails?.status === 'completed'));
|
||||
}, [liveQueryDetails?.status]);
|
||||
|
@ -510,6 +544,7 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
}
|
||||
)}
|
||||
selectable={queryCardSelectable}
|
||||
isDisabled={!canRunSingleQuery}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
|
|
|
@ -40,8 +40,8 @@ import styled from 'styled-components';
|
|||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { prepareEcsFieldsToValidate } from '../../common/helpers';
|
||||
import ECSSchema from '../../common/schemas/ecs/v8.2.0.json';
|
||||
import osquerySchema from '../../common/schemas/osquery/v5.2.2.json';
|
||||
import ECSSchema from '../../common/schemas/ecs/v8.4.0.json';
|
||||
import osquerySchema from '../../common/schemas/osquery/v5.4.0.json';
|
||||
|
||||
import { FieldIcon } from '../../common/lib/kibana';
|
||||
import type { FieldHook, ValidationFuncArg, ArrayItem, FormArrayField } from '../../shared_imports';
|
||||
|
|
|
@ -57,7 +57,12 @@ const NewLiveQueryButton = React.memo(() => {
|
|||
fill
|
||||
{...newQueryLinkProps}
|
||||
iconType="plusInCircle"
|
||||
isDisabled={!(permissions.writeLiveQueries || permissions.runSavedQueries)}
|
||||
isDisabled={
|
||||
!(
|
||||
permissions.writeLiveQueries ||
|
||||
(permissions.runSavedQueries && (permissions.readSavedQueries || permissions.readPacks))
|
||||
)
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.osquery.liveQueriesHistory.newLiveQueryButtonLabel"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue