diff --git a/x-pack/plugins/fleet/common/settings/agent_policy_settings.tsx b/x-pack/plugins/fleet/common/settings/agent_policy_settings.tsx
index a4b41979840b2..55a5885fa4e6b 100644
--- a/x-pack/plugins/fleet/common/settings/agent_policy_settings.tsx
+++ b/x-pack/plugins/fleet/common/settings/agent_policy_settings.tsx
@@ -40,7 +40,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
api_field: {
name: 'agent_limits_go_max_procs',
},
- schema: z.number().int().min(0).default(0),
+ schema: z.number().int().min(0),
},
{
name: 'agent.download.timeout',
@@ -59,7 +59,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
api_field: {
name: 'agent_download_timeout',
},
- schema: zodStringWithDurationValidation.default('2h'),
+ schema: zodStringWithDurationValidation,
},
{
name: 'agent.download.target_directory',
@@ -103,7 +103,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
),
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
- schema: zodStringWithDurationValidation.default('30s'),
+ schema: zodStringWithDurationValidation,
},
{
name: 'agent.logging.level',
@@ -124,4 +124,76 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
'https://www.elastic.co/guide/en/fleet/current/agent-policy.html#agent-policy-log-level',
schema: z.enum(AGENT_LOG_LEVELS).default(DEFAULT_LOG_LEVEL),
},
+ {
+ name: 'agent.logging.to_files',
+ title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingToFilesTitle', {
+ defaultMessage: 'Agent logging to files',
+ }),
+ description: (
+
+ ),
+ api_field: {
+ name: 'agent_logging_to_files',
+ },
+ learnMoreLink:
+ 'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
+ schema: z.boolean().default(true),
+ },
+ {
+ name: 'agent.logging.files.rotateeverybytes',
+ title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileSizeTitle', {
+ defaultMessage: 'Agent logging file size limit',
+ }),
+ description: (
+
+ ),
+ api_field: {
+ name: 'agent_logging_files_rotateeverybytes',
+ },
+ learnMoreLink:
+ 'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
+ schema: z.number().int().min(0),
+ },
+ {
+ name: 'agent.logging.files.keepfiles',
+ title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileLimitTitle', {
+ defaultMessage: 'Agent logging number of files',
+ }),
+ description: (
+
+ ),
+ api_field: {
+ name: 'agent_logging_files_keepfiles',
+ },
+ learnMoreLink:
+ 'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
+ schema: z.number().int().min(0),
+ },
+ {
+ name: 'agent.logging.files.interval',
+ title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileIntervalitle', {
+ defaultMessage: 'Agent logging number of files',
+ }),
+ description: (
+
+ ),
+ api_field: {
+ name: 'agent_logging_files_interval',
+ },
+ learnMoreLink:
+ 'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
+ schema: zodStringWithDurationValidation,
+ },
];
diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts
index 72ba130e77379..b33b5b71b8c76 100644
--- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts
+++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts
@@ -182,6 +182,18 @@ export interface FullAgentPolicy {
uninstall_token_hash: string;
signing_key: string;
};
+ logging?: {
+ level?: string;
+ to_files?: boolean;
+ files?: {
+ rotateeverybytes?: number;
+ keepfiles?: number;
+ interval?: string;
+ };
+ };
+ limits?: {
+ go_max_procs?: number;
+ };
};
secret_references?: PolicySecretReference[];
signed?: {
diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.test.tsx
index 8bafc124ec36b..768f9f913607d 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.test.tsx
@@ -102,6 +102,35 @@ describe('ConfiguredSettings', () => {
expect(mockUpdateAdvancedSettingsHasErrors).toHaveBeenCalledWith(true);
});
+ it('should render boolean field using checkbox', () => {
+ const result = render([
+ {
+ name: 'agent.logging.to_files',
+ title: 'Agent logging to files',
+ description: 'Description',
+ learnMoreLink: '',
+ api_field: {
+ name: 'agent_logging_to_files',
+ },
+ schema: z.boolean().default(false),
+ },
+ ]);
+
+ expect(result.getByText('Agent logging to files')).not.toBeNull();
+ const input = result.getByTestId('configuredSetting-agent.logging.to_files');
+ expect(input).not.toBeChecked();
+
+ act(() => {
+ fireEvent.click(input);
+ });
+
+ expect(mockUpdateAgentPolicy).toHaveBeenCalledWith(
+ expect.objectContaining({
+ advanced_settings: expect.objectContaining({ agent_logging_to_files: true }),
+ })
+ );
+ });
+
it('should not render field if hidden', () => {
const result = render([
{
diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.tsx
index 7ebf80141c554..e93dd0b6cdd82 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/index.tsx
@@ -7,7 +7,9 @@
import { ZodFirstPartyTypeKind } from '@kbn/zod';
import React from 'react';
-import { EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui';
+import { EuiCheckbox, EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui';
+
+import { i18n } from '@kbn/i18n';
import type { SettingsConfig } from '../../../../../common/settings/types';
@@ -68,7 +70,7 @@ settingComponentRegistry.set(ZodFirstPartyTypeKind.ZodEnum, ({ disabled, ...sett
(
{
+ return (
+ (
+
+ )}
+ />
+ );
+ }
+);
+
export function ConfiguredSettings({
configuredSettings,
disabled,
@@ -101,7 +127,7 @@ export function ConfiguredSettings({
const Component = settingComponentRegistry.get(getInnerType(configuredSetting.schema));
if (!Component) {
- throw new Error(`Unknown setting type: ${configuredSetting.schema._type}}`);
+ throw new Error(`Unknown setting type: ${configuredSetting.schema._type}`);
}
return (
diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/settings_field_wrapper.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/settings_field_wrapper.tsx
index 61adef4729a27..1885d466711fb 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/settings_field_wrapper.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/components/form_settings/settings_field_wrapper.tsx
@@ -13,12 +13,15 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui';
import type { SettingsConfig } from '../../../../../common/settings/types';
import { useAgentPolicyFormContext } from '../../sections/agent_policy/components/agent_policy_form';
-export const convertValue = (value: string, type: keyof typeof ZodFirstPartyTypeKind): any => {
+export const convertValue = (
+ value: string | boolean,
+ type: keyof typeof ZodFirstPartyTypeKind
+): any => {
if (type === ZodFirstPartyTypeKind.ZodNumber) {
if (value === '') {
return 0;
}
- return parseInt(value, 10);
+ return parseInt(value as string, 10);
}
return value;
};
@@ -48,7 +51,8 @@ export const SettingsFieldWrapper: React.FC<{
const coercedSchema = settingsConfig.schema as z.ZodString;
const handleChange = (e: React.ChangeEvent) => {
- const newValue = convertValue(e.target.value, typeName);
+ const value = typeName === ZodFirstPartyTypeKind.ZodBoolean ? e.target.checked : e.target.value;
+ const newValue = convertValue(value, typeName);
const validationError = validateSchema(coercedSchema, newValue);
if (validationError) {
@@ -97,9 +101,13 @@ export const SettingsFieldWrapper: React.FC<{
};
export const getInnerType = (schema: z.ZodType) => {
- return schema instanceof z.ZodDefault
- ? schema._def.innerType._def.typeName === 'ZodEffects'
+ if (schema._def.innerType) {
+ return schema._def.innerType._def.typeName === 'ZodEffects'
? schema._def.innerType._def.schema._def.typeName
- : schema._def.innerType._def.typeName
- : schema._def.typeName;
+ : schema._def.innerType._def.typeName;
+ }
+ if (schema._def.typeName === 'ZodEffects') {
+ return schema._def.schema._def.typeName;
+ }
+ return schema._def.typeName;
};
diff --git a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts
index fa5522d50802b..b62724b0cea50 100644
--- a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts
+++ b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts
@@ -888,6 +888,10 @@ describe('getFullAgentPolicy', () => {
advanced_settings: {
agent_limits_go_max_procs: 2,
agent_logging_level: 'debug',
+ agent_logging_to_files: true,
+ agent_logging_files_rotateeverybytes: 10000,
+ agent_logging_files_keepfiles: 10,
+ agent_logging_files_interval: '7h',
},
});
const agentPolicy = await getFullAgentPolicy(savedObjectsClientMock.create(), 'agent-policy');
@@ -896,7 +900,11 @@ describe('getFullAgentPolicy', () => {
id: 'agent-policy',
agent: {
limits: { go_max_procs: 2 },
- logging: { level: 'debug' },
+ logging: {
+ level: 'debug',
+ to_files: true,
+ files: { rotateeverybytes: 10000, keepfiles: 10, interval: '7h' },
+ },
},
});
});
diff --git a/x-pack/plugins/fleet/server/services/form_settings/form_settings.test.ts b/x-pack/plugins/fleet/server/services/form_settings/form_settings.test.ts
index afcba824f1a33..710d862bf3ad1 100644
--- a/x-pack/plugins/fleet/server/services/form_settings/form_settings.test.ts
+++ b/x-pack/plugins/fleet/server/services/form_settings/form_settings.test.ts
@@ -55,10 +55,10 @@ describe('form_settings', () => {
).not.toThrow();
});
- it('generate a valid API schema for api_field with default value', () => {
+ it('generate a valid API schema for api_field with default value but not add the value', () => {
const apiSchema = schema.object(_getSettingsAPISchema(TEST_SETTINGS));
const res = apiSchema.validate({ advanced_settings: {} });
- expect(res).toEqual({ advanced_settings: { test_foo_default_value: 'test' } });
+ expect(res).toEqual({ advanced_settings: {} });
});
});
diff --git a/x-pack/plugins/fleet/server/services/form_settings/form_settings.ts b/x-pack/plugins/fleet/server/services/form_settings/form_settings.ts
index a381fcd55b4ba..2c625f6bd0574 100644
--- a/x-pack/plugins/fleet/server/services/form_settings/form_settings.ts
+++ b/x-pack/plugins/fleet/server/services/form_settings/form_settings.ts
@@ -24,39 +24,19 @@ export function _getSettingsAPISchema(settings: SettingsConfig[]): Props {
if (!setting.api_field) {
return;
}
- const defaultValueRes = setting.schema.safeParse(undefined);
- const defaultValue = defaultValueRes.success ? defaultValueRes.data : undefined;
- if (defaultValue) {
- validations[setting.api_field.name] = schema.oneOf(
- [
- schema.any({
- validate: (val: any) => {
- const res = setting.schema.safeParse(val);
- if (!res.success) {
- return stringifyZodError(res.error);
- }
- },
- }),
- schema.literal(null),
- ],
- {
- defaultValue,
- }
- );
- } else {
- validations[setting.api_field.name] = schema.maybe(
- schema.nullable(
- schema.any({
- validate: (val: any) => {
- const res = setting.schema.safeParse(val);
- if (!res.success) {
- return stringifyZodError(res.error);
- }
- },
- })
- )
- );
- }
+ validations[setting.api_field.name] = schema.maybe(
+ schema.oneOf([
+ schema.literal(null),
+ schema.any({
+ validate: (val: any) => {
+ const res = setting.schema.safeParse(val);
+ if (!res.success) {
+ return stringifyZodError(res.error);
+ }
+ },
+ }),
+ ])
+ );
});
const advancedSettingsValidations: Props = {
@@ -89,7 +69,7 @@ export function _getSettingsValuesForAgentPolicy(
}
const val = agentPolicy.advanced_settings?.[setting.api_field.name];
- if (val) {
+ if (val !== undefined) {
settingsValues[setting.name] = val;
}
});