mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Fleet UI: Can run a live query on an edited (but not saved) existing query (#16282)
This commit is contained in:
parent
c069a446fd
commit
aa60187aa1
1
changes/16067-bug-running-edited-query
Normal file
1
changes/16067-bug-running-edited-query
Normal file
@ -0,0 +1 @@
|
|||||||
|
- Ability to run a live query on an edited existing query before saving
|
@ -27,6 +27,7 @@ const DEFAULT_QUERY_MOCK: ISchedulableQuery = {
|
|||||||
system_time_p95: 1,
|
system_time_p95: 1,
|
||||||
total_executions: 6,
|
total_executions: 6,
|
||||||
},
|
},
|
||||||
|
editingExistingQuery: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createMockQuery = (
|
const createMockQuery = (
|
||||||
|
@ -29,6 +29,7 @@ const DEFAULT_SCHEDULABLE_QUERY_MOCK: ISchedulableQuery = {
|
|||||||
user_time_p95: 251.4615,
|
user_time_p95: 251.4615,
|
||||||
total_executions: 5746,
|
total_executions: 5746,
|
||||||
},
|
},
|
||||||
|
editingExistingQuery: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const createMockSchedulableQuery = (
|
const createMockSchedulableQuery = (
|
||||||
|
@ -29,6 +29,7 @@ type InitialStateType = {
|
|||||||
lastEditedQueryMinOsqueryVersion: string;
|
lastEditedQueryMinOsqueryVersion: string;
|
||||||
lastEditedQueryLoggingType: QueryLoggingOption;
|
lastEditedQueryLoggingType: QueryLoggingOption;
|
||||||
lastEditedQueryDiscardData: boolean;
|
lastEditedQueryDiscardData: boolean;
|
||||||
|
editingExistingQuery: boolean;
|
||||||
selectedQueryTargets: ITarget[]; // Mimicks old selectedQueryTargets still used for policies for SelectTargets.tsx and running a live query
|
selectedQueryTargets: ITarget[]; // Mimicks old selectedQueryTargets still used for policies for SelectTargets.tsx and running a live query
|
||||||
selectedQueryTargetsByType: ISelectedTargetsByType; // New format by type for cleaner app wide state
|
selectedQueryTargetsByType: ISelectedTargetsByType; // New format by type for cleaner app wide state
|
||||||
setLastEditedQueryId: (value: number | null) => void;
|
setLastEditedQueryId: (value: number | null) => void;
|
||||||
@ -44,6 +45,7 @@ type InitialStateType = {
|
|||||||
setSelectedOsqueryTable: (tableName: string) => void;
|
setSelectedOsqueryTable: (tableName: string) => void;
|
||||||
setSelectedQueryTargets: (value: ITarget[]) => void;
|
setSelectedQueryTargets: (value: ITarget[]) => void;
|
||||||
setSelectedQueryTargetsByType: (value: ISelectedTargetsByType) => void;
|
setSelectedQueryTargetsByType: (value: ISelectedTargetsByType) => void;
|
||||||
|
setEditingExistingQuery: (value: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IQueryContext = InitialStateType;
|
export type IQueryContext = InitialStateType;
|
||||||
@ -61,6 +63,7 @@ const initialState = {
|
|||||||
lastEditedQueryMinOsqueryVersion: DEFAULT_QUERY.min_osquery_version,
|
lastEditedQueryMinOsqueryVersion: DEFAULT_QUERY.min_osquery_version,
|
||||||
lastEditedQueryLoggingType: DEFAULT_QUERY.logging,
|
lastEditedQueryLoggingType: DEFAULT_QUERY.logging,
|
||||||
lastEditedQueryDiscardData: DEFAULT_QUERY.discard_data,
|
lastEditedQueryDiscardData: DEFAULT_QUERY.discard_data,
|
||||||
|
editingExistingQuery: DEFAULT_QUERY.editingExistingQuery,
|
||||||
selectedQueryTargets: DEFAULT_TARGETS,
|
selectedQueryTargets: DEFAULT_TARGETS,
|
||||||
selectedQueryTargetsByType: DEFAULT_TARGETS_BY_TYPE,
|
selectedQueryTargetsByType: DEFAULT_TARGETS_BY_TYPE,
|
||||||
setLastEditedQueryId: () => null,
|
setLastEditedQueryId: () => null,
|
||||||
@ -76,6 +79,7 @@ const initialState = {
|
|||||||
setSelectedOsqueryTable: () => null,
|
setSelectedOsqueryTable: () => null,
|
||||||
setSelectedQueryTargets: () => null,
|
setSelectedQueryTargets: () => null,
|
||||||
setSelectedQueryTargetsByType: () => null,
|
setSelectedQueryTargetsByType: () => null,
|
||||||
|
setEditingExistingQuery: () => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
@ -137,6 +141,10 @@ const reducer = (state: InitialStateType, action: any) => {
|
|||||||
typeof action.lastEditedQueryDiscardData === "undefined"
|
typeof action.lastEditedQueryDiscardData === "undefined"
|
||||||
? state.lastEditedQueryDiscardData
|
? state.lastEditedQueryDiscardData
|
||||||
: action.lastEditedQueryDiscardData,
|
: action.lastEditedQueryDiscardData,
|
||||||
|
editingExistingQuery:
|
||||||
|
typeof action.editingExistingQuery === "undefined"
|
||||||
|
? state.editingExistingQuery
|
||||||
|
: action.editingExistingQuery,
|
||||||
};
|
};
|
||||||
case actions.SET_SELECTED_QUERY_TARGETS:
|
case actions.SET_SELECTED_QUERY_TARGETS:
|
||||||
return {
|
return {
|
||||||
@ -176,6 +184,7 @@ const QueryProvider = ({ children }: Props) => {
|
|||||||
lastEditedQueryMinOsqueryVersion: state.lastEditedQueryMinOsqueryVersion,
|
lastEditedQueryMinOsqueryVersion: state.lastEditedQueryMinOsqueryVersion,
|
||||||
lastEditedQueryLoggingType: state.lastEditedQueryLoggingType,
|
lastEditedQueryLoggingType: state.lastEditedQueryLoggingType,
|
||||||
lastEditedQueryDiscardData: state.lastEditedQueryDiscardData,
|
lastEditedQueryDiscardData: state.lastEditedQueryDiscardData,
|
||||||
|
editingExistingQuery: state.editingExistingQuery,
|
||||||
selectedQueryTargets: state.selectedQueryTargets,
|
selectedQueryTargets: state.selectedQueryTargets,
|
||||||
selectedQueryTargetsByType: state.selectedQueryTargetsByType,
|
selectedQueryTargetsByType: state.selectedQueryTargetsByType,
|
||||||
setLastEditedQueryId: (lastEditedQueryId: number | null) => {
|
setLastEditedQueryId: (lastEditedQueryId: number | null) => {
|
||||||
@ -242,6 +251,12 @@ const QueryProvider = ({ children }: Props) => {
|
|||||||
lastEditedQueryDiscardData,
|
lastEditedQueryDiscardData,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
setEditingExistingQuery: (editingExistingQuery: boolean) => {
|
||||||
|
dispatch({
|
||||||
|
type: actions.SET_LAST_EDITED_QUERY_INFO,
|
||||||
|
editingExistingQuery,
|
||||||
|
});
|
||||||
|
},
|
||||||
setSelectedQueryTargets: (selectedQueryTargets: ITarget[]) => {
|
setSelectedQueryTargets: (selectedQueryTargets: ITarget[]) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: actions.SET_SELECTED_QUERY_TARGETS,
|
type: actions.SET_SELECTED_QUERY_TARGETS,
|
||||||
|
@ -24,6 +24,7 @@ export interface ISchedulableQuery {
|
|||||||
discard_data: boolean;
|
discard_data: boolean;
|
||||||
packs: IPack[];
|
packs: IPack[];
|
||||||
stats: ISchedulableQueryStats;
|
stats: ISchedulableQueryStats;
|
||||||
|
editingExistingQuery: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEnhancedQuery extends ISchedulableQuery {
|
export interface IEnhancedQuery extends ISchedulableQuery {
|
||||||
|
@ -71,6 +71,7 @@ const EditQueryPage = ({
|
|||||||
config,
|
config,
|
||||||
} = useContext(AppContext);
|
} = useContext(AppContext);
|
||||||
const {
|
const {
|
||||||
|
editingExistingQuery,
|
||||||
selectedOsqueryTable,
|
selectedOsqueryTable,
|
||||||
setSelectedOsqueryTable,
|
setSelectedOsqueryTable,
|
||||||
lastEditedQueryName,
|
lastEditedQueryName,
|
||||||
@ -127,7 +128,7 @@ const EditQueryPage = ({
|
|||||||
["query", queryId],
|
["query", queryId],
|
||||||
() => queryAPI.load(queryId as number),
|
() => queryAPI.load(queryId as number),
|
||||||
{
|
{
|
||||||
enabled: !!queryId,
|
enabled: !!queryId && !editingExistingQuery,
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
select: (data) => data.query,
|
select: (data) => data.query,
|
||||||
onSuccess: (returnedQuery) => {
|
onSuccess: (returnedQuery) => {
|
||||||
|
@ -150,6 +150,7 @@ const EditQueryForm = ({
|
|||||||
setLastEditedQueryMinOsqueryVersion,
|
setLastEditedQueryMinOsqueryVersion,
|
||||||
setLastEditedQueryLoggingType,
|
setLastEditedQueryLoggingType,
|
||||||
setLastEditedQueryDiscardData,
|
setLastEditedQueryDiscardData,
|
||||||
|
setEditingExistingQuery,
|
||||||
} = useContext(QueryContext);
|
} = useContext(QueryContext);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -825,6 +826,7 @@ const EditQueryForm = ({
|
|||||||
className={`${baseClass}__run`}
|
className={`${baseClass}__run`}
|
||||||
variant="blue-green"
|
variant="blue-green"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
setEditingExistingQuery(true); // Persists edited query data through live query flow
|
||||||
router.push(
|
router.push(
|
||||||
PATHS.LIVE_QUERY(queryIdForEdit) +
|
PATHS.LIVE_QUERY(queryIdForEdit) +
|
||||||
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
TAGGED_TEMPLATES.queryByHostRoute(hostId)
|
||||||
|
@ -44,6 +44,7 @@ const RunQueryPage = ({
|
|||||||
const handlePageError = useErrorHandler();
|
const handlePageError = useErrorHandler();
|
||||||
const { config } = useContext(AppContext);
|
const { config } = useContext(AppContext);
|
||||||
const {
|
const {
|
||||||
|
editingExistingQuery,
|
||||||
selectedQueryTargets,
|
selectedQueryTargets,
|
||||||
setSelectedQueryTargets,
|
setSelectedQueryTargets,
|
||||||
selectedQueryTargetsByType,
|
selectedQueryTargetsByType,
|
||||||
@ -88,7 +89,7 @@ const RunQueryPage = ({
|
|||||||
Error,
|
Error,
|
||||||
ISchedulableQuery
|
ISchedulableQuery
|
||||||
>(["query", queryId], () => queryAPI.load(queryId as number), {
|
>(["query", queryId], () => queryAPI.load(queryId as number), {
|
||||||
enabled: !!queryId,
|
enabled: !!queryId && !editingExistingQuery,
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
select: (data) => data.query,
|
select: (data) => data.query,
|
||||||
onSuccess: (returnedQuery) => {
|
onSuccess: (returnedQuery) => {
|
||||||
|
@ -47,6 +47,8 @@ const RunQuery = ({
|
|||||||
DEFAULT_CAMPAIGN_STATE
|
DEFAULT_CAMPAIGN_STATE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isStoredQueryEdited = storedQuery?.query !== lastEditedQueryBody;
|
||||||
|
|
||||||
const ws = useRef(null);
|
const ws = useRef(null);
|
||||||
const runQueryInterval = useRef<any>(null);
|
const runQueryInterval = useRef<any>(null);
|
||||||
const globalSocket = useRef<any>(null);
|
const globalSocket = useRef<any>(null);
|
||||||
@ -168,8 +170,6 @@ const RunQuery = ({
|
|||||||
destroyCampaign();
|
destroyCampaign();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isStoredQueryEdited = storedQuery?.query !== lastEditedQueryBody;
|
|
||||||
|
|
||||||
const returnedCampaign = await queryAPI.run({
|
const returnedCampaign = await queryAPI.run({
|
||||||
query: lastEditedQueryBody,
|
query: lastEditedQueryBody,
|
||||||
queryId: isStoredQueryEdited ? null : queryId, // we treat edited SQL as a new query
|
queryId: isStoredQueryEdited ? null : queryId, // we treat edited SQL as a new query
|
||||||
|
@ -132,6 +132,7 @@ export const DEFAULT_QUERY: ISchedulableQuery = {
|
|||||||
team_id: 0,
|
team_id: 0,
|
||||||
author_email: "",
|
author_email: "",
|
||||||
stats: {},
|
stats: {},
|
||||||
|
editingExistingQuery: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_CAMPAIGN = {
|
export const DEFAULT_CAMPAIGN = {
|
||||||
|
Loading…
Reference in New Issue
Block a user