From be9b46d911f8648203a4c1d5fe4ccea848020ef7 Mon Sep 17 00:00:00 2001
From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
Date: Tue, 14 May 2024 10:45:54 +0200
Subject: [PATCH] [Fleet] add validation to dataset field in input packages to
disallow special characters (#182925)
## Summary
Closes https://github.com/elastic/kibana/issues/181044
Added validation to allow only valid index names as dataset name in
input packages. Allowing lowercase letters, numbers, dot and underscore
(except in the beginning).
To verify:
- add Custom Logs integration
- modfiy dataset to add invalid characters e.g. *
- verify that the field shows a validation error
- verify that the save button is disabled
- verify that valid dataset names can be used
### Checklist
Delete any items that are not applicable to this PR.
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
---
x-pack/plugins/fleet/common/index.ts | 1 +
x-pack/plugins/fleet/common/services/index.ts | 6 +-
.../common/services/is_valid_namespace.ts | 52 +++++-
.../services/validate_package_policy.test.ts | 140 ++++++++++++++
.../services/validate_package_policy.ts | 24 ++-
.../steps/components/dataset_combo.tsx | 133 -------------
.../components/dataset_component.test.tsx | 71 +++++++
.../steps/components/dataset_component.tsx | 174 ++++++++++++++++++
.../package_policy_input_var_field.tsx | 38 ++--
.../translations/translations/fr-FR.json | 4 -
.../translations/translations/ja-JP.json | 4 -
.../translations/translations/zh-CN.json | 4 -
.../package_policy/input_package_rollback.ts | 7 +-
13 files changed, 477 insertions(+), 181 deletions(-)
delete mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_combo.tsx
create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.test.tsx
create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.tsx
diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts
index 0c729823f3391..fed73a5653313 100644
--- a/x-pack/plugins/fleet/common/index.ts
+++ b/x-pack/plugins/fleet/common/index.ts
@@ -73,6 +73,7 @@ export {
fleetSetupRouteService,
// Package policy helpers
isValidNamespace,
+ isValidDataset,
INVALID_NAMESPACE_CHARACTERS,
getFileMetadataIndexName,
getFileDataIndexName,
diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts
index 3d1fc77f2a373..db7cb41d5fea0 100644
--- a/x-pack/plugins/fleet/common/services/index.ts
+++ b/x-pack/plugins/fleet/common/services/index.ts
@@ -16,7 +16,11 @@ export {
} from './package_to_package_policy';
export { fullAgentPolicyToYaml } from './full_agent_policy_to_yaml';
export { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from './limited_package';
-export { isValidNamespace, INVALID_NAMESPACE_CHARACTERS } from './is_valid_namespace';
+export {
+ isValidDataset,
+ isValidNamespace,
+ INVALID_NAMESPACE_CHARACTERS,
+} from './is_valid_namespace';
export { isDiffPathProtocol } from './is_diff_path_protocol';
export { LicenseService } from './license';
export * from './is_agent_upgradeable';
diff --git a/x-pack/plugins/fleet/common/services/is_valid_namespace.ts b/x-pack/plugins/fleet/common/services/is_valid_namespace.ts
index 49332c4a88156..dcc1a2b9b5cbf 100644
--- a/x-pack/plugins/fleet/common/services/is_valid_namespace.ts
+++ b/x-pack/plugins/fleet/common/services/is_valid_namespace.ts
@@ -14,37 +14,71 @@ export function isValidNamespace(
namespace: string,
allowBlankNamespace?: boolean
): { valid: boolean; error?: string } {
- if (!namespace.trim() && !allowBlankNamespace) {
+ return isValidEntity(namespace, 'Namespace', allowBlankNamespace);
+}
+
+export function isValidDataset(
+ dataset: string,
+ allowBlank?: boolean
+): { valid: boolean; error?: string } {
+ const { valid, error } = isValidEntity(dataset, 'Dataset', allowBlank);
+ if (!valid) {
+ return { valid, error };
+ }
+ if (dataset.startsWith('_') || dataset.startsWith('.')) {
+ return {
+ valid: false,
+ error: i18n.translate(
+ 'xpack.fleet.datasetValidation.datasetStartsWithUnderscoreErrorMessage',
+ {
+ defaultMessage: 'Dataset cannot start with an underscore or dot',
+ }
+ ),
+ };
+ }
+ return { valid, error };
+}
+
+function isValidEntity(
+ name: string,
+ type: string,
+ allowBlank?: boolean
+): { valid: boolean; error?: string } {
+ if (!name.trim() && !allowBlank) {
return {
valid: false,
error: i18n.translate('xpack.fleet.namespaceValidation.requiredErrorMessage', {
- defaultMessage: 'Namespace is required',
+ defaultMessage: '{type} is required',
+ values: { type },
}),
};
- } else if (namespace !== namespace.toLowerCase()) {
+ } else if (name !== name.toLowerCase()) {
return {
valid: false,
error: i18n.translate('xpack.fleet.namespaceValidation.lowercaseErrorMessage', {
- defaultMessage: 'Namespace must be lowercase',
+ defaultMessage: '{type} must be lowercase',
+ values: { type },
}),
};
- } else if (INVALID_NAMESPACE_CHARACTERS.test(namespace)) {
+ } else if (INVALID_NAMESPACE_CHARACTERS.test(name)) {
return {
valid: false,
error: i18n.translate('xpack.fleet.namespaceValidation.invalidCharactersErrorMessage', {
- defaultMessage: 'Namespace contains invalid characters',
+ defaultMessage: '{type} contains invalid characters',
+ values: { type },
}),
};
}
// Node.js doesn't have Blob, and browser doesn't have Buffer :)
else if (
- (typeof Blob === 'function' && new Blob([namespace]).size > 100) ||
- (typeof Buffer === 'function' && Buffer.from(namespace).length > 100)
+ (typeof Blob === 'function' && new Blob([name]).size > 100) ||
+ (typeof Buffer === 'function' && Buffer.from(name).length > 100)
) {
return {
valid: false,
error: i18n.translate('xpack.fleet.namespaceValidation.tooLongErrorMessage', {
- defaultMessage: 'Namespace cannot be more than 100 bytes',
+ defaultMessage: '{type} cannot be more than 100 bytes',
+ values: { type },
}),
};
}
diff --git a/x-pack/plugins/fleet/common/services/validate_package_policy.test.ts b/x-pack/plugins/fleet/common/services/validate_package_policy.test.ts
index 7f5c6999bce9c..3f443838d485e 100644
--- a/x-pack/plugins/fleet/common/services/validate_package_policy.test.ts
+++ b/x-pack/plugins/fleet/common/services/validate_package_policy.test.ts
@@ -1079,4 +1079,144 @@ describe('Fleet - validatePackagePolicyConfig', () => {
expect(res).toEqual(['Secret reference is invalid, id must be a string']);
});
});
+
+ describe('Dataset', () => {
+ const datasetError = 'Dataset contains invalid characters';
+
+ const validateDataset = (dataset: string) => {
+ return validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: { dataset, package: 'log' },
+ },
+ {
+ name: 'data_stream.dataset',
+ type: 'text',
+ },
+ 'data_stream.dataset',
+ safeLoad,
+ 'input'
+ );
+ };
+
+ it('should return an error message if the value has *', () => {
+ const res = validateDataset('test*');
+
+ expect(res).toEqual([datasetError]);
+ });
+
+ it('should return an error message if the value has uppercase letter', () => {
+ const res = validateDataset('Test');
+
+ expect(res).toEqual(['Dataset must be lowercase']);
+ });
+
+ it('should return an error message if the value has _ in the beginning', () => {
+ const res = validateDataset('_test');
+
+ expect(res).toEqual(['Dataset cannot start with an underscore or dot']);
+ });
+
+ it('should return an error message if the value has . in the beginning', () => {
+ const res = validateDataset('.test');
+
+ expect(res).toEqual(['Dataset cannot start with an underscore or dot']);
+ });
+
+ it('should not return an error message if the value is valid', () => {
+ const res = validateDataset('fleet_server.test_dataset');
+
+ expect(res).toEqual(null);
+ });
+
+ it('should not return an error message if the value is undefined', () => {
+ const res = validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: undefined,
+ },
+ {
+ name: 'data_stream.dataset',
+ type: 'text',
+ },
+ 'data_stream.dataset',
+ safeLoad,
+ 'input'
+ );
+
+ expect(res).toEqual(null);
+ });
+
+ it('should not return an error message if the package is not input type', () => {
+ const res = validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: { dataset: 'Test', package: 'log' },
+ },
+ {
+ name: 'data_stream.dataset',
+ type: 'text',
+ },
+ 'data_stream.dataset',
+ safeLoad,
+ 'integration'
+ );
+
+ expect(res).toEqual(null);
+ });
+
+ it('should not return an error message if the var is not dataset', () => {
+ const res = validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: { dataset: 'Test', package: 'log' },
+ },
+ {
+ name: 'test_field',
+ type: 'text',
+ },
+ 'test_field',
+ safeLoad,
+ 'input'
+ );
+
+ expect(res).toEqual(null);
+ });
+
+ it('should return an error message if the string dataset value has special characters', () => {
+ const res = validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: 'test*',
+ },
+ {
+ name: 'data_stream.dataset',
+ type: 'text',
+ },
+ 'data_stream.dataset',
+ safeLoad,
+ 'input'
+ );
+
+ expect(res).toEqual(['Dataset contains invalid characters']);
+ });
+
+ it('should return an error message if the dataset value has special characters', () => {
+ const res = validatePackagePolicyConfig(
+ {
+ type: 'text',
+ value: { dataset: 'test*', package: 'log' },
+ },
+ {
+ name: 'data_stream.dataset',
+ type: 'text',
+ },
+ 'data_stream.dataset',
+ safeLoad,
+ 'input'
+ );
+
+ expect(res).toEqual(['Dataset contains invalid characters']);
+ });
+ });
});
diff --git a/x-pack/plugins/fleet/common/services/validate_package_policy.ts b/x-pack/plugins/fleet/common/services/validate_package_policy.ts
index 8cbaf56b546db..1de38822cbc80 100644
--- a/x-pack/plugins/fleet/common/services/validate_package_policy.ts
+++ b/x-pack/plugins/fleet/common/services/validate_package_policy.ts
@@ -19,6 +19,8 @@ import type {
RegistryVarsEntry,
} from '../types';
+import { DATASET_VAR_NAME } from '../constants';
+
import {
isValidNamespace,
doesPackageHaveIntegrations,
@@ -26,6 +28,7 @@ import {
getNormalizedDataStreams,
} from '.';
import { packageHasNoPolicyTemplates } from './policy_template';
+import { isValidDataset } from './is_valid_namespace';
type Errors = string[] | null;
@@ -173,7 +176,13 @@ export const validatePackagePolicy = (
results[name] =
input.enabled && stream.enabled
- ? validatePackagePolicyConfig(configEntry, streamVarDefs[name], name, safeLoadYaml)
+ ? validatePackagePolicyConfig(
+ configEntry,
+ streamVarDefs[name],
+ name,
+ safeLoadYaml,
+ packageInfo.type
+ )
: null;
return results;
@@ -202,7 +211,8 @@ export const validatePackagePolicyConfig = (
configEntry: PackagePolicyConfigRecordEntry | undefined,
varDef: RegistryVarsEntry,
varName: string,
- safeLoadYaml: (yaml: string) => any
+ safeLoadYaml: (yaml: string) => any,
+ packageType?: string
): string[] | null => {
const errors = [];
@@ -357,6 +367,16 @@ export const validatePackagePolicyConfig = (
}
}
+ if (varName === DATASET_VAR_NAME && packageType === 'input' && parsedValue !== undefined) {
+ const { valid, error } = isValidDataset(
+ parsedValue.dataset ? parsedValue.dataset : parsedValue,
+ false
+ );
+ if (!valid && error) {
+ errors.push(error);
+ }
+ }
+
return errors.length ? errors : null;
};
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_combo.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_combo.tsx
deleted file mode 100644
index 180060db52f1c..0000000000000
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_combo.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React, { useEffect, useState } from 'react';
-import { EuiComboBox, EuiIcon, EuiLink, EuiSpacer, EuiText, EuiToolTip } from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
-
-import { FormattedMessage } from '@kbn/i18n-react';
-
-import type { DataStream } from '../../../../../../../../../common/types';
-import { GENERIC_DATASET_NAME } from '../../../../../../../../../common/constants';
-
-interface SelectedDataset {
- dataset: string;
- package: string;
-}
-
-export const DatasetComboBox: React.FC<{
- value?: SelectedDataset | string;
- onChange: (newValue: SelectedDataset) => void;
- datastreams: DataStream[];
- pkgName?: string;
- isDisabled?: boolean;
-}> = ({ value, onChange, datastreams, isDisabled, pkgName = '' }) => {
- const datasetOptions =
- datastreams.map((datastream: DataStream) => ({
- label: datastream.dataset,
- value: datastream,
- })) ?? [];
- const existingGenericStream = datasetOptions.find((ds) => ds.label === GENERIC_DATASET_NAME);
- const valueAsOption = value
- ? typeof value === 'string'
- ? { label: value, value: { dataset: value, package: pkgName } }
- : { label: value.dataset, value: { dataset: value.dataset, package: value.package } }
- : undefined;
- const defaultOption = valueAsOption ||
- existingGenericStream || {
- label: GENERIC_DATASET_NAME,
- value: { dataset: GENERIC_DATASET_NAME, package: pkgName },
- };
-
- const [selectedOptions, setSelectedOptions] = useState>([defaultOption]);
-
- useEffect(() => {
- if (!value || typeof value === 'string') onChange(defaultOption.value as SelectedDataset);
- }, [value, defaultOption.value, onChange, pkgName]);
-
- const onDatasetChange = (newSelectedOptions: Array<{ label: string; value?: DataStream }>) => {
- setSelectedOptions(newSelectedOptions);
- const dataStream = newSelectedOptions[0].value;
- onChange({
- dataset: newSelectedOptions[0].label,
- package: !dataStream || typeof dataStream === 'string' ? pkgName : dataStream.package,
- });
- };
-
- const onCreateOption = (searchValue: string = '') => {
- const normalizedSearchValue = searchValue.trim().toLowerCase();
- if (!normalizedSearchValue) {
- return;
- }
- const newOption = {
- label: searchValue,
- value: { dataset: searchValue, package: pkgName },
- };
- setSelectedOptions([newOption]);
- onChange({
- dataset: searchValue,
- package: pkgName,
- });
- };
- return (
- <>
-
- {valueAsOption && valueAsOption.value.package !== pkgName && (
- <>
-
-
-
-
-
- }
- >
-
- {i18n.translate('xpack.fleet.datasetCombo.learnMoreLink', {
- defaultMessage: 'learn more',
- })}
-
-
- ),
- }}
- />
-
- >
- )}
- >
- );
-};
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.test.tsx
new file mode 100644
index 0000000000000..e45da365e74aa
--- /dev/null
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.test.tsx
@@ -0,0 +1,71 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { fireEvent } from '@testing-library/react';
+
+import { createFleetTestRendererMock } from '../../../../../../../../mock';
+
+import { DatasetComponent } from './dataset_component';
+
+describe('DatasetComponent', () => {
+ function render(value = 'generic', datastreams: any = []) {
+ const renderer = createFleetTestRendererMock();
+ const mockOnChange = jest.fn();
+ const fieldLabel = 'Dataset name';
+
+ const utils = renderer.render(
+
+ );
+
+ return { utils, mockOnChange };
+ }
+
+ it('should show validation error if dataset is invalid', () => {
+ const { utils } = render();
+
+ const inputEl = utils.getByTestId('comboBoxSearchInput');
+ fireEvent.change(inputEl, { target: { value: 'generic*' } });
+ fireEvent.keyDown(inputEl, { key: 'Enter', code: 'Enter' });
+
+ utils.getByText('Dataset contains invalid characters');
+ });
+
+ it('should not show validation error if dataset is valid', () => {
+ const { utils } = render();
+
+ const inputEl = utils.getByTestId('comboBoxSearchInput');
+ fireEvent.change(inputEl, { target: { value: 'test' } });
+ fireEvent.keyDown(inputEl, { key: 'Enter', code: 'Enter' });
+
+ expect(utils.queryByText('Dataset contains invalid characters')).toBeNull();
+ });
+
+ it('should not show validation error if valid dataset selected from select', () => {
+ const { utils, mockOnChange } = render(undefined, [
+ { dataset: 'fleet_server.test_ds', package: 'log' },
+ ]);
+
+ const inputEl = utils.getByTestId('comboBoxSearchInput');
+ fireEvent.click(inputEl);
+ const option = utils.getByText('fleet_server.test_ds');
+ fireEvent.click(option);
+
+ expect(utils.queryByText('Dataset contains invalid characters')).toBeNull();
+ expect(mockOnChange).toHaveBeenCalledWith({ dataset: 'fleet_server.test_ds', package: 'log' });
+ });
+});
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.tsx
new file mode 100644
index 0000000000000..bac9f76b5cf54
--- /dev/null
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/dataset_component.tsx
@@ -0,0 +1,174 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { useEffect, useState } from 'react';
+import {
+ EuiComboBox,
+ EuiFormRow,
+ EuiIcon,
+ EuiLink,
+ EuiSpacer,
+ EuiText,
+ EuiToolTip,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import styled from 'styled-components';
+import ReactMarkdown from 'react-markdown';
+
+import { FormattedMessage } from '@kbn/i18n-react';
+
+import type { DataStream } from '../../../../../../../../../common/types';
+import { GENERIC_DATASET_NAME } from '../../../../../../../../../common/constants';
+import { isValidDataset } from '../../../../../../../../../common';
+
+const FormRow = styled(EuiFormRow)`
+ .euiFormRow__label {
+ flex: 1;
+ }
+
+ .euiFormRow__fieldWrapper > .euiPanel {
+ padding: ${(props) => props.theme.eui?.euiSizeXS};
+ }
+`;
+
+interface SelectedDataset {
+ dataset: string;
+ package: string;
+}
+
+export const DatasetComponent: React.FC<{
+ value?: SelectedDataset | string;
+ onChange: (newValue: SelectedDataset) => void;
+ datastreams: DataStream[];
+ pkgName?: string;
+ isDisabled?: boolean;
+ fieldLabel: string;
+ description?: string;
+}> = ({ value, onChange, datastreams, isDisabled, pkgName = '', fieldLabel, description }) => {
+ const datasetOptions =
+ datastreams.map((datastream: DataStream) => ({
+ label: datastream.dataset,
+ value: datastream,
+ })) ?? [];
+ const existingGenericStream = datasetOptions.find((ds) => ds.label === GENERIC_DATASET_NAME);
+ const valueAsOption = value
+ ? typeof value === 'string'
+ ? { label: value, value: { dataset: value, package: pkgName } }
+ : { label: value.dataset, value: { dataset: value.dataset, package: value.package } }
+ : undefined;
+ const defaultOption = valueAsOption ||
+ existingGenericStream || {
+ label: GENERIC_DATASET_NAME,
+ value: { dataset: GENERIC_DATASET_NAME, package: pkgName },
+ };
+
+ const [selectedOptions, setSelectedOptions] = useState>([defaultOption]);
+ const [isInvalid, setIsInvalid] = useState(false);
+ const [error, setError] = useState(undefined);
+
+ useEffect(() => {
+ if (!value || typeof value === 'string') onChange(defaultOption.value as SelectedDataset);
+ }, [value, defaultOption.value, onChange, pkgName]);
+
+ const onDatasetChange = (newSelectedOptions: Array<{ label: string; value?: DataStream }>) => {
+ setSelectedOptions(newSelectedOptions);
+ const dataStream = newSelectedOptions[0].value;
+ const { valid, error: dsError } = isValidDataset(newSelectedOptions[0].label, false);
+ setIsInvalid(!valid);
+ setError(dsError);
+ onChange({
+ dataset: newSelectedOptions[0].label,
+ package: !dataStream || typeof dataStream === 'string' ? pkgName : dataStream.package,
+ });
+ };
+
+ const onCreateOption = (searchValue: string = '') => {
+ const normalizedSearchValue = searchValue.trim().toLowerCase();
+ if (!normalizedSearchValue) {
+ return;
+ }
+ const newOption = {
+ label: searchValue,
+ value: { dataset: searchValue, package: pkgName },
+ };
+ setSelectedOptions([newOption]);
+ const { valid, error: dsError } = isValidDataset(searchValue, false);
+ setIsInvalid(!valid);
+ setError(dsError);
+ onChange({
+ dataset: searchValue,
+ package: pkgName,
+ });
+ };
+ return (
+ }
+ fullWidth
+ >
+ <>
+
+ {valueAsOption && valueAsOption.value.package !== pkgName && (
+ <>
+
+
+
+
+
+ }
+ >
+
+ {i18n.translate('xpack.fleet.datasetCombo.learnMoreLink', {
+ defaultMessage: 'learn more',
+ })}
+
+
+ ),
+ }}
+ />
+
+ >
+ )}
+ >
+
+ );
+};
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx
index 9464d60402a1d..653986a7128de 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_var_field.tsx
@@ -36,7 +36,7 @@ import { DATASET_VAR_NAME } from '../../../../../../../../../common/constants';
import type { DataStream, RegistryVarsEntry } from '../../../../../../types';
import { MultiTextInput } from './multi_text_input';
-import { DatasetComboBox } from './dataset_combo';
+import { DatasetComponent } from './dataset_component';
const FixedHeightDiv = styled.div`
height: 300px;
@@ -88,7 +88,6 @@ export const PackagePolicyInputVarField: React.FunctionComponent {
const fleetStatus = useFleetStatus();
-
const [isDirty, setIsDirty] = useState(false);
const { required, type, title, name, description } = varDef;
const isInvalid = Boolean((isDirty || forceShowErrors) && !!varErrors?.length);
@@ -101,6 +100,20 @@ export const PackagePolicyInputVarField: React.FunctionComponent
+ );
+ }
+
let field: JSX.Element;
if (useSecretsUi) {
@@ -127,10 +140,6 @@ export const PackagePolicyInputVarField: React.FunctionComponent
);
}
- if (name === DATASET_VAR_NAME && packageType === 'input') {
- return (
-
- );
- }
switch (type) {
case 'textarea':
return (
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 2f0ab0b25c907..845fe18530a5a 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -18698,10 +18698,6 @@
"xpack.fleet.multiRowInput.addRow": "Ajouter une ligne",
"xpack.fleet.multiRowInput.deleteButton": "Supprimer la ligne",
"xpack.fleet.multiTextInput.addRow": "Ajouter une ligne",
- "xpack.fleet.namespaceValidation.invalidCharactersErrorMessage": "L'espace de nom contient des caractères non valides",
- "xpack.fleet.namespaceValidation.lowercaseErrorMessage": "L'espace de nom doit être en minuscules",
- "xpack.fleet.namespaceValidation.requiredErrorMessage": "L'espace de nom est obligatoire",
- "xpack.fleet.namespaceValidation.tooLongErrorMessage": "L'espace de nom ne peut pas dépasser 100 octets",
"xpack.fleet.newEnrollmentKey.cancelButtonLabel": "Annuler",
"xpack.fleet.newEnrollmentKey.helpText": "Un ID de jeton sera utilisé si ce champ est laissé vide.",
"xpack.fleet.newEnrollmentKey.keyCreatedToasts": "Jeton d'enregistrement créé",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 6d9d12a3c36a5..351327102a5f1 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -18675,10 +18675,6 @@
"xpack.fleet.multiRowInput.addRow": "行の追加",
"xpack.fleet.multiRowInput.deleteButton": "行の削除",
"xpack.fleet.multiTextInput.addRow": "行の追加",
- "xpack.fleet.namespaceValidation.invalidCharactersErrorMessage": "名前空間に無効な文字が含まれています",
- "xpack.fleet.namespaceValidation.lowercaseErrorMessage": "名前空間は小文字で指定する必要があります",
- "xpack.fleet.namespaceValidation.requiredErrorMessage": "名前空間は必須です",
- "xpack.fleet.namespaceValidation.tooLongErrorMessage": "名前空間は100バイト以下でなければなりません",
"xpack.fleet.newEnrollmentKey.cancelButtonLabel": "キャンセル",
"xpack.fleet.newEnrollmentKey.helpText": "これを空にすると、トークンIDが使用されます。",
"xpack.fleet.newEnrollmentKey.keyCreatedToasts": "登録トークンが作成されました",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 4e76adb30ab5f..69f740ad5ac0e 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -18704,10 +18704,6 @@
"xpack.fleet.multiRowInput.addRow": "添加行",
"xpack.fleet.multiRowInput.deleteButton": "删除行",
"xpack.fleet.multiTextInput.addRow": "添加行",
- "xpack.fleet.namespaceValidation.invalidCharactersErrorMessage": "命名空间包含无效字符",
- "xpack.fleet.namespaceValidation.lowercaseErrorMessage": "命名空间必须小写",
- "xpack.fleet.namespaceValidation.requiredErrorMessage": "“命名空间”必填",
- "xpack.fleet.namespaceValidation.tooLongErrorMessage": "命名空间不能超过 100 个字节",
"xpack.fleet.newEnrollmentKey.cancelButtonLabel": "取消",
"xpack.fleet.newEnrollmentKey.helpText": "此项留空时,将使用令牌 ID。",
"xpack.fleet.newEnrollmentKey.keyCreatedToasts": "注册令牌已创建",
diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/input_package_rollback.ts b/x-pack/test/fleet_api_integration/apis/package_policy/input_package_rollback.ts
index 50c325dac22fb..f470b872a8e52 100644
--- a/x-pack/test/fleet_api_integration/apis/package_policy/input_package_rollback.ts
+++ b/x-pack/test/fleet_api_integration/apis/package_policy/input_package_rollback.ts
@@ -79,7 +79,7 @@ export default function (providerContext: FtrProviderContext) {
.send(policy)
.expect(expectStatusCode);
- return res.body.item;
+ return expectStatusCode === 200 ? res.body.item : res;
};
const createAgentPolicy = async (name = 'Input Package Test 3') => {
@@ -117,7 +117,10 @@ export default function (providerContext: FtrProviderContext) {
setupFleetAndAgents(providerContext);
it('should rollback package install on package policy create failure', async () => {
- await createPackagePolicyWithDataset(agentPolicyId, 'test*', 400);
+ const res = await createPackagePolicyWithDataset(agentPolicyId, 'test*', 400);
+ expect(res.body.message).to.eql(
+ 'Package policy is invalid: inputs.logfile.streams.input_package_upgrade.logs.vars.data_stream.dataset: Dataset contains invalid characters'
+ );
const pkg = await getPackage(PACKAGE_NAME, START_VERSION);
expect(pkg?.status).to.eql('not_installed');