[Osquery] Update eslint config (#129637)

This commit is contained in:
Patryk Kopyciński 2022-04-19 11:09:32 +02:00 committed by GitHub
parent a843db30f1
commit e8f59a5888
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
82 changed files with 189 additions and 0 deletions

View file

@ -1452,6 +1452,20 @@ module.exports = {
plugins: ['react', '@typescript-eslint'],
files: ['x-pack/plugins/osquery/**/*.{js,mjs,ts,tsx}'],
rules: {
'padding-line-between-statements': [
'error',
{
blankLine: 'always',
prev: ['block-like'],
next: ['*'],
},
{
blankLine: 'always',
prev: ['*'],
next: ['return'],
},
],
'padded-blocks': ['error', 'always'],
'arrow-body-style': ['error', 'as-needed'],
'prefer-arrow-callback': 'error',
'no-unused-vars': 'off',

View file

@ -11,5 +11,6 @@ export const extendMap = (
): Readonly<Record<string, string>> =>
Object.entries(map).reduce<Record<string, string>>((accum, [key, value]) => {
accum[`${path}.${key}`] = `${path}.${value}`;
return accum;
}, {});

View file

@ -25,6 +25,7 @@
module.exports = (on: any, config: any) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-extraneous-dependencies
require('@cypress/code-coverage/task')(on, config);
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
return config;

View file

@ -64,6 +64,7 @@ export const getUrlWithRoute = (role: ROLES, route: string) => {
port: kibana.port,
} as UrlObject)}${route.startsWith('/') ? '' : '/'}${route}`;
cy.log(`origin: ${theUrl}`);
return theUrl;
};
@ -92,6 +93,7 @@ export const constructUrlWithUser = (user: User, route: string) => {
const builtUrl = new URL(strUrl);
cy.log(`origin: ${builtUrl.href}`);
return builtUrl.href;
};

View file

@ -27,15 +27,18 @@ export const AgentStatusBar: React.FC<{
}> = ({ agentStatus }) => {
const palette = useMemo(() => {
let stop = 0;
return AGENT_STATUSES.reduce((acc, status) => {
stop += agentStatus[status] || 0;
acc.push({
stop,
color: getColorForAgentStatus(status),
});
return acc;
}, [] as Array<{ stop: number; color: string }>);
}, [agentStatus]);
return (
<StyledEuiColorPaletteDisplay
className="osquery-action-agent-status-bar"

View file

@ -40,6 +40,7 @@ export function genAgent(policyId: string, hostname: string, id: string): Groupe
},
};
}
export const groupData: GroupData = {
[AGENT_GROUP_KEY.Platform]: new Array(3).fill('test platform ').map((el, i) => genGroup(el + i)),
[AGENT_GROUP_KEY.Policy]: new Array(3).fill('test policy ').map((el, i) => genGroup(el + i)),
@ -109,6 +110,7 @@ describe('AgentGrouper', () => {
});
};
}
it('should generate policy options', genGroupTest(AGENT_GROUP_KEY.Policy, 'policy'));
it('should generate platform options', genGroupTest(AGENT_GROUP_KEY.Platform, 'platform'));
});

View file

@ -78,12 +78,14 @@ export class AgentGrouper {
if (!data?.length || key === AGENT_GROUP_KEY.All) {
return;
}
const group = this.groups[key];
if (append) {
group.data.push(...data);
} else {
group.data = data;
}
group.size = data.length;
}
@ -91,6 +93,7 @@ export class AgentGrouper {
if (total < 0) {
return;
}
this.groups[AGENT_GROUP_KEY.All].size = total;
}
@ -124,6 +127,7 @@ export class AgentGrouper {
break;
}
}
return opts;
}
}

View file

@ -108,6 +108,7 @@ const AgentsTableComponent: React.FC<AgentsTableProps> = ({ agentSelection, onCh
getNumOverlapped(selectedGroups, groups.overlap)
);
}
onChange(newAgentSelection);
setSelectedOptions(selection);
},
@ -131,6 +132,7 @@ const AgentsTableComponent: React.FC<AgentsTableProps> = ({ agentSelection, onCh
}
}
};
if (agentSelection && !defaultValueInitialized.current && options.length) {
if (agentSelection.allAgentsSelected) {
const allAgentsOptions = find(['label', ALL_AGENTS_LABEL], options);
@ -175,6 +177,7 @@ const AgentsTableComponent: React.FC<AgentsTableProps> = ({ agentSelection, onCh
const renderOption = useCallback((option, searchVal, contentClassName) => {
const { label, value } = option;
return value?.groupType === AGENT_GROUP_KEY.Agent ? (
<EuiHealth color={value?.status === 'online' ? 'success' : 'danger'}>
<span className={contentClassName}>

View file

@ -30,8 +30,10 @@ export const getNumOverlapped = (
sum += policies[pol] ?? 0;
});
});
return sum;
};
interface Aggs extends estypes.AggregationsTermsAggregateBase {
buckets: AggregationDataPoint[];
}
@ -51,6 +53,7 @@ export const processAggregations = (aggs: Record<string, estypes.AggregationsAgg
if (platformPolicies?.buckets && policies.length > 0) {
overlap[key] = platformPolicies.buckets.reduce((acc: { [key: string]: number }, pol) => {
acc[pol.key] = pol.doc_count;
return acc;
}, {} as { [key: string]: number });
}
@ -63,13 +66,16 @@ export const processAggregations = (aggs: Record<string, estypes.AggregationsAgg
policies,
};
};
export const generateColorPicker = () => {
const visColorsBehindText = euiPaletteColorBlindBehindText();
const typeColors = new Map<AGENT_GROUP_KEY, string>();
return (type: AGENT_GROUP_KEY) => {
if (!typeColors.has(type)) {
typeColors.set(type, visColorsBehindText[typeColors.size]);
}
return typeColors.get(type);
};
};
@ -80,6 +86,7 @@ export const getNumAgentsInGrouping = (selectedGroups: SelectedGroups) => {
const group = selectedGroups[g];
sum += Object.keys(group).reduce((acc, k) => acc + group[k], 0);
});
return sum;
};
@ -90,6 +97,7 @@ export const generateAgentCheck =
.map((group) => {
const selectedGroup = selectedGroups[group];
const agentGroup = groups[group];
// check if the agent platform/policy is selected
return selectedGroup[agentGroup];
})
@ -124,6 +132,7 @@ export const generateAgentSelection = (selection: GroupOption[]) => {
// we don't need to calculate diffs when all agents are selected
selectedGroups.platform[key] = value.size;
}
newAgentSelection.platformsSelected.push(key);
break;
case AGENT_GROUP_KEY.Policy:
@ -132,6 +141,7 @@ export const generateAgentSelection = (selection: GroupOption[]) => {
// we don't need to calculate diffs when all agents are selected
selectedGroups.policy[key] = value.size;
}
newAgentSelection.policiesSelected.push(key);
break;
case AGENT_GROUP_KEY.Agent:
@ -140,6 +150,7 @@ export const generateAgentSelection = (selection: GroupOption[]) => {
// we don't need to count how many agents are selected if they are all selected
selectedAgents.push(value);
}
newAgentSelection.agents.push(key);
break;
default:
@ -148,5 +159,6 @@ export const generateAgentSelection = (selection: GroupOption[]) => {
console.error(`unknown group type ${groupType}`);
}
}
return { newAgentSelection, selectedGroups, selectedAgents };
};

View file

@ -21,6 +21,7 @@ interface UseAgentDetails {
export const useAgentDetails = ({ agentId, silent, skip }: UseAgentDetails) => {
const { http } = useKibana().services;
const setErrorToast = useErrorToast();
return useQuery<GetOneAgentResponse, unknown, GetOneAgentResponse['item']>(
['agentDetails', agentId],
() => http.get(`/internal/osquery/fleet_wrapper/agents/${agentId}`),

View file

@ -88,6 +88,7 @@ export const useAgentGroups = ({ osqueryPolicies, osqueryPoliciesLoading }: UseA
setPolicies(
newPolicies.map((p) => {
const name = agentPolicyById[p.id]?.name ?? p.name;
return {
...p,
name,

View file

@ -33,6 +33,7 @@ export const useOsqueryPolicies = () => {
}),
}
);
return useMemo(
() => ({ osqueryPoliciesLoading, osqueryPolicies }),
[osqueryPoliciesLoading, osqueryPolicies]

View file

@ -26,6 +26,7 @@ export const generateTablePaginationOptions = (
limit: number
): PaginationInputPaginated => {
const cursorStart = activePage * limit;
return {
activePage,
cursorStart,

View file

@ -163,6 +163,7 @@ export function useBreadcrumbs(page: Page, values: DynamicPagePathValues = {}) {
const href = breadcrumb.href
? http.basePath.prepend(`${BASE_PATH}${breadcrumb.href}`)
: undefined;
return {
...breadcrumb,
href,
@ -171,6 +172,7 @@ export function useBreadcrumbs(page: Page, values: DynamicPagePathValues = {}) {
if (ev.metaKey || ev.altKey || ev.ctrlKey || ev.shiftKey) {
return;
}
ev.preventDefault();
application.navigateToUrl(href);
}

View file

@ -43,6 +43,7 @@ export const useDiscoverLink = ({ filters }: UseDiscoverLink) => {
});
setDiscoverUrl(newUrl);
};
getDiscoverUrl();
}, [filters, locator]);

View file

@ -14,10 +14,12 @@ export const useErrorToast = () => {
const {
notifications: { toasts },
} = useKibana().services;
return (error?: unknown, opts?: ErrorToastOptions) => {
if (errorToast) {
toasts.remove(errorToast);
}
if (error) {
setErrorToast(
// @ts-expect-error update types

View file

@ -36,6 +36,7 @@ const useRouterNavigate = (
onClickCallback?: Parameters<typeof reactRouterNavigate>[2]
) => {
const history = useHistory();
return reactRouterNavigate(history, to, onClickCallback);
};

View file

@ -38,6 +38,7 @@ const OsqueryAppEmptyStateComponent = () => {
(event) => {
if (!isModifiedEvent(event) && isLeftClickEvent(event)) {
event.preventDefault();
return navigateToApp(INTEGRATIONS_PLUGIN_ID, {
path: pagePathGetters.integration_details_overview({
pkgkey: OSQUERY_INTEGRATION_NAME,

View file

@ -22,6 +22,7 @@ enum Section {
export const MainNavigation = () => {
const location = useLocation();
const section = useMemo(() => location.pathname.split('/')[1] ?? 'overview', [location.pathname]);
return (
<Nav>
<EuiFlexGroup gutterSize="l" alignItems="center">

View file

@ -33,6 +33,7 @@ const ManageIntegrationLinkComponent = () => {
(event) => {
if (!isModifiedEvent(event) && isLeftClickEvent(event)) {
event.preventDefault();
return navigateToApp(INTEGRATIONS_PLUGIN_ID, {
path: pagePathGetters.integration_details_policies({
pkgkey: OSQUERY_INTEGRATION_NAME,

View file

@ -40,6 +40,7 @@ const OsqueryEditorComponent: React.FC<OsqueryEditorProps> = ({
]);
useEffect(() => setEditorValue(defaultValue), [defaultValue]);
return (
<EuiCodeEditor
value={editorValue}

View file

@ -13,11 +13,14 @@ type TablesJSON = Array<{
export const normalizeTables = (tablesJSON: TablesJSON) => sortBy(tablesJSON, 'name');
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'));
}
return osqueryTables;
};
export const getOsqueryTableNames = () => flatMap(getOsqueryTables(), 'name');

View file

@ -48,6 +48,7 @@ const ConfigUploaderComponent: React.FC<ConfigUploaderProps> = ({ onChange }) =>
// remove any multiple spaces from the query
return value.replaceAll(/\s(?=\s)/gm, '');
}
return value;
});
@ -95,6 +96,7 @@ const ConfigUploaderComponent: React.FC<ConfigUploaderProps> = ({ onChange }) =>
);
// @ts-expect-error update types
filePickerRef.current?.removeFiles(new Event('fake'));
return;
}

View file

@ -13,6 +13,7 @@ export const LazyOsqueryManagedCustomButtonExtension = lazy<PackageCustomExtensi
const { OsqueryManagedCustomButtonExtension } = await import(
'./osquery_managed_custom_button_extension'
);
return {
default: OsqueryManagedCustomButtonExtension,
};

View file

@ -13,6 +13,7 @@ export const LazyOsqueryManagedPolicyCreateImportExtension =
const { OsqueryManagedPolicyCreateImportExtension } = await import(
'./osquery_managed_policy_create_import_extension'
);
return {
default: OsqueryManagedPolicyCreateImportExtension,
};

View file

@ -13,6 +13,7 @@ export const LazyOsqueryManagedPolicyEditExtension = lazy<PackagePolicyEditExten
const { OsqueryManagedPolicyCreateImportExtension } = await import(
'./osquery_managed_policy_create_import_extension'
);
return {
default: OsqueryManagedPolicyCreateImportExtension,
};

View file

@ -245,6 +245,7 @@ export const OsqueryManagedPolicyCreateImportExtension = React.memo<
} else {
set(draft, 'inputs[0].config.osquery.value', parsedConfig);
}
return draft;
});
@ -322,6 +323,7 @@ export const OsqueryManagedPolicyCreateImportExtension = React.memo<
policy_template: 'osquery_manager',
});
}
return draft;
});

View file

@ -29,6 +29,7 @@ export const useFetchStatus = () => {
}
});
};
fetchStatus();
}, [http]);

View file

@ -13,4 +13,5 @@ import { OsqueryPlugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new OsqueryPlugin(initializerContext);
}
export type { OsqueryPluginSetup, OsqueryPluginStart } from './types';

View file

@ -444,13 +444,16 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
if (defaultValue?.agentSelection) {
setFieldValue('agentSelection', defaultValue?.agentSelection);
}
if (defaultValue?.query) {
setFieldValue('query', defaultValue?.query);
}
// TODO: Set query and ECS mapping from savedQueryId object
if (defaultValue?.savedQueryId) {
setFieldValue('savedQueryId', defaultValue?.savedQueryId);
}
if (!isEmpty(defaultValue?.ecs_mapping)) {
setFieldValue('ecs_mapping', defaultValue?.ecs_mapping);
}

View file

@ -162,6 +162,7 @@ const PackFormComponent: React.FC<PackFormProps> = ({
policyIds,
(acc, policyId) => {
const agentPolicy = agentPoliciesById && agentPoliciesById[policyId];
return acc + (agentPolicy?.agents ?? 0);
},
0
@ -177,6 +178,7 @@ const PackFormComponent: React.FC<PackFormProps> = ({
const handleSaveClick = useCallback(() => {
if (agentCount) {
setShowConfirmationModal(true);
return;
}

View file

@ -47,10 +47,12 @@ const OsqueryPackUploaderComponent: React.FC<OsqueryPackUploaderProps> = ({ onCh
// remove any multiple spaces from the query
return value.replaceAll(/\s(?=\s)/gm, '');
}
if (key === 'interval') {
// convert interval int to string
return `${value}`;
}
return value;
});
@ -82,6 +84,7 @@ const OsqueryPackUploaderComponent: React.FC<OsqueryPackUploaderProps> = ({ onCh
(inputFiles) => {
if (!inputFiles.length) {
packName.current = '';
return;
}
@ -103,6 +106,7 @@ const OsqueryPackUploaderComponent: React.FC<OsqueryPackUploaderProps> = ({ onCh
);
// @ts-expect-error update types
filePickerRef.current?.removeFiles(new Event('fake'));
return;
}

View file

@ -106,6 +106,7 @@ const PolicyIdComboBoxFieldComponent: React.FC<PolicyIdComboBoxFieldProps> = ({
value,
(acc, policyId) => {
const agentPolicy = agentPoliciesById && agentPoliciesById[policyId];
return acc + (agentPolicy?.agents ?? 0);
},
0

View file

@ -113,6 +113,7 @@ const QueriesFieldComponent: React.FC<QueriesFieldProps> = ({
setValue(
produce((draft) => {
draft.push(newQuery);
return draft;
})
);

View file

@ -17,6 +17,7 @@ export const convertPackQueriesToSO = (queries) =>
id: key,
...pick(value, ['query', 'interval', 'platform', 'version', 'ecs_mapping']),
});
return acc;
},
[]
@ -28,6 +29,7 @@ export const convertSOQueriesToPack = (queries) =>
queries,
(acc, { id: queryId, ...query }) => {
acc[queryId] = query;
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View file

@ -234,6 +234,7 @@ const ViewResultsInLensActionComponent: React.FC<ViewResultsInDiscoverActionProp
if (!isLensAvailable) {
return null;
}
if (buttonType === ViewResultsActionButtonType.button) {
return (
<EuiButtonEmpty size="xs" iconType="lensApp" onClick={handleClick} disabled={false}>
@ -335,12 +336,14 @@ const ViewResultsInDiscoverActionComponent: React.FC<ViewResultsInDiscoverAction
});
setDiscoverUrl(newUrl);
};
getDiscoverUrl();
}, [actionId, agentIds, endDate, startDate, locator]);
if (!discoverPermissions.show) {
return null;
}
if (buttonType === ViewResultsActionButtonType.button) {
return (
<EuiButtonEmpty size="xs" iconType="discoverApp" href={discoverUrl} target="_blank">
@ -618,6 +621,7 @@ const PackQueriesStatusTableComponent: React.FC<PackQueriesStatusTableProps> = (
setLogsDataView(dataView[0]);
};
fetchLogsDataView();
}, [dataViews]);
@ -644,6 +648,7 @@ const PackQueriesStatusTableComponent: React.FC<PackQueriesStatusTableProps> = (
/>
);
}
setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues);
},
[agentIds, itemIdToExpandedRowMap, packName]

View file

@ -104,6 +104,7 @@ const PacksTableComponent = () => {
item.attributes.updated_by !== item.attributes.created_by
? ` @ ${item.attributes.updated_by}`
: '';
return updatedAt ? (
<EuiToolTip content={`${moment(updatedAt).fromNow()}${updatedBy}`}>
<UpdatedBy>{`${moment(updatedAt).fromNow()}${updatedBy}`}</UpdatedBy>

View file

@ -404,6 +404,7 @@ const OsqueryColumnFieldComponent: React.FC<OsqueryColumnFieldProps> = ({
} else {
setValue([trimmedNewOption]);
}
inputRef.current?.blur();
} else {
setValue(trimmedNewOption);
@ -675,9 +676,11 @@ export const ECSMappingEditorForm = forwardRef<ECSMappingEditorFormRef, ECSMappi
if (onAdd) {
onAdd(serializedData);
}
if (onChange) {
onChange(serializedData);
}
reset();
}
}, [validate, validateFields, submit, onAdd, onChange, reset]);
@ -840,6 +843,7 @@ export const ECSMappingEditorField = React.memo(
const validations = await Promise.all(
Object.values(formRefs.current).map(async (formRef) => {
const { data, isValid } = await formRef.validate();
return [data, isValid];
})
);
@ -945,6 +949,7 @@ export const ECSMappingEditorField = React.memo(
},
}))
);
return acc;
},
[] as OsquerySchemaOption[]
@ -961,6 +966,7 @@ export const ECSMappingEditorField = React.memo(
if (column === '*' && astOsqueryTables[table]) {
const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table];
return osqueryColumns.map((osqueryColumn) => ({
label: osqueryColumn.name,
value: {
@ -1050,6 +1056,7 @@ export const ECSMappingEditorField = React.memo(
setValue(
produce((draft) => {
draft[newRow.key] = newRow.value;
return draft;
})
);
@ -1085,6 +1092,7 @@ export const ECSMappingEditorField = React.memo(
if (draft[key]) {
delete draft[key];
}
return draft;
})
);

View file

@ -91,6 +91,7 @@ export const PlatformCheckBoxGroupField = ({
() =>
(options as EuiCheckboxGroupOption[]).reduce((acc, option) => {
acc[option.id] = isEmpty(field.value) ? true : field.value?.includes(option.id) ?? false;
return acc;
}, {} as Record<string, boolean>)
);
@ -116,6 +117,7 @@ export const PlatformCheckBoxGroupField = ({
setCheckboxIdToSelectedMap(() =>
(options as EuiCheckboxGroupOption[]).reduce((acc, option) => {
acc[option.id] = isEmpty(field.value) ? true : field.value?.includes(option.id) ?? false;
return acc;
}, {} as Record<string, boolean>)
);

View file

@ -43,12 +43,14 @@ export const getSupportedPlatforms = (payload: string) => {
acc.push(PlatformType.darwin);
acc.push(PlatformType.linux);
}
if (nextPlatform === 'ubuntu') {
acc.push(PlatformType.linux);
}
} else {
acc.push(nextPlatform);
}
return acc;
}, [] as string[])
).join(',');

View file

@ -27,6 +27,7 @@ const PlatformIconsComponent: React.FC<PlatformIconsProps> = ({ platform }) => {
} catch (e) {
return prevValue;
}
return platformArray;
} else {
return SUPPORTED_PLATFORMS;

View file

@ -65,6 +65,7 @@ const QueryFlyoutComponent: React.FC<QueryFlyoutProps> = ({
});
onClose();
}
resolve();
});
},

View file

@ -84,10 +84,12 @@ export const usePackQueryForm = ({
if (isArray(draft.platform)) {
draft.platform.join(',');
}
if (draft.platform?.split(',').length === 3) {
// if all platforms are checked then use undefined
delete draft.platform;
}
if (isArray(draft.version)) {
if (!draft.version.length) {
delete draft.version;
@ -95,9 +97,11 @@ export const usePackQueryForm = ({
draft.version = draft.version[0];
}
}
if (isEmpty(draft.ecs_mapping)) {
delete draft.ecs_mapping;
}
return draft;
}),
// @ts-expect-error update types

View file

@ -34,6 +34,7 @@ const createUniqueIdValidation = (ids: Set<string>) => {
};
}
};
return uniqueIdCheck;
};

View file

@ -43,6 +43,7 @@ export const useCreatePack = ({ withRedirect }: UseCreatePackProps) => {
if (withRedirect) {
navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() });
}
toasts.addSuccess(
i18n.translate('xpack.osquery.newPack.successToastMessageText', {
defaultMessage: 'Successfully created "{packName}" pack',

View file

@ -40,6 +40,7 @@ export const useDeletePack = ({ packId, withRedirect }: UseDeletePackProps) => {
if (withRedirect) {
navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() });
}
toasts.addSuccess(
i18n.translate('xpack.osquery.deletePack.successToastMessageText', {
defaultMessage: 'Successfully deleted pack',

View file

@ -70,6 +70,7 @@ export const usePackQueryErrors = ({
});
searchSource.setField('index', logsDataView);
return lastValueFrom(searchSource.fetch$());
},
{

View file

@ -46,6 +46,7 @@ export const useUpdatePack = ({ withRedirect, options }: UseUpdatePackProps) =>
if (withRedirect) {
navigateToApp(PLUGIN_ID, { path: pagePathGetters.packs() });
}
toasts.addSuccess(
i18n.translate('xpack.osquery.updatePack.successToastMessageText', {
defaultMessage: 'Successfully updated "{packName}" pack',

View file

@ -50,6 +50,7 @@ export class OsqueryPlugin implements Plugin<OsqueryPluginSetup, OsqueryPluginSt
const [coreStart, depsStart] = await core.getStartServices();
// Load application bundle
const { renderApp } = await import('./application');
// Render the application
return renderApp(
coreStart,

View file

@ -195,6 +195,7 @@ const ResultsTableComponent: React.FC<ResultsTableComponentProps> = ({
// @ts-expect-error update types
acc[value?.field] = [...(acc[value?.field] ?? []), key];
}
return acc;
},
{},
@ -274,6 +275,7 @@ const ResultsTableComponent: React.FC<ResultsTableComponentProps> = ({
});
seen.add(fieldName);
}
return acc;
}
@ -291,6 +293,7 @@ const ResultsTableComponent: React.FC<ResultsTableComponentProps> = ({
});
seen.add(displayAsText);
}
return acc;
}

View file

@ -141,6 +141,7 @@ const SavedQueriesPageComponent = () => {
item.attributes.updated_by !== item.attributes.created_by
? ` @ ${item.attributes.updated_by}`
: '';
return updatedAt ? `${moment(updatedAt).fromNow()}${updatedBy}` : '-';
}, []);

View file

@ -73,6 +73,7 @@ const SavedQueryFormComponent = forwardRef<SavedQueryFormRefObject, SavedQueryFo
if (ecsFieldRef.current) {
return ecsFieldRef.current.validate();
}
return Promise.resolve(false);
},
}),

View file

@ -38,12 +38,14 @@ export const useSavedQueryForm = ({
const res = new Set<string>(ids);
// @ts-expect-error update types
if (defaultValue && defaultValue.id) res.delete(defaultValue.id);
return res;
}, [ids, defaultValue]);
const formSchema = useMemo<ReturnType<typeof createFormSchema>>(
() => createFormSchema(idSet),
[idSet]
);
return useForm({
id: SAVED_QUERY_FORM_ID + uuid.v4(),
schema: formSchema,
@ -70,6 +72,7 @@ export const useSavedQueryForm = ({
// @ts-expect-error update types
delete draft.platform;
}
if (isArray(draft.version)) {
if (!draft.version.length) {
// @ts-expect-error update types
@ -78,12 +81,15 @@ export const useSavedQueryForm = ({
draft.version = draft.version[0];
}
}
if (isEmpty(draft.ecs_mapping)) {
// @ts-expect-error update types
delete draft.ecs_mapping;
}
// @ts-expect-error update types
draft.interval = draft.interval + '';
return draft;
}),
// @ts-expect-error update types

View file

@ -75,6 +75,7 @@ const SavedQueriesDropdownComponent: React.FC<SavedQueriesDropdownProps> = ({
if (!newSelectedOptions.length) {
onChange(null);
setSelectedOptions(newSelectedOptions);
return;
}

View file

@ -45,6 +45,7 @@ export const useCreateSavedQuery = ({ withRedirect }: UseCreateSavedQueryProps)
if (withRedirect) {
navigateToApp(PLUGIN_ID, { path: pagePathGetters.saved_queries() });
}
toasts.addSuccess(
i18n.translate('xpack.osquery.newSavedQuery.successToastMessageText', {
defaultMessage: 'Successfully saved "{savedQueryId}" query',

View file

@ -11,6 +11,7 @@ import React, { lazy, Suspense } from 'react';
// eslint-disable-next-line react/display-name
export const getLazyOsqueryAction = (services) => (props) => {
const OsqueryAction = lazy(() => import('./osquery_action'));
return (
<Suspense fallback={null}>
<OsqueryAction services={services} {...props} />

View file

@ -39,6 +39,7 @@ export const useIsOsqueryAvailable = (agentId?: string) => {
'package.name',
OSQUERY_INTEGRATION_NAME,
]);
return osqueryPackageInstalled?.enabled;
}, [agentPolicyData?.package_policies, policyError]);

View file

@ -30,6 +30,7 @@ const aggregateResults = async (
const { results: additionalResults } = await generator(currPage++, PER_PAGE);
results.push(...additionalResults);
}
return uniq<string>(results);
};
@ -52,6 +53,7 @@ export const parseAgentSelection = async (
perPage,
page,
});
return { results: items.map((it) => it.policy_id), total };
});
kueryFragments.push(`policy_id:(${uniq(osqueryPolicies).join(' or ')})`);
@ -64,6 +66,7 @@ export const parseAgentSelection = async (
kuery,
showInactive: false,
});
return { results: res.agents.map((agent) => agent.id), total: res.total };
});
fetchedAgents.forEach(addAgent);
@ -73,9 +76,11 @@ export const parseAgentSelection = async (
if (platformsSelected.length) {
groupFragments.push(`local_metadata.os.platform:(${platformsSelected.join(' or ')})`);
}
if (policiesSelected.length) {
groupFragments.push(`policy_id:(${policiesSelected.join(' or ')})`);
}
kueryFragments.push(`(${groupFragments.join(' or ')})`);
const kuery = kueryFragments.join(' and ');
const fetchedAgents = await aggregateResults(async (page, perPage) => {
@ -85,6 +90,7 @@ export const parseAgentSelection = async (
kuery,
showInactive: false,
});
return { results: res.agents.map((agent) => agent.id), total: res.total };
});
fetchedAgents.forEach(addAgent);

View file

@ -49,18 +49,21 @@ export function copyAllowlistedFields(
return { ...newEvent, [allowKey]: eventValue };
} else if (typeof allowValue === 'object' && Array.isArray(eventValue)) {
const subValues = eventValue.filter((v) => typeof v === 'object');
return {
...newEvent,
[allowKey]: subValues.map((v) => copyAllowlistedFields(allowValue, v as TelemetryEvent)),
};
} else if (typeof allowValue === 'object' && typeof eventValue === 'object') {
const values = copyAllowlistedFields(allowValue, eventValue as TelemetryEvent);
return {
...newEvent,
...(Object.keys(values).length > 0 ? { [allowKey]: values } : {}),
};
}
}
return newEvent;
}, {});
}

View file

@ -111,6 +111,7 @@ export class TelemetryReceiver {
return (await ret).license;
} catch (err) {
this.logger.debug(`failed retrieving license: ${err}`);
return undefined;
}
}

View file

@ -59,6 +59,7 @@ export class TelemetryEventsSender {
(config: OsqueryTelemetryTaskConfig) => {
const task = new OsqueryTelemetryTask(config, this.logger, this, telemetryReceiver);
task.register(taskManager);
return task;
}
);
@ -128,6 +129,7 @@ export class TelemetryEventsSender {
public async isTelemetryOptedIn() {
this.isOptedIn = await this.telemetryStart?.getIsOptedIn();
return this.isOptedIn === true;
}
@ -148,6 +150,7 @@ export class TelemetryEventsSender {
this.logger.debug(`Telemetry is not opted-in.`);
this.queue = [];
this.isSending = false;
return;
}
@ -183,6 +186,7 @@ export class TelemetryEventsSender {
} catch (err) {
this.queue = [];
}
this.isSending = false;
}
@ -229,6 +233,7 @@ export class TelemetryEventsSender {
if (!telemetryUrl) {
throw Error("Couldn't get telemetry URL");
}
return this.getV3UrlFromV2(telemetryUrl.toString(), channel);
}
@ -242,6 +247,7 @@ export class TelemetryEventsSender {
} else {
url.pathname = `/v3-dev/send/${channel}`;
}
return url.toString();
}

View file

@ -131,16 +131,19 @@ export class OsqueryTelemetryTask {
this.logger.debug(`[task ${taskId}]: attempting to run`);
if (taskId !== this.getTaskId()) {
this.logger.debug(`[task ${taskId}]: outdated task`);
return 0;
}
const isOptedIn = await this.sender.isTelemetryOptedIn();
if (!isOptedIn) {
this.logger.debug(`[task ${taskId}]: telemetry is not opted-in`);
return 0;
}
this.logger.debug(`[task ${taskId}]: running task`);
return this.config.runTask(taskId, this.logger, this.receiver, this.sender, executionPeriod);
};
}

View file

@ -43,6 +43,7 @@ export function createTelemetryPacksTaskConfig() {
if (!packsResponse?.total) {
logger.debug('no packs found');
return 0;
}

View file

@ -43,6 +43,7 @@ export function createTelemetrySavedQueriesTaskConfig() {
if (!savedQueriesResponse?.total) {
logger.debug('no saved queries found');
return 0;
}

View file

@ -75,6 +75,7 @@ export const createActionRoute = (router: IRouter, osqueryContext: OsqueryAppCon
incrementCount(internalSavedObjectsClient, 'live_query');
if (!selectedAgents.length) {
incrementCount(internalSavedObjectsClient, 'live_query', 'errors');
return response.badRequest({ body: new Error('No agents found for selection') });
}
@ -111,6 +112,7 @@ export const createActionRoute = (router: IRouter, osqueryContext: OsqueryAppCon
});
} catch (error) {
incrementCount(internalSavedObjectsClient, 'live_query', 'errors');
return response.customError({
statusCode: 500,
body: new Error(`Error occurred while processing ${error}`),

View file

@ -22,5 +22,6 @@ export const combineMerge = (target, source, options) => {
destination.push(item);
}
});
return destination;
};

View file

@ -135,9 +135,11 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
if (!has(draft, 'inputs[0].streams')) {
set(draft, 'inputs[0].streams', []);
}
set(draft, `inputs[0].config.osquery.value.packs.${packSO.attributes.name}`, {
queries,
});
return draft;
})
);

View file

@ -62,6 +62,7 @@ export const deletePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
draft,
`inputs[0].config.osquery.value.packs.${[currentPackSO.attributes.name]}`
);
return draft;
})
)

View file

@ -53,6 +53,7 @@ export const findPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext
// @ts-expect-error update types
pack.policy_ids = policyIds;
return pack;
});

View file

@ -192,6 +192,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
if (!has(draft, 'inputs[0].streams')) {
set(draft, 'inputs[0].streams', []);
}
set(
draft,
`inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`,
@ -199,6 +200,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
queries: updatedPackSO.attributes.queries,
}
);
return draft;
})
);
@ -221,6 +223,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
draft,
`inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}`
);
return draft;
})
);
@ -248,6 +251,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
draft,
`inputs[0].config.osquery.value.packs.${currentPackSO.attributes.name}`
);
return draft;
})
);
@ -280,6 +284,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
queries: updatedPackSO.attributes.queries,
}
);
return draft;
})
);
@ -301,6 +306,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
if (!(draft.inputs.length && draft.inputs[0].streams.length)) {
set(draft, 'inputs[0].streams', []);
}
set(
draft,
`inputs[0].config.osquery.value.packs.${updatedPackSO.attributes.name}`,
@ -308,6 +314,7 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte
queries: updatedPackSO.attributes.queries,
}
);
return draft;
})
);

View file

@ -19,6 +19,7 @@ export const convertPackQueriesToSO = (queries) =>
...pick(value, ['query', 'interval', 'platform', 'version']),
...(ecsMapping ? { ecs_mapping: ecsMapping } : {}),
});
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -35,6 +36,7 @@ export const convertSOQueriesToPack = (queries) =>
...query,
ecs_mapping: convertECSMappingToObject(ecs_mapping),
};
return acc;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View file

@ -78,6 +78,7 @@ export const createStatusRoute = (router: IRouter, osqueryContext: OsqueryAppCon
const { id: queryId, ...query } = stream.compiled_stream;
queries[queryId] = query;
}
return queries;
},
{} as Record<string, unknown>

View file

@ -82,6 +82,7 @@ describe('Usage metric recorder', () => {
count: 0,
errors: 0,
};
return acc;
}, {} as { [key: string]: CounterValue });
get.mockClear();

View file

@ -22,6 +22,7 @@ export const convertECSMappingToObject = (
ecsMapping,
(acc, value) => {
acc[value.key] = value.value;
return acc;
},
{} as Record<string, { field?: string; value?: string }>

View file

@ -21,6 +21,7 @@ export const allActions: OsqueryFactory<OsqueryQueries.actions> = {
if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) {
throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`);
}
return buildActionsQuery(options);
},
parse: async (

View file

@ -22,6 +22,7 @@ export const actionResults: OsqueryFactory<OsqueryQueries.actionResults> = {
if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) {
throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`);
}
return buildActionResultsQuery(options);
},
parse: async (

View file

@ -23,6 +23,7 @@ export const allAgents: OsqueryFactory<OsqueryQueries.agents> = {
if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) {
throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`);
}
return buildAgentsQuery(options);
},
parse: async (

View file

@ -21,6 +21,7 @@ export const allResults: OsqueryFactory<OsqueryQueries.results> = {
if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) {
throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`);
}
return buildResultsQuery(options);
},
parse: async (

View file

@ -26,6 +26,7 @@ export const osquerySearchStrategyProvider = <T extends FactoryQueryTypes>(
if (request.factoryQueryType == null) {
throw new Error('factoryQueryType is required');
}
const queryFactory: OsqueryFactory<T> = osqueryFactory[request.factoryQueryType];
const dsl = queryFactory.buildDsl(request);

View file

@ -15,6 +15,7 @@ export const getInternalSavedObjectsClient = async (
getStartServices: CoreSetup['getStartServices']
) => {
const [coreStart] = await getStartServices();
return new SavedObjectsClient(coreStart.savedObjects.createInternalRepository());
};
@ -22,6 +23,7 @@ export const registerCollector: RegisterCollector = ({ core, osqueryContext, usa
if (!usageCollection) {
return;
}
const collector = usageCollection.makeUsageCollector<UsageData>({
type: 'osquery',
schema: usageSchema,

View file

@ -36,6 +36,7 @@ export async function getPolicyLevelUsage(
if (!packagePolicyService) {
return {};
}
const packagePolicies = await packagePolicyService.list(soClient, {
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${OSQUERY_INTEGRATION_NAME}`,
perPage: 10_000,
@ -78,6 +79,7 @@ export async function getPolicyLevelUsage(
enrolled: policied.doc_count,
};
}
return result;
}
@ -86,6 +88,7 @@ export function getPackageVersions(packagePolicies: ListResult<PackagePolicy>) {
if (item.package) {
acc[item.package.version] = (acc[item.package.version] ?? 0) + 1;
}
return acc;
}, {} as { [version: string]: number });
}
@ -105,6 +108,7 @@ export function getScheduledQueryUsage(packagePolicies: ListResult<PackagePolicy
if (policyAgents === 0) {
++acc.queryGroups.empty;
}
return acc;
},
{
@ -206,6 +210,7 @@ export function extractBeatUsageMetrics(
}
}
}
return result;
}

View file

@ -45,14 +45,18 @@ const getProps = (
if (codec == null) {
return null;
}
switch (codec._tag) {
case 'DictionaryType': {
if (codec.codomain.props != null) {
return codec.codomain.props;
}
const dTypes: rt.HasProps[] = codec.codomain.types;
return dTypes.reduce<rt.Props>((props, type) => Object.assign(props, getProps(type)), {});
}
case 'RefinementType':
case 'ReadonlyType':
return getProps(codec.type);
@ -62,11 +66,13 @@ const getProps = (
return codec.props;
case 'IntersectionType': {
const iTypes = codec.types as rt.HasProps[];
return iTypes.reduce<rt.Props>(
(props, type) => Object.assign(props, getProps(type) as rt.Props),
{} as rt.Props
) as rt.Props;
}
default:
return null;
}
@ -84,6 +90,7 @@ const getExcessProps = (
const childrenObject = r[k] as Record<string, unknown>;
if (codecChildren != null && childrenProps != null && codecChildren._tag === 'DictionaryType') {
const keys = Object.keys(childrenObject);
return [
...acc,
...keys.reduce<string[]>(
@ -92,11 +99,13 @@ const getExcessProps = (
),
];
}
if (codecChildren != null && childrenProps != null) {
return [...acc, ...getExcessProps(childrenProps, childrenObject)];
} else if (codecChildren == null) {
return [...acc, k];
}
return acc;
}, []);
@ -115,6 +124,7 @@ export const excess = <
if (codecProps == null) {
return rt.failure(i, c, 'unknown codec');
}
const ex = getExcessProps(codecProps, s);
return ex.length > 0
@ -128,5 +138,6 @@ export const excess = <
codec.encode,
codecProps
);
return r as C;
};