[Osquery] Prepare for versioned HTTP APIs (#158500)

This commit is contained in:
Patryk Kopyciński 2023-05-30 18:08:56 +02:00 committed by GitHub
parent 47eed48cde
commit bb1731786d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 297 additions and 318 deletions

View file

@ -19,7 +19,6 @@ import {
removedOrUndefined,
ecsMappingOrUndefined,
} from '@kbn/osquery-io-ts-types';
import type { RequiredKeepUndefined } from '../../../types';
export const createSavedQueryRequestSchema = t.type({
id,
@ -36,9 +35,8 @@ export const createSavedQueryRequestSchema = t.type({
export type CreateSavedQueryRequestSchema = t.OutputOf<typeof createSavedQueryRequestSchema>;
// This type is used after a decode since some things are defaults after a decode.
export type CreateSavedQueryRequestSchemaDecoded = Omit<
RequiredKeepUndefined<t.TypeOf<typeof createSavedQueryRequestSchema>>,
'description'
export type CreateSavedQueryRequestSchemaDecoded = t.TypeOf<
typeof createSavedQueryRequestSchema
> & {
description: Description;
};

View file

@ -9,20 +9,3 @@ export const savedQuerySavedObjectType = 'osquery-saved-query';
export const packSavedObjectType = 'osquery-pack';
export const packAssetSavedObjectType = 'osquery-pack-asset';
export const usageMetricSavedObjectType = 'osquery-manager-usage-metric';
/**
* This makes any optional property the same as Required<T> would but also has the
* added benefit of keeping your undefined.
*
* For example:
* type A = RequiredKeepUndefined<{ a?: undefined; b: number }>;
*
* will yield a type of:
* type A = { a: undefined; b: number; }
*
*/
export type RequiredKeepUndefined<T> = { [K in keyof T]-?: [T[K]] } extends infer U
? U extends Record<keyof U, [unknown]>
? { [K in keyof U]: U[K][0] }
: never
: never;

View file

@ -37,7 +37,7 @@ describe('ALL - Add Integration', () => {
before(() => {
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryId = data.saved_object_id;
});
});

View file

@ -64,8 +64,8 @@ describe('Alert Event Details', () => {
before(() => {
loadPack(packData).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadRule().then((data) => {
ruleId = data.id;
@ -107,12 +107,12 @@ describe('Alert Event Details', () => {
before(() => {
loadPack(packData).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadPack(multiQueryPackData).then((data) => {
multiQueryPackId = data.id;
multiQueryPackName = data.attributes.name;
multiQueryPackId = data.saved_object_id;
multiQueryPackName = data.name;
});
loadRule().then((data) => {
ruleId = data.id;
@ -382,8 +382,8 @@ describe('Alert Event Details', () => {
before(() => {
loadPack(packData).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadRule(true).then((data) => {
ruleId = data.id;

View file

@ -49,8 +49,8 @@ describe('ALL - Custom space', () => {
},
space as string
).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
});
});
@ -96,7 +96,7 @@ describe('ALL - Custom space', () => {
cy.contains('Packs').click();
cy.contains('Create pack').click();
cy.react('CustomItemAction', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
}).click();
selectAllAgents();
cy.contains('Submit').click();

View file

@ -15,8 +15,8 @@ describe('ALL - Edit saved query', () => {
before(() => {
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
});
@ -31,7 +31,7 @@ describe('ALL - Edit saved query', () => {
it('by changing ecs mappings and platforms', () => {
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryName } } },
props: { index: 1, item: { id: savedQueryName } },
}).click();
cy.contains('Custom key/value pairs.').should('exist');
cy.contains('Hours of uptime').should('exist');
@ -72,7 +72,7 @@ describe('ALL - Edit saved query', () => {
cy.wait(5000);
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryName } } },
props: { index: 1, item: { id: savedQueryName } },
}).click();
cy.contains('Custom key/value pairs').should('not.exist');
cy.contains('Hours of uptime').should('not.exist');

View file

@ -63,16 +63,16 @@ describe('ALL - Live Query', () => {
},
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
loadSavedQuery({
interval: '3600',
query: 'select * from uptime;',
ecs_mapping: {},
}).then((savedQuery) => {
savedQueryId = savedQuery.id;
savedQueryName = savedQuery.attributes.name;
savedQueryId = savedQuery.saved_object_id;
savedQueryName = savedQuery.name;
});
loadCase('securitySolution').then((caseInfo) => {
caseId = caseInfo.id;

View file

@ -17,8 +17,8 @@ describe('ALL - Inventory', () => {
before(() => {
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
});

View file

@ -63,16 +63,16 @@ describe('ALL - Packs', () => {
describe('Create and edit a pack', () => {
before(() => {
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
loadSavedQuery({
ecs_mapping: {},
interval: '3600',
query: 'select * from uptime;',
}).then((data) => {
nomappingSavedQueryId = data.id;
nomappingSavedQueryName = data.attributes.id;
nomappingSavedQueryId = data.saved_object_id;
nomappingSavedQueryName = data.id;
});
loadSavedQuery({
ecs_mapping: {
@ -83,8 +83,8 @@ describe('ALL - Packs', () => {
interval: '3600',
query: 'select * from uptime;',
}).then((data) => {
oneMappingSavedQueryId = data.id;
oneMappingSavedQueryName = data.attributes.id;
oneMappingSavedQueryId = data.saved_object_id;
oneMappingSavedQueryName = data.id;
});
loadSavedQuery({
ecs_mapping: {
@ -101,8 +101,8 @@ describe('ALL - Packs', () => {
interval: '3600',
query: 'select * from uptime;',
}).then((data) => {
multipleMappingsSavedQueryId = data.id;
multipleMappingsSavedQueryName = data.attributes.id;
multipleMappingsSavedQueryId = data.saved_object_id;
multipleMappingsSavedQueryName = data.id;
});
});
@ -290,8 +290,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -332,8 +332,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -365,8 +365,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -408,8 +408,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -452,8 +452,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -479,8 +479,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 60, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -537,8 +537,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -574,8 +574,8 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packId = pack.id;
packName = pack.attributes.name;
packId = pack.saved_object_id;
packName = pack.name;
});
});
@ -631,7 +631,7 @@ describe('ALL - Packs', () => {
[savedQueryName]: { ecs_mapping: {}, interval: 3600, query: 'select * from uptime;' },
},
}).then((pack) => {
packName = pack.attributes.name;
packName = pack.name;
});
});

View file

@ -76,8 +76,8 @@ describe('ALL - Saved queries', () => {
},
},
}).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
});
@ -93,7 +93,7 @@ describe('ALL - Saved queries', () => {
it('checks result type on prebuilt saved query', () => {
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: 'users_elastic' } } },
props: { index: 1, item: { id: 'users_elastic' } },
}).click();
cy.getBySel('resultsTypeField').within(() => {
cy.contains('Snapshot');
@ -102,7 +102,7 @@ describe('ALL - Saved queries', () => {
it('user can run prebuilt saved query and add to case', () => {
cy.react('PlayButtonComponent', {
props: { savedQuery: { attributes: { id: 'users_elastic' } } },
props: { savedQuery: { id: 'users_elastic' } },
}).click();
selectAllAgents();
@ -114,7 +114,7 @@ describe('ALL - Saved queries', () => {
it('user cant delete prebuilt saved query', () => {
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: 'users_elastic' } } },
props: { index: 1, item: { id: 'users_elastic' } },
}).click();
cy.contains('Delete query').should('not.exist');
navigateTo('/app/osquery/saved_queries');
@ -124,7 +124,7 @@ describe('ALL - Saved queries', () => {
findFormFieldByRowsLabelAndType('ID', 'query-to-delete');
cy.contains('Save query').click();
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: 'query-to-delete' } } },
props: { index: 1, item: { id: 'query-to-delete' } },
}).click();
deleteAndConfirm('query');
});

View file

@ -35,8 +35,8 @@ describe('Alert Test', () => {
},
},
}).then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadRule().then((data) => {
ruleId = data.id;

View file

@ -24,12 +24,12 @@ describe('Reader - only READ', () => {
before(() => {
loadPack().then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
loadLiveQuery().then((data) => {
liveQueryQuery = data.queries?.[0].query;
@ -51,11 +51,11 @@ describe('Reader - only READ', () => {
cy.contains(savedQueryName);
cy.contains('Add saved query').should('be.disabled');
cy.react('PlayButtonComponent', {
props: { savedQuery: { attributes: { id: savedQueryName } } },
props: { savedQuery: { id: savedQueryName } },
options: { timeout: 3000 },
}).should('not.exist');
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryName } } },
props: { index: 1, item: { id: savedQueryName } },
}).click();
cy.react('EuiFormRow', { props: { label: 'ID' } })
.getBySel('input')
@ -90,7 +90,7 @@ describe('Reader - only READ', () => {
cy.getBySel('tablePaginationPopoverButton').click();
cy.getBySel('tablePagination-50-rows').click();
cy.react('ActiveStateSwitchComponent', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
})
.find('button')
.should('be.disabled');

View file

@ -32,12 +32,12 @@ describe('T1 Analyst - READ + runSavedQueries ', () => {
before(() => {
loadPack().then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
loadLiveQuery().then((data) => {
liveQueryQuery = data.queries?.[0].query;
@ -59,7 +59,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => {
cy.contains(savedQueryName);
cy.contains('Add saved query').should('be.disabled');
cy.react('PlayButtonComponent', {
props: { savedQuery: { attributes: { id: savedQueryName } } },
props: { savedQuery: { id: savedQueryName } },
})
.should('not.be.disabled')
.click();
@ -105,7 +105,7 @@ describe('T1 Analyst - READ + runSavedQueries ', () => {
cy.getBySel('tablePagination-50-rows').click();
cy.contains('Add pack').should('be.disabled');
cy.react('ActiveStateSwitchComponent', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
})
.find('button')
.should('be.disabled');

View file

@ -29,12 +29,12 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
before(() => {
loadPack().then((data) => {
packId = data.id;
packName = data.attributes.name;
packId = data.saved_object_id;
packName = data.name;
});
loadSavedQuery().then((data) => {
savedQueryId = data.id;
savedQueryName = data.attributes.id;
savedQueryId = data.saved_object_id;
savedQueryName = data.id;
});
});
@ -57,7 +57,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
cy.getBySel('tablePagination-50-rows').click();
cy.contains('Add pack').should('be.disabled');
cy.react('ActiveStateSwitchComponent', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
})
.find('button')
.should('be.disabled');
@ -121,7 +121,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
it('to click the edit button and edit pack', () => {
navigateTo('/app/osquery/saved_queries');
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryName } } },
props: { index: 1, item: { id: savedQueryName } },
}).click();
cy.contains('Custom key/value pairs.').should('exist');
cy.contains('Hours of uptime').should('exist');
@ -134,7 +134,7 @@ describe('T2 Analyst - READ + Write Live/Saved + runSavedQueries ', () => {
cy.wait(5000);
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryName } } },
props: { index: 1, item: { id: savedQueryName } },
}).click();
cy.contains('Custom key/value pairs').should('not.exist');
cy.contains('Hours of uptime').should('not.exist');

View file

@ -75,7 +75,7 @@ export const interceptPackId = (cb: (packId: string) => void) => {
cy.intercept('POST', '**/api/osquery/packs', (req) => {
req.continue((res) => {
if (res.body.data) {
cb(res.body.data.id);
cb(res.body.data.saved_object_id);
}
return res.send(res.body);

View file

@ -21,7 +21,7 @@ export const preparePack = (packName: string) => {
export const deactivatePack = (packName: string) => {
cy.react('ActiveStateSwitchComponent', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
}).click();
closeModalIfVisible();
@ -32,7 +32,7 @@ export const deactivatePack = (packName: string) => {
export const activatePack = (packName: string) => {
cy.react('ActiveStateSwitchComponent', {
props: { item: { attributes: { name: packName } } },
props: { item: { name: packName } },
}).click();
closeModalIfVisible();
@ -50,6 +50,6 @@ export const cleanupAllPrebuiltPacks = () => {
some(pack.references, { type: 'osquery-pack-asset' })
);
return Promise.all(prebuiltPacks?.map((pack) => cleanupPack(pack.id)));
return Promise.all(prebuiltPacks?.map((pack) => cleanupPack(pack.saved_object_id)));
});
};

View file

@ -94,7 +94,7 @@ export const getSavedQueriesComplexTest = () =>
navigateTo('/app/osquery/saved_queries');
cy.contains(savedQueryId);
cy.react('PlayButtonComponent', {
props: { savedQuery: { attributes: { id: savedQueryId } } },
props: { savedQuery: { id: savedQueryId } },
}).click();
selectAllAgents();
submitQuery();
@ -103,7 +103,7 @@ export const getSavedQueriesComplexTest = () =>
cy.contains('Saved queries').click();
cy.contains(savedQueryId);
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryId } } },
props: { index: 1, item: { id: savedQueryId } },
}).click();
findFormFieldByRowsLabelAndType('Description (optional)', ' Edited');
// Run in test configuration
@ -127,7 +127,7 @@ export const getSavedQueriesComplexTest = () =>
// delete saved query
cy.contains(savedQueryId);
cy.react('CustomItemAction', {
props: { index: 1, item: { attributes: { id: savedQueryId } } },
props: { index: 1, item: { id: savedQueryId } },
}).click();
deleteAndConfirm('query');
cy.contains(savedQueryId).should('exist');

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import type { SavedObject } from '@kbn/core/public';
import type { KibanaAssetReference } from '@kbn/fleet-plugin/common';
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '../common/lib/kibana';
import { INTEGRATION_ASSETS_STATUS_ID } from './constants';
@ -13,12 +13,12 @@ import { INTEGRATION_ASSETS_STATUS_ID } from './constants';
export const useAssetsStatus = () => {
const { http } = useKibana().services;
return useQuery<{ install: SavedObject[]; update: SavedObject[]; upToDate: SavedObject[] }>(
[INTEGRATION_ASSETS_STATUS_ID],
() => http.get('/internal/osquery/assets'),
{
keepPreviousData: true,
retry: false,
}
);
return useQuery<{
install: KibanaAssetReference[];
update: KibanaAssetReference[];
upToDate: KibanaAssetReference[];
}>([INTEGRATION_ASSETS_STATUS_ID], () => http.get('/internal/osquery/assets'), {
keepPreviousData: true,
retry: false,
});
};

View file

@ -250,7 +250,7 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
setValue('queryType', 'pack');
if (!isPackDataFetched) return;
const selectedPackOption = find(packsData?.data, ['id', defaultValue.packId]);
const selectedPackOption = find(packsData?.data, ['saved_object_id', defaultValue.packId]);
if (selectedPackOption) {
setValue('packId', [defaultValue.packId]);
}

View file

@ -81,11 +81,11 @@ export const PacksComboBoxField = ({
const packOptions = useMemo<Array<EuiComboBoxOptionOption<PackOption>>>(
() =>
fieldProps?.packsData?.map((packSO) => ({
label: packSO.attributes.name ?? '',
label: packSO.name ?? '',
value: {
id: packSO.id,
name: packSO.attributes.name,
description: packSO.attributes.description,
id: packSO.saved_object_id,
name: packSO.name,
description: packSO.description,
},
})) ?? [],
[fieldProps?.packsData]

View file

@ -58,17 +58,17 @@ const ActiveStateSwitchComponent: React.FC<ActiveStateSwitchProps> = ({ item })
queryClient.invalidateQueries([PACKS_ID]);
setErrorToast();
toasts.addSuccess(
response?.data?.attributes.enabled
response?.data?.enabled
? i18n.translate('xpack.osquery.pack.table.activatedSuccessToastMessageText', {
defaultMessage: 'Successfully activated "{packName}" pack',
values: {
packName: response?.data?.attributes.name,
packName: response?.data?.name,
},
})
: i18n.translate('xpack.osquery.pack.table.deactivatedSuccessToastMessageText', {
defaultMessage: 'Successfully deactivated "{packName}" pack',
values: {
packName: response?.data?.attributes.name,
packName: response?.data?.name,
},
})
);
@ -77,7 +77,7 @@ const ActiveStateSwitchComponent: React.FC<ActiveStateSwitchProps> = ({ item })
});
const handleToggleActive = useCallback(() => {
mutateAsync({ id: item.id, enabled: !item.attributes.enabled });
mutateAsync({ id: item.saved_object_id, enabled: !item.enabled });
hideConfirmationModal();
}, [hideConfirmationModal, item, mutateAsync]);
@ -93,7 +93,7 @@ const ActiveStateSwitchComponent: React.FC<ActiveStateSwitchProps> = ({ item })
<>
{isLoading && <StyledEuiLoadingSpinner />}
<EuiSwitch
checked={!!item.attributes.enabled}
checked={!!item.enabled}
disabled={!permissions.writePacks || isLoading}
showLabel={false}
label=""

View file

@ -169,15 +169,15 @@ const PackFormComponent: React.FC<PackFormProps> = ({
};
try {
if (editMode && defaultValue?.id) {
await updateAsync({ id: defaultValue?.id, ...serializer(values) });
if (editMode && defaultValue?.saved_object_id) {
await updateAsync({ id: defaultValue?.saved_object_id, ...serializer(values) });
} else {
await createAsync(serializer(values));
}
// eslint-disable-next-line no-empty
} catch (e) {}
},
[createAsync, defaultValue?.id, editMode, getShards, shards, updateAsync]
[createAsync, defaultValue?.saved_object_id, editMode, getShards, shards, updateAsync]
);
const handleSubmitForm = useMemo(() => handleSubmit(onSubmit), [handleSubmit, onSubmit]);

View file

@ -42,8 +42,8 @@ const ScheduledQueryNameComponent = ({ id, name }: { id: string; name: string })
const ScheduledQueryName = React.memo(ScheduledQueryNameComponent);
const renderName = (_: unknown, item: { id: string; attributes: { name: string } }) => (
<ScheduledQueryName id={item.id} name={item.attributes.name} />
const renderName = (_: unknown, item: PackSavedObject) => (
<ScheduledQueryName id={item.saved_object_id} name={item.name} />
);
export const AgentPoliciesPopover = ({ agentPolicyIds = [] }: { agentPolicyIds?: string[] }) => {
@ -101,10 +101,7 @@ const PacksTableComponent = () => {
const renderUpdatedAt = useCallback((updatedAt, item) => {
if (!updatedAt) return '-';
const updatedBy =
item.attributes.updated_by !== item.attributes.created_by
? ` @ ${item.attributes.updated_by}`
: '';
const updatedBy = item.updated_by !== item.created_by ? ` @ ${item.updated_by}` : '';
return updatedAt ? (
<EuiToolTip content={`${moment(updatedAt).fromNow()}${updatedBy}`}>
@ -119,7 +116,7 @@ const PacksTableComponent = () => {
(item) => () =>
push('/live_queries/new', {
form: {
packId: item.id,
packId: item.saved_object_id,
},
}),
[push]
@ -130,7 +127,7 @@ const PacksTableComponent = () => {
const playText = i18n.translate('xpack.osquery.packs.table.runActionAriaLabel', {
defaultMessage: 'Run {packName}',
values: {
packName: item.attributes.name,
packName: item.name,
},
});
@ -146,11 +143,11 @@ const PacksTableComponent = () => {
const columns: Array<EuiBasicTableColumn<PackSavedObject>> = useMemo(
() => [
{
field: 'attributes.name',
field: 'name',
name: i18n.translate('xpack.osquery.packs.table.nameColumnTitle', {
defaultMessage: 'Name',
}),
sortable: (item) => item.attributes.name.toLowerCase(),
sortable: (item) => item.name.toLowerCase(),
render: renderName,
},
{
@ -162,7 +159,7 @@ const PacksTableComponent = () => {
render: renderAgentPolicy,
},
{
field: 'attributes.queries',
field: 'queries',
name: i18n.translate('xpack.osquery.packs.table.numberOfQueriesColumnTitle', {
defaultMessage: 'Number of queries',
}),
@ -170,7 +167,7 @@ const PacksTableComponent = () => {
width: '150px',
},
{
field: 'attributes.created_by',
field: 'created_by',
name: i18n.translate('xpack.osquery.packs.table.createdByColumnTitle', {
defaultMessage: 'Created by',
}),
@ -178,14 +175,14 @@ const PacksTableComponent = () => {
truncateText: true,
},
{
field: 'attributes.updated_at',
field: 'updated_at',
name: 'Last updated',
sortable: (item) => (item.updated_at ? Date.parse(item.updated_at) : 0),
truncateText: true,
render: renderUpdatedAt,
},
{
field: 'attributes.enabled',
field: 'enabled',
name: i18n.translate('xpack.osquery.packs.table.activeColumnTitle', {
defaultMessage: 'Active',
}),
@ -221,7 +218,7 @@ const PacksTableComponent = () => {
const sorting = useMemo(
() => ({
sort: {
field: 'attributes.name',
field: 'name',
direction: 'asc' as const,
},
}),

View file

@ -4,11 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { SavedObject } from '@kbn/core/public';
import type { Shard } from '../../common/schemas/common/utils';
import type { PackQueryFormData } from './queries/use_pack_query_form';
export type PackSavedObject = SavedObject<{
export interface PackSavedObject {
saved_object_id: string;
name: string;
description: string | undefined;
queries: Record<string, Omit<PackQueryFormData, 'id'>>;
@ -18,9 +18,10 @@ export type PackSavedObject = SavedObject<{
created_by: string | undefined;
updated_at: string;
updated_by: string | undefined;
}>;
references: Array<{ name: string; id: string; type: string }>;
}
export type PackItem = PackSavedObject['attributes'] & {
export type PackItem = PackSavedObject & {
id: string;
policy_ids: string[];
read_only?: boolean;

View file

@ -51,7 +51,7 @@ export const useCreatePack = ({ withRedirect }: UseCreatePackProps) => {
i18n.translate('xpack.osquery.newPack.successToastMessageText', {
defaultMessage: 'Successfully created "{packName}" pack',
values: {
packName: payload.data.attributes?.name ?? '',
packName: payload.data?.name ?? '',
},
})
);

View file

@ -5,16 +5,16 @@
* 2.0.
*/
import type { SavedObjectsFindResponse } from '@kbn/core/public';
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '../common/lib/kibana';
import { PACKS_ID } from './constants';
import type { PackSavedObject } from './types';
export type UsePacksResponse = Omit<SavedObjectsFindResponse, 'savedObjects'> & {
export interface UsePacksResponse {
total: number;
data: PackSavedObject[];
};
}
export const usePacks = ({
isLive = false,

View file

@ -21,7 +21,7 @@ interface UseUpdatePackProps {
options?: UseMutationOptions<
{ data: PackSavedObject },
{ body: { message: string; error: string } },
Partial<PackSavedObject['attributes']> & { id: string }
Partial<PackSavedObject> & { id: string }
>;
}
@ -37,7 +37,7 @@ export const useUpdatePack = ({ withRedirect, options }: UseUpdatePackProps) =>
return useMutation<
{ data: PackSavedObject },
{ body: { message: string; error: string } },
Partial<PackSavedObject['attributes']> & { id: string }
Partial<PackSavedObject> & { id: string }
>(
({ id, ...payload }) =>
http.put(`/api/osquery/packs/${id}`, {
@ -57,7 +57,7 @@ export const useUpdatePack = ({ withRedirect, options }: UseUpdatePackProps) =>
i18n.translate('xpack.osquery.updatePack.successToastMessageText', {
defaultMessage: 'Successfully updated "{packName}" pack',
values: {
packName: response?.data?.attributes?.name ?? '',
packName: response?.data?.name ?? '',
},
})
);

View file

@ -41,12 +41,9 @@ const EditSavedQueryPageComponent = () => {
const updateSavedQueryMutation = useUpdateSavedQuery({ savedQueryId });
const deleteSavedQueryMutation = useDeleteSavedQuery({ savedQueryId });
useBreadcrumbs('saved_query_edit', { savedQueryName: savedQueryDetails?.attributes?.id ?? '' });
useBreadcrumbs('saved_query_edit', { savedQueryName: savedQueryDetails?.saved_object_id ?? '' });
const elasticPrebuiltQuery = useMemo(
() => !!savedQueryDetails?.attributes?.prebuilt,
[savedQueryDetails]
);
const elasticPrebuiltQuery = useMemo(() => !!savedQueryDetails?.prebuilt, [savedQueryDetails]);
const viewMode = useMemo(
() => !permissions.writeSavedQueries || elasticPrebuiltQuery,
[permissions.writeSavedQueries, elasticPrebuiltQuery]
@ -87,7 +84,7 @@ const EditSavedQueryPageComponent = () => {
defaultMessage='"{savedQueryId}" details'
// eslint-disable-next-line react-perf/jsx-no-new-object-as-prop
values={{
savedQueryId: savedQueryDetails?.attributes?.id ?? '',
savedQueryId: savedQueryDetails?.id ?? '',
}}
/>
{elasticPrebuiltQuery && (
@ -105,7 +102,7 @@ const EditSavedQueryPageComponent = () => {
defaultMessage='Edit "{savedQueryId}"'
// eslint-disable-next-line react-perf/jsx-no-new-object-as-prop
values={{
savedQueryId: savedQueryDetails?.attributes?.id ?? '',
savedQueryId: savedQueryDetails?.id ?? '',
}}
/>
)}
@ -114,7 +111,7 @@ const EditSavedQueryPageComponent = () => {
</EuiFlexItem>
</EuiFlexGroup>
),
[elasticPrebuiltQuery, savedQueryDetails?.attributes?.id, savedQueryListProps, viewMode]
[elasticPrebuiltQuery, savedQueryDetails?.id, savedQueryListProps, viewMode]
);
const RightColumn = useMemo(
@ -146,7 +143,7 @@ const EditSavedQueryPageComponent = () => {
>
{!isLoading && !isEmpty(savedQueryDetails) && (
<EditSavedQueryForm
defaultValue={savedQueryDetails?.attributes}
defaultValue={savedQueryDetails}
handleSubmit={handleSubmit}
viewMode={viewMode}
/>

View file

@ -21,8 +21,6 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { useHistory } from 'react-router-dom';
import deepEqual from 'fast-deep-equal';
import type { SavedObject } from '@kbn/core/public';
import type { ECSMapping } from '@kbn/osquery-io-ts-types';
import { Direction } from '../../../../common/search_strategy';
import { WithHeaderLayout } from '../../../components/layouts';
@ -30,15 +28,16 @@ import { useBreadcrumbs } from '../../../common/hooks/use_breadcrumbs';
import { useKibana, useRouterNavigate } from '../../../common/lib/kibana';
import { useSavedQueries } from '../../../saved_queries/use_saved_queries';
export type SavedQuerySO = SavedObject<{
export interface SavedQuerySO {
name: string;
id: string;
saved_object_id: string;
description?: string;
query: string;
ecs_mapping: ECSMapping;
updated_at: string;
prebuilt?: boolean;
}>;
}
interface PlayButtonProps {
disabled: boolean;
@ -54,8 +53,8 @@ const PlayButtonComponent: React.FC<PlayButtonProps> = ({ disabled = false, save
push('/live_queries/new', {
form: {
savedQueryId: savedQuery.id,
query: savedQuery.attributes.query,
ecs_mapping: savedQuery.attributes.ecs_mapping,
query: savedQuery.query,
ecs_mapping: savedQuery.ecs_mapping,
},
}),
[push, savedQuery]
@ -66,7 +65,7 @@ const PlayButtonComponent: React.FC<PlayButtonProps> = ({ disabled = false, save
i18n.translate('xpack.osquery.savedQueryList.queriesTable.runActionAriaLabel', {
defaultMessage: 'Run {savedQueryName}',
values: {
savedQueryName: savedQuery.attributes.id,
savedQueryName: savedQuery.id,
},
}),
[savedQuery]
@ -133,14 +132,14 @@ const SavedQueriesPageComponent = () => {
const newQueryLinkProps = useRouterNavigate('saved_queries/new');
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(20);
const [sortField, setSortField] = useState('attributes.updated_at');
const [sortField, setSortField] = useState('updated_at');
const [sortDirection, setSortDirection] = useState<Direction>(Direction.desc);
const { data } = useSavedQueries({ isLive: true });
const renderEditAction = useCallback(
(item: SavedQuerySO) => (
<EditButton savedQueryId={item.id} savedQueryName={item.attributes.id} />
<EditButton savedQueryId={item.saved_object_id} savedQueryName={item.id} />
),
[]
);
@ -158,10 +157,7 @@ const SavedQueriesPageComponent = () => {
const renderUpdatedAt = useCallback((updatedAt, item) => {
if (!updatedAt) return '-';
const updatedBy =
item.attributes.updated_by !== item.attributes.created_by
? ` @ ${item.attributes.updated_by}`
: '';
const updatedBy = item.updated_by !== item.created_by ? ` @ ${item.updated_by}` : '';
return updatedAt ? `${moment(updatedAt).fromNow()}${updatedBy}` : '-';
}, []);
@ -179,16 +175,16 @@ const SavedQueriesPageComponent = () => {
const columns: Array<EuiBasicTableColumn<SavedQuerySO>> = useMemo(
() => [
{
field: 'attributes.id',
field: 'id',
name: i18n.translate('xpack.osquery.savedQueries.table.queryIdColumnTitle', {
defaultMessage: 'Query ID',
}),
sortable: (item) => item.attributes.id.toLowerCase(),
sortable: (item) => item.id.toLowerCase(),
truncateText: true,
width: '15%',
},
{
field: 'attributes.description',
field: 'description',
name: i18n.translate('xpack.osquery.savedQueries.table.descriptionColumnTitle', {
defaultMessage: 'Description',
}),
@ -196,7 +192,7 @@ const SavedQueriesPageComponent = () => {
width: '50%',
},
{
field: 'attributes.created_by',
field: 'created_by',
name: i18n.translate('xpack.osquery.savedQueries.table.createdByColumnTitle', {
defaultMessage: 'Created by',
}),
@ -205,13 +201,12 @@ const SavedQueriesPageComponent = () => {
truncateText: true,
},
{
field: 'attributes.updated_at',
field: 'updated_at',
name: i18n.translate('xpack.osquery.savedQueries.table.updatedAtColumnTitle', {
defaultMessage: 'Last updated at',
}),
width: '10%',
sortable: (item) =>
item.attributes.updated_at ? Date.parse(item.attributes.updated_at) : 0,
sortable: (item) => (item.updated_at ? Date.parse(item.updated_at) : 0),
truncateText: true,
render: renderUpdatedAt,
},

View file

@ -77,7 +77,7 @@ export const savedQueryDataSerializer = (payload: SavedQueryFormData): SavedQuer
export const useSavedQueryForm = ({ defaultValue }: UseSavedQueryFormProps) => {
const { data } = useSavedQueries({});
const ids: string[] = useMemo<string[]>(() => map(data?.data, 'attributes.id') ?? [], [data]);
const ids: string[] = useMemo<string[]>(() => map(data?.data, 'id') ?? [], [data]);
const idSet = useMemo<Set<string>>(() => {
const res = new Set<string>(ids);
if (defaultValue && defaultValue.id) res.delete(defaultValue.id);

View file

@ -31,7 +31,7 @@ export interface SavedQueriesDropdownProps {
disabled?: boolean;
onChange: (
value:
| (Pick<SavedQuerySO['attributes'], 'id' | 'description' | 'query' | 'ecs_mapping'> & {
| (Pick<SavedQuerySO, 'id' | 'description' | 'query' | 'ecs_mapping'> & {
savedQueryId: string;
})
| null
@ -40,7 +40,7 @@ export interface SavedQueriesDropdownProps {
interface SelectedOption {
label: string;
value: Pick<SavedQuerySO['attributes'], 'id' | 'description' | 'query' | 'ecs_mapping'> & {
value: Pick<SavedQuerySO, 'id' | 'description' | 'query' | 'ecs_mapping'> & {
savedQueryId: string;
};
}
@ -60,13 +60,13 @@ const SavedQueriesDropdownComponent: React.FC<SavedQueriesDropdownProps> = ({
const queryOptions = useMemo(
() =>
data?.data?.map((savedQuery) => ({
label: savedQuery.attributes.id ?? '',
label: savedQuery.id ?? '',
value: {
savedQueryId: savedQuery.id,
id: savedQuery.attributes.id,
description: savedQuery.attributes.description,
query: savedQuery.attributes.query,
ecs_mapping: savedQuery.attributes.ecs_mapping,
id: savedQuery.id,
description: savedQuery.description,
query: savedQuery.query,
ecs_mapping: savedQuery.ecs_mapping,
},
})) ?? [],
[data]
@ -81,13 +81,10 @@ const SavedQueriesDropdownComponent: React.FC<SavedQueriesDropdownProps> = ({
return;
}
const selectedSavedQuery = find(
['attributes.id', newSelectedOptions[0].value.id],
data?.data
);
const selectedSavedQuery = find(['id', newSelectedOptions[0].value.id], data?.data);
if (selectedSavedQuery) {
onChange({ ...selectedSavedQuery.attributes, savedQueryId: selectedSavedQuery.id });
onChange({ ...selectedSavedQuery, savedQueryId: selectedSavedQuery.id });
}
setSelectedOptions(newSelectedOptions);

View file

@ -55,7 +55,7 @@ export const useCreateSavedQuery = ({ withRedirect }: UseCreateSavedQueryProps)
i18n.translate('xpack.osquery.newSavedQuery.successToastMessageText', {
defaultMessage: 'Successfully saved "{savedQueryId}" query',
values: {
savedQueryId: response.data.attributes?.id ?? '',
savedQueryId: response.data?.id ?? '',
},
})
);

View file

@ -7,7 +7,6 @@
import { useQuery } from '@tanstack/react-query';
import type { SavedObjectsFindResponse } from '@kbn/core/public';
import { useKibana } from '../common/lib/kibana';
import { useErrorToast } from '../common/hooks/use_error_toast';
import { SAVED_QUERIES_ID } from './constants';
@ -24,7 +23,10 @@ export const useSavedQueries = ({
const setErrorToast = useErrorToast();
return useQuery<
Omit<SavedObjectsFindResponse, 'savedObjects'> & {
{
total: number;
perPage: number;
page: number;
data: SavedQuerySO[];
},
{ body: { error: string; message: string } }

View file

@ -33,7 +33,7 @@ export const useSavedQuery = ({ savedQueryId }: UseSavedQueryProps) => {
};
},
{ body: { error: string; message: string } },
SavedQuerySO
SavedQuerySO & { error?: { error: string; message: string } }
>(
[SAVED_QUERY_ID, { savedQueryId }],
() => http.get(`/api/osquery/saved_queries/${savedQueryId}`),

View file

@ -48,7 +48,7 @@ export const useUpdateSavedQuery = ({ savedQueryId }: UseUpdateSavedQueryProps)
i18n.translate('xpack.osquery.editSavedQuery.successToastMessageText', {
defaultMessage: 'Successfully updated "{savedQueryName}" query',
values: {
savedQueryName: payload.data.attributes?.id ?? '',
savedQueryName: payload.data.id ?? '',
},
})
);

View file

@ -37,7 +37,7 @@ export const PackFieldWrapper = ({
const { packId } = useWatch<{ packId: string[] }>();
const selectedPackData = useMemo(
() => (packId?.length ? find(packsData?.data, { id: packId[0] }) : null),
() => (packId?.length ? find(packsData?.data, { saved_object_id: packId[0] }) : null),
[packId, packsData]
);
@ -56,18 +56,16 @@ export const PackFieldWrapper = ({
{submitButtonContent}
<EuiSpacer />
{liveQueryDetails?.queries?.length || selectedPackData?.attributes?.queries?.length ? (
<>
<EuiFlexItem>
<PackQueriesStatusTable
actionId={actionId}
agentIds={agentIds}
// @ts-expect-error update types
data={liveQueryDetails?.queries ?? selectedPackData?.attributes?.queries}
showResultsHeader={showResultsHeader}
/>
</EuiFlexItem>
</>
{liveQueryDetails?.queries?.length || selectedPackData?.queries?.length ? (
<EuiFlexItem>
<PackQueriesStatusTable
actionId={actionId}
agentIds={agentIds}
// @ts-expect-error update types
data={liveQueryDetails?.queries ?? selectedPackData?.queries}
showResultsHeader={showResultsHeader}
/>
</EuiFlexItem>
) : null}
</>
);

View file

@ -5,18 +5,15 @@
* 2.0.
*/
import type { SavedObject } from '@kbn/core/server';
export interface IQueryPayload {
attributes?: {
name: string;
id: string;
};
name: string;
id: string;
}
export type SOShard = Array<{ key: string; value: number }>;
export interface PackSavedObjectAttributes {
export interface PackSavedObject {
saved_object_id: string;
name: string;
description: string | undefined;
queries: Array<{
@ -36,11 +33,10 @@ export interface PackSavedObjectAttributes {
updated_by: string | undefined;
policy_ids?: string[];
shards: SOShard;
references: Array<{ name: string; type: string; id: string }>;
}
export type PackSavedObject = SavedObject<PackSavedObjectAttributes>;
export interface SavedQuerySavedObjectAttributes {
export interface SavedQuerySavedObject {
id: string;
description: string | undefined;
query: string;
@ -55,8 +51,6 @@ export interface SavedQuerySavedObjectAttributes {
updated_by: string | undefined;
}
export type SavedQuerySavedObject = SavedObject<PackSavedObjectAttributes>;
export interface HTTPError extends Error {
statusCode: number;
}

View file

@ -20,7 +20,7 @@ import type { CreateLiveQueryRequestBodySchema } from '../../../common/schemas/r
import { convertSOQueriesToPack } from '../../routes/pack/utils';
import { ACTIONS_INDEX } from '../../../common/constants';
import { TELEMETRY_EBT_LIVE_QUERY_EVENT } from '../../lib/telemetry/constants';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
import { CustomHttpRequestError } from '../../common/error';
interface Metadata {
@ -63,10 +63,7 @@ export const createActionHandler = async (
let packSO;
if (params.pack_id) {
packSO = await savedObjectsClient.get<PackSavedObjectAttributes>(
packSavedObjectType,
params.pack_id
);
packSO = await savedObjectsClient.get<PackSavedObject>(packSavedObjectType, params.pack_id);
}
const osqueryAction = {

View file

@ -6,13 +6,9 @@
*/
import { filter, find, isEmpty, pick, isString } from 'lodash';
import type { SavedObjectsFindResponse } from '@kbn/core/server';
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import type {
PackSavedObjectAttributes,
SavedQuerySavedObjectAttributes,
} from '../../common/types';
import type { PackSavedObject, SavedQuerySavedObject } from '../../common/types';
/**
* Constructs the configs telemetry schema from a collection of config saved objects
@ -28,21 +24,18 @@ export const templateConfigs = (configsData: PackagePolicy[]) =>
/**
* Constructs the packs telemetry schema from a collection of packs saved objects
*/
export const templatePacks = (
packsData: SavedObjectsFindResponse<PackSavedObjectAttributes>['saved_objects']
) => {
const nonEmptyQueryPacks = filter(packsData, (pack) => !isEmpty(pack.attributes.queries));
export const templatePacks = (packsData: PackSavedObject[]) => {
const nonEmptyQueryPacks = filter(packsData, (pack) => !isEmpty(pack.queries));
return nonEmptyQueryPacks.map((item) =>
pick(
{
name: item.attributes.name,
enabled: item.attributes.enabled,
queries: item.attributes.queries,
name: item.name,
enabled: item.enabled,
queries: item.queries,
policies: (filter(item.references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), 'id')?.length,
prebuilt:
!!filter(item.references, ['type', 'osquery-pack-asset']) &&
item.attributes.version !== undefined,
!!filter(item.references, ['type', 'osquery-pack-asset']) && item.version !== undefined,
},
['name', 'queries', 'policies', 'prebuilt', 'enabled']
)
@ -53,18 +46,16 @@ export const templatePacks = (
* Constructs the packs telemetry schema from a collection of packs saved objects
*/
export const templateSavedQueries = (
savedQueriesData: SavedObjectsFindResponse<SavedQuerySavedObjectAttributes>['saved_objects'],
savedQueriesData: SavedQuerySavedObject[],
prebuiltSavedQueryIds: string[]
) =>
savedQueriesData.map((item) => ({
id: item.attributes.id,
query: item.attributes.query,
platform: item.attributes.platform,
interval: isString(item.attributes.interval)
? parseInt(item.attributes.interval, 10)
: item.attributes.interval,
...(!isEmpty(item.attributes.snapshot) ? { snapshot: item.attributes.snapshot } : {}),
...(!isEmpty(item.attributes.removed) ? { snapshot: item.attributes.removed } : {}),
...(!isEmpty(item.attributes.ecs_mapping) ? { ecs_mapping: item.attributes.ecs_mapping } : {}),
id: item.id,
query: item.query,
platform: item.platform,
interval: isString(item.interval) ? parseInt(item.interval, 10) : item.interval,
...(!isEmpty(item.snapshot) ? { snapshot: item.snapshot } : {}),
...(!isEmpty(item.removed) ? { snapshot: item.removed } : {}),
...(!isEmpty(item.ecs_mapping) ? { ecs_mapping: item.ecs_mapping } : {}),
prebuilt: prebuiltSavedQueryIds.includes(item.id),
}));

View file

@ -22,10 +22,7 @@ import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import { OSQUERY_INTEGRATION_NAME } from '../../../common';
import { packSavedObjectType, savedQuerySavedObjectType } from '../../../common/types';
import type { OsqueryAppContextService } from '../osquery_app_context_services';
import type {
PackSavedObjectAttributes,
SavedQuerySavedObjectAttributes,
} from '../../common/types';
import type { PackSavedObject, SavedQuerySavedObject } from '../../common/types';
import { getPrebuiltSavedQueryIds } from '../../routes/saved_query/utils';
export class TelemetryReceiver {
@ -54,23 +51,39 @@ export class TelemetryReceiver {
}
public async fetchPacks() {
return this.soClient?.find<PackSavedObjectAttributes>({
type: packSavedObjectType,
page: 1,
perPage: this.max_records,
sortField: 'updated_at',
sortOrder: 'desc',
});
return this.soClient
?.find<PackSavedObject>({
type: packSavedObjectType,
page: 1,
perPage: this.max_records,
sortField: 'updated_at',
sortOrder: 'desc',
})
.then((data) => ({
...data,
saved_objects: data.saved_objects.map((pack) => ({
...pack.attributes,
saved_object_id: pack.id,
})),
}));
}
public async fetchSavedQueries() {
return this.soClient?.find<SavedQuerySavedObjectAttributes>({
type: savedQuerySavedObjectType,
page: 1,
perPage: this.max_records,
sortField: 'updated_at',
sortOrder: 'desc',
});
return this.soClient
?.find<SavedQuerySavedObject>({
type: savedQuerySavedObjectType,
page: 1,
perPage: this.max_records,
sortField: 'updated_at',
sortOrder: 'desc',
})
.then((data) => ({
...data,
saved_objects: data.saved_objects.map((savedQuery) => ({
...savedQuery.attributes,
saved_object_id: savedQuery.id,
})),
}));
}
public async fetchConfigs() {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import type { SavedObjectsClient, SavedObjectsFindResponse } from '@kbn/core/server';
import type { SavedObjectsClient } from '@kbn/core/server';
import { set } from '@kbn/safer-lodash-set';
import { has, map, mapKeys } from 'lodash';
import type { NewPackagePolicy } from '@kbn/fleet-plugin/common';
@ -14,14 +14,13 @@ import produce from 'immer';
import { convertShardsToObject } from '../routes/utils';
import { packSavedObjectType } from '../../common/types';
import type { OsqueryAppContextService } from './osquery_app_context_services';
import type { PackSavedObjectAttributes } from '../common/types';
import { convertSOQueriesToPackConfig } from '../routes/pack/utils';
import type { PackSavedObject } from '../common/types';
import { convertSOQueriesToPackConfig } from '../routes/pack/utils';
export const updateGlobalPacksCreateCallback = async (
packagePolicy: NewPackagePolicy,
packsClient: SavedObjectsClient,
allPacks: SavedObjectsFindResponse<PackSavedObjectAttributes>,
allPacks: PackSavedObject[],
osqueryContext: OsqueryAppContextService
) => {
const agentPolicyService = osqueryContext.getAgentPolicyService();
@ -35,8 +34,8 @@ export const updateGlobalPacksCreateCallback = async (
: {};
const packsContainingShardForPolicy: PackSavedObject[] = [];
allPacks.saved_objects.map((pack) => {
const shards = convertShardsToObject(pack.attributes.shards);
allPacks.map((pack) => {
const shards = convertShardsToObject(pack.shards);
return map(shards, (shard, shardName) => {
if (shardName === '*') {
@ -50,11 +49,11 @@ export const updateGlobalPacksCreateCallback = async (
map(packsContainingShardForPolicy, (pack) => {
packsClient.update(
packSavedObjectType,
pack.id,
pack.saved_object_id,
{},
{
references: [
...pack.references,
...(pack.references ?? []),
{
id: packagePolicy.policy_id,
name: agentPolicies[packagePolicy.policy_id]?.name,
@ -72,9 +71,9 @@ export const updateGlobalPacksCreateCallback = async (
}
map(packsContainingShardForPolicy, (pack) => {
set(draft, `inputs[0].config.osquery.value.packs.${pack.attributes.name}`, {
set(draft, `inputs[0].config.osquery.value.packs.${pack.name}`, {
shard: 100,
queries: convertSOQueriesToPackConfig(pack.attributes.queries),
queries: convertSOQueriesToPackConfig(pack.queries),
});
});

View file

@ -19,7 +19,7 @@ import type { NewPackagePolicy, UpdatePackagePolicy } from '@kbn/fleet-plugin/co
import type { Subscription } from 'rxjs';
import { upgradeIntegration } from './utils/upgrade_integration';
import type { PackSavedObjectAttributes } from './common/types';
import type { PackSavedObject } from './common/types';
import { updateGlobalPacksCreateCallback } from './lib/update_global_packs';
import { packSavedObjectType } from '../common/types';
import { createConfig } from './create_config';
@ -146,15 +146,23 @@ export class OsqueryPlugin implements Plugin<OsqueryPluginSetup, OsqueryPluginSt
if (newPackagePolicy.package?.name === OSQUERY_INTEGRATION_NAME) {
await this.initialize(core, dataViewsService);
const allPacks = await client.find<PackSavedObjectAttributes>({
type: packSavedObjectType,
});
const allPacks = await client
.find<PackSavedObject>({
type: packSavedObjectType,
})
.then((data) => ({
...data,
saved_objects: data.saved_objects.map((pack) => ({
...pack.attributes,
saved_object_id: pack.id,
})),
}));
if (allPacks.saved_objects) {
return updateGlobalPacksCreateCallback(
newPackagePolicy,
client,
allPacks,
allPacks.saved_objects,
this.osqueryAppContextService
);
}

View file

@ -18,7 +18,7 @@ import { combineMerge } from './utils';
import { PLUGIN_ID, OSQUERY_INTEGRATION_NAME } from '../../../common';
import type { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { convertSOQueriesToPack, convertPackQueriesToSO } from '../pack/utils';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.post(
@ -92,7 +92,7 @@ export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppCon
await Promise.all([
...install.map(async (installationPackAsset) => {
const packAssetSavedObject = await savedObjectsClient.get<PackSavedObjectAttributes>(
const packAssetSavedObject = await savedObjectsClient.get<PackSavedObject>(
installationPackAsset.type,
installationPackAsset.id
);
@ -138,19 +138,18 @@ export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppCon
);
}),
...update.map(async (updatePackAsset) => {
const packAssetSavedObject = await savedObjectsClient.get<PackSavedObjectAttributes>(
const packAssetSavedObject = await savedObjectsClient.get<PackSavedObject>(
updatePackAsset.type,
updatePackAsset.id
);
const packSavedObjectsResponse =
await savedObjectsClient.find<PackSavedObjectAttributes>({
type: 'osquery-pack',
hasReference: {
type: updatePackAsset.type,
id: updatePackAsset.id,
},
});
const packSavedObjectsResponse = await savedObjectsClient.find<PackSavedObject>({
type: 'osquery-pack',
hasReference: {
type: updatePackAsset.type,
id: updatePackAsset.id,
},
});
if (packSavedObjectsResponse.total) {
await savedObjectsClient.update(

View file

@ -27,7 +27,9 @@ import {
getInitialPolicies,
} from './utils';
import { convertShardsToArray, getInternalSavedObjectsClient } from '../utils';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
type PackSavedObjectLimited = Omit<PackSavedObject, 'saved_object_id' | 'references'>;
export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.post(
@ -121,7 +123,7 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
type: AGENT_POLICY_SAVED_OBJECT_TYPE,
}));
const packSO = await savedObjectsClient.create<PackSavedObjectAttributes>(
const packSO = await savedObjectsClient.create<PackSavedObjectLimited>(
packSavedObjectType,
{
name,
@ -174,7 +176,7 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
return response.ok({
body: {
data: packSO,
data: { ...packSO.attributes, saved_object_id: packSO.id },
},
});
}

View file

@ -12,7 +12,7 @@ import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import type { IRouter } from '@kbn/core/server';
import { packSavedObjectType } from '../../../common/types';
import { PLUGIN_ID } from '../../../common';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
export const findPackRoute = (router: IRouter) => {
router.get(
@ -35,7 +35,7 @@ export const findPackRoute = (router: IRouter) => {
const coreContext = await context.core;
const savedObjectsClient = coreContext.savedObjects.client;
const soClientResponse = await savedObjectsClient.find<PackSavedObjectAttributes>({
const soClientResponse = await savedObjectsClient.find<PackSavedObject>({
type: packSavedObjectType,
page: request.query.page ?? 1,
perPage: request.query.pageSize ?? 20,
@ -50,7 +50,8 @@ export const findPackRoute = (router: IRouter) => {
);
return {
...pack,
...pack.attributes,
saved_object_id: pack.id,
policy_ids: policyIds,
};
});

View file

@ -9,7 +9,7 @@ import { filter, map } from 'lodash';
import { schema } from '@kbn/config-schema';
import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common';
import type { IRouter } from '@kbn/core/server';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
import { PLUGIN_ID } from '../../../common';
import { packSavedObjectType } from '../../../common/types';
@ -31,11 +31,10 @@ export const readPackRoute = (router: IRouter) => {
const coreContext = await context.core;
const savedObjectsClient = coreContext.savedObjects.client;
const { attributes, references, ...rest } =
await savedObjectsClient.get<PackSavedObjectAttributes>(
packSavedObjectType,
request.params.id
);
const { attributes, references, id, ...rest } = await savedObjectsClient.get<PackSavedObject>(
packSavedObjectType,
request.params.id
);
const policyIds = map(filter(references, ['type', AGENT_POLICY_SAVED_OBJECT_TYPE]), 'id');
const osqueryPackAssetReference = !!filter(references, ['type', 'osquery-pack-asset']);
@ -45,6 +44,7 @@ export const readPackRoute = (router: IRouter) => {
data: {
...rest,
...attributes,
saved_object_id: id,
queries: convertSOQueriesToPack(attributes.queries),
shards: convertShardsToObject(attributes.shards),
policy_ids: policyIds,

View file

@ -30,7 +30,7 @@ import {
} from './utils';
import { convertShardsToArray, getInternalSavedObjectsClient } from '../utils';
import type { PackSavedObjectAttributes } from '../../common/types';
import type { PackSavedObject } from '../../common/types';
export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.put(
@ -100,7 +100,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
);
if (name) {
const conflictingEntries = await savedObjectsClient.find<PackSavedObjectAttributes>({
const conflictingEntries = await savedObjectsClient.find<PackSavedObject>({
type: packSavedObjectType,
filter: `${packSavedObjectType}.attributes.name: "${name}"`,
});
@ -159,7 +159,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
const references = getUpdatedReferences();
await savedObjectsClient.update<PackSavedObjectAttributes>(
await savedObjectsClient.update<PackSavedObject>(
packSavedObjectType,
request.params.id,
{
@ -349,7 +349,9 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
);
}
return response.ok({ body: { data: updatedPackSO } });
return response.ok({
body: { data: { ...updatedPackSO.attributes, saved_object_id: updatedPackSO.id } },
});
}
);
};

View file

@ -84,7 +84,8 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp
body: {
data: pickBy(
{
...savedQuerySO,
...savedQuerySO.attributes,
saved_object_id: savedQuerySO.id,
ecs_mapping,
},
(value) => !isEmpty(value)

View file

@ -61,7 +61,10 @@ export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppC
savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping);
}
return savedObject;
return {
...savedObject.attributes,
saved_object_id: savedObject.id,
};
});
return response.ok({

View file

@ -46,7 +46,7 @@ export const readSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppC
);
return response.ok({
body: { data: savedQuery },
body: { data: { ...savedQuery.attributes, saved_object_id: savedQuery.id } },
});
}
);

View file

@ -123,7 +123,9 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp
}
return response.ok({
body: { data: updatedSavedQuerySO },
body: {
data: { ...updatedSavedQuerySO.attributes, saved_object_id: updatedSavedQuerySO.id },
},
});
}
);

View file

@ -9,7 +9,6 @@ import * as t from 'io-ts';
import type { CreateRuleExceptionListItemSchemaDecoded } from '@kbn/securitysolution-io-ts-list-types';
import { createRuleExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import type { RequiredKeepUndefined } from '@kbn/osquery-plugin/common/types';
import { RuleObjectId } from '../../../rule_schema';
@ -39,7 +38,7 @@ export const CreateRuleExceptionsRequestBody = t.exact(
* This type is used after a decode since some things are defaults after a decode.
*/
export type CreateRuleExceptionsRequestBodyDecoded = Omit<
RequiredKeepUndefined<CreateRuleExceptionsRequestBody>,
CreateRuleExceptionsRequestBody,
'items'
> & {
items: CreateRuleExceptionListItemSchemaDecoded[];