Skip to content

Commit

Permalink
Add vulnerabilities configurations and healthCheck (#6147)
Browse files Browse the repository at this point in the history
* Add vulnerabilities configurations and healthCheck

* Update check-result test

* Sync core and main plugin default configuration

* Fix useSearchBarConfiguration for a test

* Fix useSearchBarConfiguration

---------

Co-authored-by: Federico Rodriguez <[email protected]>
Co-authored-by: Maximiliano Ibarra <[email protected]>
  • Loading branch information
3 people authored Nov 23, 2023
1 parent cfd875c commit e391616
Show file tree
Hide file tree
Showing 22 changed files with 815 additions and 785 deletions.
10 changes: 10 additions & 0 deletions plugins/main/common/config-equivalences.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export const configEquivalences = {
'Define the number of replicas to use for the statistics indices.',
'alerts.sample.prefix':
'Define the index name prefix of sample alerts. It must match the template used by the index pattern to avoid unknown fields in dashboards.',
'vulnerabilities.pattern':
'Default index pattern to use for vulnerabilities.',
};

export const nameEquivalence = {
Expand Down Expand Up @@ -94,20 +96,24 @@ export const nameEquivalence = {
'cron.statistics.index.shards': 'Index shards',
'cron.statistics.index.replicas': 'Index replicas',
'alerts.sample.prefix': 'Sample alerts prefix',
'vulnerabilities.pattern': 'Index pattern',
'checks.vulnerabilities.pattern': 'Vulnerabilities index pattern',
};

const HEALTH_CHECK = 'Health Check';
const GENERAL = 'General';
const SECURITY = 'Security';
const MONITORING = 'Monitoring';
const STATISTICS = 'Statistics';
const VULNERABILITIES = 'Vulnerabilities';
const CUSTOMIZATION = 'Logo Customization';
export const categoriesNames = [
HEALTH_CHECK,
GENERAL,
SECURITY,
MONITORING,
STATISTICS,
VULNERABILITIES,
CUSTOMIZATION,
];

Expand Down Expand Up @@ -145,6 +151,8 @@ export const categoriesEquivalence = {
'cron.statistics.index.shards': STATISTICS,
'cron.statistics.index.replicas': STATISTICS,
'alerts.sample.prefix': GENERAL,
'vulnerabilities.pattern': VULNERABILITIES,
'checks.vulnerabilities.pattern': HEALTH_CHECK,
};

const TEXT = 'text';
Expand Down Expand Up @@ -216,4 +224,6 @@ export const formEquivalence = {
'cron.statistics.index.shards': { type: NUMBER },
'cron.statistics.index.replicas': { type: NUMBER },
'alerts.sample.prefix': { type: TEXT },
'vulnerabilities.pattern': { type: TEXT },
'checks.vulnerabilities.pattern': { type: BOOLEAN },
};
73 changes: 72 additions & 1 deletion plugins/main/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export const WAZUH_STATISTICS_DEFAULT_STATUS = true;
export const WAZUH_STATISTICS_DEFAULT_FREQUENCY = 900;
export const WAZUH_STATISTICS_DEFAULT_CRON_FREQ = '0 */5 * * * *';

// Wazuh vulnerabilities
export const WAZUH_VULNERABILITIES_PATTERN = 'wazuh-states-vulnerabilities';

// Job - Wazuh initialize
export const WAZUH_PLUGIN_PLATFORM_TEMPLATE_NAME = 'wazuh-kibana';

Expand Down Expand Up @@ -402,6 +405,10 @@ export const ELASTIC_NAME = 'elastic';
// Default Wazuh indexer name
export const WAZUH_INDEXER_NAME = 'Wazuh indexer';

// Not timeFieldName on index pattern
export const NOT_TIME_FIELD_NAME_INDEX_PATTERN =
'not_time_field_name_index_pattern';

// Customization
export const CUSTOMIZATION_ENDPOINT_PAYLOAD_UPLOAD_CUSTOM_FILE_MAXIMUM_BYTES = 1048576;

Expand All @@ -411,6 +418,7 @@ export enum SettingCategory {
HEALTH_CHECK,
MONITORING,
STATISTICS,
VULNERABILITIES,
SECURITY,
CUSTOMIZATION,
}
Expand Down Expand Up @@ -563,6 +571,12 @@ export const PLUGIN_SETTINGS_CATEGORIES: {
'Options related to the daemons manager monitoring job and their storage in indexes.',
renderOrder: SettingCategory.STATISTICS,
},
[SettingCategory.VULNERABILITIES]: {
title: 'Vulnerabilities',
description:
'Options related to the agent vulnerabilities monitoring job and its storage in indexes.',
renderOrder: SettingCategory.VULNERABILITIES,
},
[SettingCategory.CUSTOMIZATION]: {
title: 'Custom branding',
description:
Expand Down Expand Up @@ -820,6 +834,33 @@ export const PLUGIN_SETTINGS: { [key: string]: TPluginSetting } = {
return schema.boolean();
},
},
'checks.vulnerabilities.pattern': {
title: 'Vulnerabilities index pattern',
description:
'Enable or disable the vulnerabilities index pattern health check when opening the app.',
category: SettingCategory.HEALTH_CHECK,
type: EpluginSettingType.switch,
defaultValue: true,
isConfigurableFromFile: true,
isConfigurableFromUI: true,
options: {
switch: {
values: {
disabled: { label: 'false', value: false },
enabled: { label: 'true', value: true },
},
},
},
uiFormTransformChangedInputValue: function (
value: boolean | string,
): boolean {
return Boolean(value);
},
validate: SettingsValidator.isBoolean,
validateBackend: function (schema) {
return schema.boolean();
},
},
'cron.prefix': {
title: 'Cron prefix',
description: 'Define the index prefix of predefined jobs.',
Expand Down Expand Up @@ -1108,7 +1149,7 @@ export const PLUGIN_SETTINGS: { [key: string]: TPluginSetting } = {
},
'customization.logo.app': {
title: 'App main logo',
description: `This logo is used as loading indicator while the user is logging into Wazuh API`,
description: `This logo is used as loading indicator while the user is logging into Wazuh API.`,
category: SettingCategory.CUSTOMIZATION,
type: EpluginSettingType.filepicker,
defaultValue: '',
Expand Down Expand Up @@ -1720,6 +1761,36 @@ export const PLUGIN_SETTINGS: { [key: string]: TPluginSetting } = {
return schema.number({ validate: this.validate.bind(this) });
},
},
'vulnerabilities.pattern': {
title: 'Index pattern',
description: 'Default index pattern to use for vulnerabilities.',
category: SettingCategory.VULNERABILITIES,
type: EpluginSettingType.text,
defaultValue: WAZUH_VULNERABILITIES_PATTERN,
isConfigurableFromFile: true,
isConfigurableFromUI: true,
requiresRunningHealthCheck: false,
validate: SettingsValidator.compose(
SettingsValidator.isNotEmptyString,
SettingsValidator.hasNoSpaces,
SettingsValidator.noLiteralString('.', '..'),
SettingsValidator.noStartsWithString('-', '_', '+', '.'),
SettingsValidator.hasNotInvalidCharacters(
'\\',
'/',
'?',
'"',
'<',
'>',
'|',
',',
'#',
),
),
validateBackend: function (schema) {
return schema.string({ minLength: 1, validate: this.validate });
},
},
};

export type TPluginSettingKey = keyof typeof PLUGIN_SETTINGS;
Expand Down
18 changes: 18 additions & 0 deletions plugins/main/common/plugin-settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ describe('[settings] Input validation', () => {
${'checks.template'} | ${0} | ${'It should be a boolean. Allowed values: true or false.'}
${'checks.timeFilter'} | ${true} | ${undefined}
${'checks.timeFilter'} | ${0} | ${'It should be a boolean. Allowed values: true or false.'}
${'checks.vulnerabilities.pattern'} | ${true} | ${undefined}
${'checks.vulnerabilities.pattern'} | ${0} | ${'It should be a boolean. Allowed values: true or false.'}
${'cron.prefix'} | ${'test'} | ${undefined}
${'cron.prefix'} | ${'test space'} | ${'No whitespaces allowed.'}
${'cron.prefix'} | ${''} | ${'Value can not be empty.'}
Expand Down Expand Up @@ -208,6 +210,22 @@ describe('[settings] Input validation', () => {
${'wazuh.monitoring.shards'} | ${-1} | ${'Value should be greater or equal than 1.'}
${'wazuh.monitoring.shards'} | ${'1.2'} | ${'Number should be an integer.'}
${'wazuh.monitoring.shards'} | ${1.2} | ${'Number should be an integer.'}
${'vulnerabilities.pattern'} | ${'test'} | ${undefined}
${'vulnerabilities.pattern'} | ${'test*'} | ${undefined}
${'vulnerabilities.pattern'} | ${''} | ${'Value can not be empty.'}
${'vulnerabilities.pattern'} | ${'-test'} | ${"It can't start with: -, _, +, .."}
${'vulnerabilities.pattern'} | ${'_test'} | ${"It can't start with: -, _, +, .."}
${'vulnerabilities.pattern'} | ${'+test'} | ${"It can't start with: -, _, +, .."}
${'vulnerabilities.pattern'} | ${'.test'} | ${"It can't start with: -, _, +, .."}
${'vulnerabilities.pattern'} | ${'test\\'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test/'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test?'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test"'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test<'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test>'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test|'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test,'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
${'vulnerabilities.pattern'} | ${'test#'} | ${'It can\'t contain invalid characters: \\, /, ?, ", <, >, |, ,, #.'}
`(
'$setting | $value | $expectedValidation',
({ setting, value, expectedValidation }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ exports[`Check result component should render a Check result screen 1`] = `
check={true}
checksReady={Object {}}
cleanErrors={[MockFunction]}
cleanWarnings={[MockFunction]}
handleCheckReady={[MockFunction]}
handleErrors={[MockFunction]}
handleWarnings={[MockFunction]}
isLoading={false}
name="test"
title="Check Test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import { act } from 'react-dom/test-utils';

describe('Check result component', () => {
const validationService = jest.fn();
const handleWarnings = jest.fn();
const handleErrors = jest.fn();
const handleCheckReady = jest.fn();
const cleanWarnings = jest.fn();
const cleanErrors = jest.fn();

const awaitForMyComponent = async (wrapper: any) => {
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
await new Promise(resolve => setTimeout(resolve, 0));
wrapper.update();
});
};
Expand All @@ -38,13 +40,15 @@ describe('Check result component', () => {
awaitFor={[]}
check={true}
validationService={validationService}
handleWarnings={handleWarnings}
handleErrors={handleErrors}
isLoading={false}
handleCheckReady={handleCheckReady}
checksReady={{}}
cleanWarnings={cleanWarnings}
cleanErrors={cleanErrors}
canRetry={true}
/>
/>,
);

expect(component).toMatchSnapshot();
Expand All @@ -59,13 +63,15 @@ describe('Check result component', () => {
awaitFor={[]}
shouldCheck={true}
validationService={validationService}
handleWarnings={handleWarnings}
handleErrors={handleErrors}
isLoading={false}
handleCheckReady={handleCheckReady}
checksReady={{}}
cleanWarnings={cleanWarnings}
cleanErrors={cleanErrors}
canRetry={true}
/>
/>,
);

await awaitForMyComponent(wrapper);
Expand All @@ -85,13 +91,15 @@ describe('Check result component', () => {
awaitFor={[]}
shouldCheck={true}
validationService={validationService}
handleWarnings={handleWarnings}
handleErrors={handleErrors}
isLoading={false}
handleCheckReady={handleCheckReady}
checksReady={{}}
cleanWarnings={cleanWarnings}
cleanErrors={cleanErrors}
canRetry={true}
/>
/>,
);

await awaitForMyComponent(wrapper);
Expand All @@ -111,13 +119,15 @@ describe('Check result component', () => {
awaitFor={[]}
shouldCheck={true}
validationService={validationService}
handleWarnings={handleWarnings}
handleErrors={handleErrors}
isLoading={false}
handleCheckReady={handleCheckReady}
checksReady={{}}
cleanWarnings={cleanWarnings}
cleanErrors={cleanErrors}
canRetry={false}
/>
/>,
);

expect(wrapper.find('ResultIcons').exists()).toBeTruthy();
Expand Down
Loading

0 comments on commit e391616

Please sign in to comment.