mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 10:23:14 -04:00
* [Osquery] Fix ECS editor field array value (#132786)
(cherry picked from commit 272d9be670
)
* revert
This commit is contained in:
parent
8a40536c61
commit
0b6a03355b
14 changed files with 61 additions and 56 deletions
|
@ -79,7 +79,7 @@ describe('ALL - Add Integration', () => {
|
|||
it.skip('should have integration and packs copied when upgrading integration', () => {
|
||||
const packageName = 'osquery_manager';
|
||||
const oldVersion = '1.2.0';
|
||||
const newVersion = '1.3.0';
|
||||
const newVersion = '1.3.1';
|
||||
|
||||
cy.visit(`app/integrations/detail/${packageName}-${oldVersion}/overview`);
|
||||
cy.contains('Add Osquery Manager').click();
|
||||
|
|
|
@ -17,7 +17,6 @@ import {
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import deepMerge from 'deepmerge';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { pickBy, isEmpty, map } from 'lodash';
|
||||
|
@ -110,8 +109,12 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
options: {
|
||||
stripEmptyFields: false,
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
serializer: ({ savedQueryId, ecs_mapping, ...formData }) =>
|
||||
serializer: ({
|
||||
savedQueryId,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
ecs_mapping,
|
||||
...formData
|
||||
}) =>
|
||||
pickBy(
|
||||
{
|
||||
...formData,
|
||||
|
@ -120,20 +123,6 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
},
|
||||
(value) => !isEmpty(value)
|
||||
),
|
||||
defaultValue: deepMerge(
|
||||
{
|
||||
agentSelection: {
|
||||
agents: [],
|
||||
allAgentsSelected: false,
|
||||
platformsSelected: [],
|
||||
policiesSelected: [],
|
||||
},
|
||||
query: '',
|
||||
savedQueryId: null,
|
||||
ecs_mapping: [],
|
||||
},
|
||||
defaultValue ?? {}
|
||||
),
|
||||
});
|
||||
|
||||
const { updateFieldValues, setFieldValue, submit, isSubmitting } = form;
|
||||
|
@ -256,6 +245,7 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
/>
|
||||
</>
|
||||
)}
|
||||
<UseField path="savedQueryId" component={GhostFormField} />
|
||||
<UseField
|
||||
path="query"
|
||||
component={LiveQueryQueryField}
|
||||
|
@ -385,7 +375,6 @@ const LiveQueryFormComponent: React.FC<LiveQueryFormProps> = ({
|
|||
<EuiFlexItem>{queryFieldStepContent}</EuiFlexItem>
|
||||
<EuiFlexItem>{resultsStepContent}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<UseField path="savedQueryId" component={GhostFormField} />
|
||||
</Form>
|
||||
{showSavedQueryFlyout ? (
|
||||
<SavedQueryFlyout
|
||||
|
|
|
@ -28,6 +28,7 @@ export const liveQueryFormSchema = {
|
|||
validations: [],
|
||||
},
|
||||
query: {
|
||||
defaultValue: '',
|
||||
type: FIELD_TYPES.TEXT,
|
||||
validations: [
|
||||
{
|
||||
|
|
|
@ -143,7 +143,7 @@ const QueriesFieldComponent: React.FC<QueriesFieldProps> = ({
|
|||
pickBy(
|
||||
{
|
||||
id: newQueryId,
|
||||
interval: newQuery.interval ?? parsedContent.interval,
|
||||
interval: newQuery.interval ?? parsedContent.interval ?? '3600',
|
||||
query: newQuery.query,
|
||||
version: newQuery.version ?? parsedContent.version,
|
||||
platform: getSupportedPlatforms(newQuery.platform ?? parsedContent.platform),
|
||||
|
|
|
@ -398,7 +398,7 @@ const OsqueryColumnFieldComponent: React.FC<OsqueryColumnFieldProps> = ({
|
|||
return ecsKeySchemaOption?.value?.normalization !== 'array';
|
||||
}
|
||||
|
||||
return true;
|
||||
return !!ecsKey?.length;
|
||||
}, [typeValue, formData, item.path]);
|
||||
|
||||
const onTypeChange = useCallback(
|
||||
|
@ -637,6 +637,7 @@ export const ECSMappingEditorForm: React.FC<ECSMappingEditorFormProps> = ({
|
|||
osquerySchemaOptions,
|
||||
editForm: !isLastItem,
|
||||
},
|
||||
readDefaultValueOnForm: !item.isNew,
|
||||
config: {
|
||||
valueChangeDebounceTime: 300,
|
||||
type: FIELD_TYPES.COMBO_BOX,
|
||||
|
@ -702,6 +703,7 @@ export const ECSMappingEditorForm: React.FC<ECSMappingEditorFormProps> = ({
|
|||
component={ECSComboboxField}
|
||||
euiFieldProps={ecsComboBoxEuiFieldProps}
|
||||
validationData={validationData}
|
||||
readDefaultValueOnForm={!item.isNew}
|
||||
// @ts-expect-error update types
|
||||
config={config}
|
||||
/>
|
||||
|
@ -1017,7 +1019,9 @@ export const ECSMappingEditorField = React.memo(
|
|||
if (itemKey) {
|
||||
const serializedFormData = formDataSerializer();
|
||||
const itemValue =
|
||||
serializedFormData.ecs_mapping && serializedFormData.ecs_mapping[`${itemKey}`]?.field;
|
||||
serializedFormData.ecs_mapping &&
|
||||
(serializedFormData.ecs_mapping[`${itemKey}`]?.field ||
|
||||
serializedFormData.ecs_mapping[`${itemKey}`]?.value);
|
||||
|
||||
if (itemValue && onAdd.current) {
|
||||
onAdd.current();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { getPlatformIconModule } from './helpers';
|
||||
|
||||
export interface PlatformIconProps {
|
||||
|
@ -14,19 +14,9 @@ export interface PlatformIconProps {
|
|||
}
|
||||
|
||||
const PlatformIconComponent: React.FC<PlatformIconProps> = ({ platform }) => {
|
||||
const [Icon, setIcon] = useState<React.ReactElement | null>(null);
|
||||
const platformIconModule = useMemo(() => getPlatformIconModule(platform), [platform]);
|
||||
|
||||
// FIXME: This is a hack to force the icon to be loaded asynchronously.
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
const platformIconModule = getPlatformIconModule(platform);
|
||||
setIcon(<EuiIcon type={platformIconModule} title={platform} size="l" />);
|
||||
}, 0);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [platform, setIcon]);
|
||||
|
||||
return Icon;
|
||||
return <EuiIcon type={platformIconModule} title={platform} size="l" />;
|
||||
};
|
||||
|
||||
export const PlatformIcon = React.memo(PlatformIconComponent);
|
||||
|
|
|
@ -30,6 +30,7 @@ import { ALL_OSQUERY_VERSIONS_OPTIONS } from './constants';
|
|||
import { UsePackQueryFormProps, PackFormData, usePackQueryForm } from './use_pack_query_form';
|
||||
import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown';
|
||||
import { ECSMappingEditorField } from './lazy_ecs_mapping_editor_field';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
const CommonUseField = getUseField({ component: Field });
|
||||
|
||||
|
@ -46,6 +47,7 @@ const QueryFlyoutComponent: React.FC<QueryFlyoutProps> = ({
|
|||
onSave,
|
||||
onClose,
|
||||
}) => {
|
||||
const permissions = useKibana().services.application.capabilities.osquery;
|
||||
const [isEditMode] = useState(!!defaultValue);
|
||||
const { form } = usePackQueryForm({
|
||||
uniqueQueryIds,
|
||||
|
@ -117,7 +119,7 @@ const QueryFlyoutComponent: React.FC<QueryFlyoutProps> = ({
|
|||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<Form form={form}>
|
||||
{!isEditMode ? (
|
||||
{!isEditMode && permissions.readSavedQueries ? (
|
||||
<>
|
||||
<SavedQueriesDropdown onChange={handleSetQueryValue} />
|
||||
<EuiSpacer />
|
||||
|
|
|
@ -14,7 +14,7 @@ import { FIELD_TYPES } from '../../shared_imports';
|
|||
|
||||
import {
|
||||
createIdFieldValidations,
|
||||
intervalFieldValidation,
|
||||
intervalFieldValidations,
|
||||
queryFieldValidation,
|
||||
} from './validations';
|
||||
|
||||
|
@ -46,7 +46,7 @@ export const createFormSchema = (ids: Set<string>) => ({
|
|||
label: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldLabel', {
|
||||
defaultMessage: 'Interval (s)',
|
||||
}),
|
||||
validations: [{ validator: intervalFieldValidation }],
|
||||
validations: intervalFieldValidations,
|
||||
},
|
||||
platform: {
|
||||
type: FIELD_TYPES.TEXT,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { ValidationFunc, fieldValidators } from '../../shared_imports';
|
||||
import { ValidationConfig, ValidationFunc, fieldValidators } from '../../shared_imports';
|
||||
export { queryFieldValidation } from '../../common/validations';
|
||||
|
||||
const idPattern = /^[a-zA-Z0-9-_]+$/;
|
||||
|
@ -48,14 +48,30 @@ export const createIdFieldValidations = (ids: Set<string>) => [
|
|||
createUniqueIdValidation(ids),
|
||||
];
|
||||
|
||||
export const intervalFieldValidation: ValidationFunc<
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
any,
|
||||
string,
|
||||
number
|
||||
> = fieldValidators.numberGreaterThanField({
|
||||
than: 0,
|
||||
message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.invalidIntervalField', {
|
||||
defaultMessage: 'A positive interval value is required',
|
||||
}),
|
||||
});
|
||||
export const intervalFieldValidations: Array<
|
||||
ValidationConfig<
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
any,
|
||||
string,
|
||||
number
|
||||
>
|
||||
> = [
|
||||
{
|
||||
validator: fieldValidators.numberGreaterThanField({
|
||||
than: 0,
|
||||
message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError', {
|
||||
defaultMessage: 'A positive interval value is required',
|
||||
}),
|
||||
}),
|
||||
},
|
||||
{
|
||||
validator: fieldValidators.numberSmallerThanField({
|
||||
than: 604800,
|
||||
message: ({ than }) =>
|
||||
i18n.translate('xpack.osquery.pack.queryFlyoutForm.intervalFieldMaxNumberError', {
|
||||
defaultMessage: 'An interval value must be lower than {than}',
|
||||
values: { than },
|
||||
}),
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -12,6 +12,7 @@ export type {
|
|||
FormData,
|
||||
FormHook,
|
||||
FormSchema,
|
||||
ValidationConfig,
|
||||
ValidationError,
|
||||
ValidationFunc,
|
||||
ValidationFuncArg,
|
||||
|
|
|
@ -19,14 +19,16 @@ const getInstallation = async (osqueryContext: OsqueryAppContext) =>
|
|||
|
||||
export const getInstalledSavedQueriesMap = async (osqueryContext: OsqueryAppContext) => {
|
||||
const installation = await getInstallation(osqueryContext);
|
||||
|
||||
if (installation) {
|
||||
return reduce(
|
||||
return reduce<KibanaAssetReference, Record<string, KibanaAssetReference>>(
|
||||
installation.installed_kibana,
|
||||
// @ts-expect-error not sure why it shouts, but still it's properly typed
|
||||
(acc: Record<string, KibanaAssetReference>, item: KibanaAssetReference) => {
|
||||
(acc, item) => {
|
||||
if (item.type === savedQuerySavedObjectType) {
|
||||
return { ...acc, [item.id]: item };
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
|
|
@ -21923,7 +21923,7 @@
|
|||
"xpack.osquery.pack.queryFlyoutForm.idFieldLabel": "ID",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldLabel": "Intervalle (s)",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIdError": "Les caractères doivent être alphanumériques, _ ou -",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIntervalField": "Une valeur d'intervalle positive est requise",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError": "Une valeur d'intervalle positive est requise",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingEcsFieldLabel": "Champ ECS",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingValueFieldLabel": "Valeur",
|
||||
"xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage": "Valeur obligatoire.",
|
||||
|
|
|
@ -22061,7 +22061,7 @@
|
|||
"xpack.osquery.pack.queryFlyoutForm.idFieldLabel": "ID",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldLabel": "間隔",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIdError": "文字は英数字、_、または-でなければなりません",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIntervalField": "正の間隔値が必要です",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError": "正の間隔値が必要です",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingEcsFieldLabel": "ECSフィールド",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingValueFieldLabel": "値",
|
||||
"xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage": "値が必要です。",
|
||||
|
|
|
@ -22092,7 +22092,7 @@
|
|||
"xpack.osquery.pack.queryFlyoutForm.idFieldLabel": "ID",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldLabel": "时间间隔 (s)",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIdError": "字符必须是数字字母、_ 或 -",
|
||||
"xpack.osquery.pack.queryFlyoutForm.invalidIntervalField": "时间间隔值必须为正数",
|
||||
"xpack.osquery.pack.queryFlyoutForm.intervalFieldMinNumberError": "时间间隔值必须为正数",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingEcsFieldLabel": "ECS 字段",
|
||||
"xpack.osquery.pack.queryFlyoutForm.mappingValueFieldLabel": "值",
|
||||
"xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage": "“值”必填。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue