diff --git a/x-pack/plugins/osquery/cypress/e2e/all/live_query_run.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/live_query_run.cy.ts index 035c228623fda..c74b253ae9d41 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/live_query_run.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/live_query_run.cy.ts @@ -10,11 +10,13 @@ import { navigateTo } from '../../tasks/navigation'; import { checkActionItemsInResults, checkResults, + fillInQueryTimeout, inputQuery, selectAllAgents, submitQuery, typeInECSFieldInput, typeInOsqueryFieldInput, + verifyQueryTimeout, } from '../../tasks/live_query'; import { LIVE_QUERY_EDITOR, RESULTS_TABLE, RESULTS_TABLE_BUTTON } from '../../screens/live_query'; import { getAdvancedButton } from '../../screens/integrations'; @@ -93,6 +95,8 @@ describe('ALL - Live Query run custom and saved', { tags: ['@ess', '@serverless' selectAllAgents(); cy.getBySel(SAVED_QUERY_DROPDOWN_SELECT).type(`${savedQueryName}{downArrow}{enter}`); inputQuery('{selectall}{backspace}select * from users;'); + getAdvancedButton().click(); + fillInQueryTimeout('601'); cy.wait(1000); submitQuery(); checkResults(); @@ -100,6 +104,7 @@ describe('ALL - Live Query run custom and saved', { tags: ['@ess', '@serverless' cy.get('[aria-label="Run query"]').first().should('be.visible').click(); cy.getBySel(LIVE_QUERY_EDITOR).contains('select * from users;'); + verifyQueryTimeout('601'); }); it('should open query details by clicking the details icon', () => { diff --git a/x-pack/plugins/osquery/cypress/tasks/live_query.ts b/x-pack/plugins/osquery/cypress/tasks/live_query.ts index cc9319633befc..b1ad8124dc8c6 100644 --- a/x-pack/plugins/osquery/cypress/tasks/live_query.ts +++ b/x-pack/plugins/osquery/cypress/tasks/live_query.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getAdvancedButton } from '../screens/integrations'; import { LIVE_QUERY_EDITOR, OSQUERY_FLYOUT_BODY_EDITOR } from '../screens/live_query'; import { ServerlessRoleName } from '../support/roles'; import { waitForAlertsToPopulate } from '../../../../test/security_solution_cypress/cypress/tasks/create_new_rule'; @@ -46,6 +47,13 @@ export const fillInQueryTimeout = (timeout: string) => { }); }; +export const verifyQueryTimeout = (timeout: string) => { + getAdvancedButton().click(); + cy.getBySel('advanced-accordion-content').within(() => { + cy.getBySel('timeout-input').should('have.value', timeout); + }); +}; + // sometimes the results get stuck in the tests, this is a workaround export const checkResults = () => { cy.getBySel('osqueryResultsTable').then(($table) => { diff --git a/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts b/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts index b01effba17e65..d25761c9f42a8 100644 --- a/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts +++ b/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getAdvancedButton } from '../screens/integrations'; import { RESULTS_TABLE_BUTTON } from '../screens/live_query'; import { closeToastIfVisible, generateRandomStringName } from './integrations'; import { @@ -14,11 +15,14 @@ import { inputQuery, selectAllAgents, submitQuery, + fillInQueryTimeout, + verifyQueryTimeout, } from './live_query'; import { navigateTo } from './navigation'; export const getSavedQueriesComplexTest = () => describe('Saved queries Complex Test', () => { + const timeout = '601'; const suffix = generateRandomStringName(1)[0]; const savedQueryId = `Saved-Query-Id-${suffix}`; const savedQueryDescription = `Test saved query description ${suffix}`; @@ -32,6 +36,8 @@ export const getSavedQueriesComplexTest = () => cy.contains('New live query').click(); selectAllAgents(); inputQuery(BIG_QUERY); + getAdvancedButton().click(); + fillInQueryTimeout(timeout); submitQuery(); checkResults(); // enter fullscreen @@ -92,6 +98,7 @@ export const getSavedQueriesComplexTest = () => cy.contains(savedQueryId); cy.get(`[aria-label="Run ${savedQueryId}"]`).click(); selectAllAgents(); + verifyQueryTimeout(timeout); submitQuery(); // edit saved query @@ -104,6 +111,7 @@ export const getSavedQueriesComplexTest = () => // Run in test configuration cy.contains('Test configuration').click(); selectAllAgents(); + verifyQueryTimeout(timeout); submitQuery(); checkResults(); diff --git a/x-pack/plugins/osquery/public/actions/actions_table.tsx b/x-pack/plugins/osquery/public/actions/actions_table.tsx index cd5e1a685d33b..a6c66855f12cc 100644 --- a/x-pack/plugins/osquery/public/actions/actions_table.tsx +++ b/x-pack/plugins/osquery/public/actions/actions_table.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { isArray, isEmpty, pickBy, map } from 'lodash'; +import { isArray, isEmpty, pickBy, map, isNumber } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiBasicTable, @@ -20,6 +20,7 @@ import { import React, { useState, useCallback, useMemo } from 'react'; import { useHistory } from 'react-router-dom'; +import { QUERY_TIMEOUT } from '../../common/constants'; import { removeMultilines } from '../../common/utils/build_query/remove_multilines'; import { useAllLiveQueries } from './use_all_live_queries'; import type { SearchHit } from '../../common/search_strategy'; @@ -136,6 +137,7 @@ const ActionsTableComponent = () => { query: item._source.queries[0].query, ecs_mapping: item._source.queries[0].ecs_mapping, savedQueryId: item._source.queries[0].saved_query_id, + timeout: item._source.queries[0].timeout ?? QUERY_TIMEOUT.DEFAULT, agentSelection: { agents: item._source.agent_ids, allAgentsSelected: item._source.agent_all, @@ -143,7 +145,7 @@ const ActionsTableComponent = () => { policiesSelected: item._source.agent_policy_ids, }, }, - (value) => !isEmpty(value) + (value) => !isEmpty(value) || isNumber(value) ), }); }, diff --git a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx index 518f03be92f35..3d7dbf1b3a3dd 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/playground_flyout.tsx @@ -10,6 +10,7 @@ import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { useFormContext } from 'react-hook-form'; +import { QUERY_TIMEOUT } from '../../../common/constants'; import { LiveQuery } from '../../live_queries'; const euiFlyoutHeaderCss = { @@ -28,7 +29,7 @@ const PlaygroundFlyoutComponent: React.FC = ({ enabled, o // @ts-expect-error update types const { serializer, watch } = useFormContext(); const watchedValues = watch(); - const { query, ecs_mapping: ecsMapping, id } = watchedValues; + const { query, ecs_mapping: ecsMapping, id, timeout } = watchedValues; /* recalculate the form data when ecs_mapping changes */ // eslint-disable-next-line react-hooks/exhaustive-deps const serializedFormData = useMemo(() => serializer(watchedValues), [ecsMapping]); @@ -52,6 +53,7 @@ const PlaygroundFlyoutComponent: React.FC = ({ enabled, o query={query} ecs_mapping={serializedFormData.ecs_mapping} savedQueryId={id} + timeout={timeout || QUERY_TIMEOUT.DEFAULT} queryField={false} ecsMappingField={false} />