Skip to content

Commit

Permalink
Migrate wazuh.yml configuration to opensearch_dashboards.yml (#7175)
Browse files Browse the repository at this point in the history
* Added wazuh configuration in wazuh_core plugin

* Add hosts config on opensearch_dashboards.yml

* Add advanced settings (ui_settings)

* Move all configurations to yml and ui settings

* Add new configuration providers and repository

* Update providers

* Update core with new configuration store interface

* Fix main errores

* Create configuration services folder on common

* Update server configuration services and types

* Create public configuration types

* Apply new configuration store implementation on server

* Apply new configuration store implementation on public context

* Moved ui settings to common

* Update providers and configuration types

* Use configuration service on public

* Add configuration store unit tests

* Update configuration service unit tests

* Adapt the plugin settings to ui settings

* Use settings adapter to create plugin config

* Fix conflicts with master

* Apply prettier

* Apply prettier

* Fix linter errors

* Fix linter error

* Fix linter errors

* Fix linter errors

* Fix linter error

* Fix linter errors

* Fix linter errors

* Apply prettier

* Fix errors and unit tests

* Resolve requested changes

* Add port number validation
  • Loading branch information
Machi3mfl authored Dec 30, 2024
1 parent b58f540 commit 09dd139
Show file tree
Hide file tree
Showing 38 changed files with 1,314 additions and 3,908 deletions.
7 changes: 7 additions & 0 deletions docker/osd-dev/config/2.x/osd/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ opensearch.username: 'kibanaserver'
opensearch.password: 'kibanaserver'
opensearchDashboards.branding:
useExpandedHeader: false
wazuh_core.hosts:
manager:
url: 'https://wazuh.manager'
port: 55000
username: wazuh-wui
password: MyS3cr37P450r.*-
run_as: false
76 changes: 33 additions & 43 deletions plugins/main/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {
Plugin,
PluginInitializerContext,
} from 'opensearch_dashboards/public';
import { Cookies } from 'react-cookie';
import { euiPaletteColorBlind } from '@elastic/eui';
import { createHashHistory } from 'history';
import {
setDataPlugin,
setHttp,
Expand All @@ -27,61 +30,49 @@ import {
setWazuhEnginePlugin,
setWazuhFleetPlugin,
} from './kibana-services';
import { validate as validateNodeCronInterval } from 'node-cron';
import {
AppPluginStartDependencies,
WazuhSetup,
WazuhSetupPlugins,
WazuhStart,
WazuhStartPlugins,
} from './types';
import { Cookies } from 'react-cookie';
import { AppState } from './react-services/app-state';
import { setErrorOrchestrator } from './react-services/common-services';
import { ErrorOrchestratorService } from './react-services/error-orchestrator/error-orchestrator.service';
import store from './redux/store';
import { updateAppConfig } from './redux/actions/appConfigActions';
import {
initializeInterceptor,
unregisterInterceptor,
} from './services/request-handler';
import { Applications, Categories } from './utils/applications';
import { euiPaletteColorBlind } from '@elastic/eui';
import NavigationService from './react-services/navigation-service';
import { createHashHistory } from 'history';
import { reportingDefinitions } from './react-services/reporting/reporting-definitions';

export class WazuhPlugin
implements
Plugin<WazuhSetup, WazuhStart, WazuhSetupPlugins, WazuhStartPlugins>
{
constructor(private readonly initializerContext: PluginInitializerContext) {}

private hideTelemetryBanner?: () => void;

public async setup(
core: CoreSetup,
plugins: WazuhSetupPlugins,
): Promise<WazuhSetup> {
// Get custom logos configuration to start up the app with the correct logos
let logosInitialState = {};
try {
logosInitialState = await core.http.get(`/api/logos`);
} catch (error) {
console.error('plugin.ts: Error getting logos configuration', error);
}

// Redefine the mapKeys method to change the properties sent to euiPaletteColorBlind.
// This is a workaround until the issue reported in Opensearch Dashboards is fixed.
// https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5422
// This should be reomved when the issue is fixed. Probably in OSD 2.12.0
plugins.charts.colors.mappedColors.mapKeys = function (
keys: Array<string | number>,
keys: (string | number)[],
) {
const configMapping = this.getConfigColorMapping();
const configColors = _.values(configMapping);
const oldColors = _.values(this._oldMap);

let alreadyUsedColors: string[] = [];
const keysToMap: Array<string | number> = [];
const keysToMap: (string | number)[] = [];

_.each(keys, key => {
// If this key is mapped in the config, it's unnecessary to have it mapped here
if (configMapping[key as any]) {
Expand All @@ -90,7 +81,9 @@ export class WazuhPlugin
}

// If this key is mapped to a color used by the config color mapping, we need to remap it
if (_.includes(configColors, this._mapping[key])) keysToMap.push(key);
if (_.includes(configColors, this._mapping[key])) {
keysToMap.push(key);
}

// if key exist in oldMap, move it to mapping
if (this._oldMap[key]) {
Expand All @@ -99,13 +92,16 @@ export class WazuhPlugin
}

// If this key isn't mapped, we need to map it
if (this.get(key) == null) keysToMap.push(key);
if (this.get(key) === null) {
keysToMap.push(key);
}
});

alreadyUsedColors.push(...Object.values(this._mapping));
alreadyUsedColors = alreadyUsedColors.map(color =>
color.toLocaleLowerCase(),
);

// Choose colors from euiPaletteColorBlind and filter out any already assigned to keys
const colorPalette = euiPaletteColorBlind({
rotations: Math.ceil(
Expand All @@ -120,57 +116,46 @@ export class WazuhPlugin
};

// Register the applications
Applications.forEach(app => {
for (const app of Applications) {
const { category, id, title, redirectTo, order } = app;

core.application.register({
id,
title,
order,
mount: async (params: AppMountParameters) => {
try {
/* Workaround: Redefine the validation functions of cron.statistics.interval setting.
There is an optimization error of the frontend side source code due to some modules can
not be loaded
*/
const setting = plugins.wazuhCore.configuration._settings.get(
'cron.statistics.interval',
);
!setting.validateUIForm &&
(setting.validateUIForm = function (value) {
return this.validate(value);
});
!setting.validate &&
(setting.validate = function (value: string) {
return validateNodeCronInterval(value)
? undefined
: 'Interval is not valid.';
});
setWzCurrentAppID(id);
// Set the dynamic redirection
setWzMainParams(redirectTo());
initializeInterceptor(core);

// Update redux app state logos with the custom logos
if (logosInitialState?.logos) {
store.dispatch(updateAppConfig(logosInitialState.logos));
}
// hide the telemetry banner.
// Set the flag in the telemetry saved object as the notice was seen and dismissed
this.hideTelemetryBanner && (await this.hideTelemetryBanner());
if (this.hideTelemetryBanner) {
await this.hideTelemetryBanner();
}

setScopedHistory(params.history);
// This allows you to add the selectors to the navbar
setHeaderActionMenuMounter(params.setHeaderActionMenu);
NavigationService.getInstance(createHashHistory());

// Load application bundle
const { renderApp } = await import('./application');

setErrorOrchestrator(ErrorOrchestratorService);
setHttp(core.http);
setCookies(new Cookies());

if (!AppState.checkCookies()) {
NavigationService.getInstance().reload();
}

params.element.classList.add('dscAppWrapper', 'wz-app');

const unmount = await renderApp(params);

return () => {
unmount();
unregisterInterceptor();
Expand All @@ -183,9 +168,11 @@ export class WazuhPlugin
({ id: categoryID }) => categoryID === category,
),
});
});
}

return {};
}

public start(
core: CoreStart,
plugins: AppPluginStartDependencies,
Expand All @@ -194,11 +181,13 @@ export class WazuhPlugin
if (plugins.securityOss) {
plugins.securityOss.insecureCluster.hideAlert(true);
}

if (plugins?.telemetry?.telemetryNotifications?.setOptedInNoticeSeen) {
// assign to a method to hide the telemetry banner used when the app is mounted
this.hideTelemetryBanner = () =>
plugins.telemetry.telemetryNotifications.setOptedInNoticeSeen();
}

setCore(core);
setPlugins(plugins);
setHttp(core.http);
Expand All @@ -215,6 +204,7 @@ export class WazuhPlugin
setWazuhCorePlugin(plugins.wazuhCore);
setWazuhEnginePlugin(plugins.wazuhEngine);
setWazuhFleetPlugin(plugins.wazuhFleet);

return {};
}
}
51 changes: 24 additions & 27 deletions plugins/main/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,10 @@ import {
PluginInitializerContext,
SharedGlobalConfig,
} from 'opensearch_dashboards/server';

import { first } from 'rxjs/operators';
import { WazuhPluginSetup, WazuhPluginStart, PluginSetup } from './types';
import { setupRoutes } from './routes';
import {
jobInitializeRun,
jobMonitoringRun,
jobSchedulerRun,
jobQueueRun,
jobMigrationTasksRun,
jobSanitizeUploadedFilesTasksRun,
} from './start';
import { first } from 'rxjs/operators';
import { jobInitializeRun, jobQueueRun, jobMigrationTasksRun } from './start';

declare module 'opensearch_dashboards/server' {
interface RequestHandlerContext {
Expand Down Expand Up @@ -82,31 +74,31 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {

const serverInfo = core.http.getServerInfo();

core.http.registerRouteHandlerContext('wazuh', (context, request) => {
return {
// Create a custom logger with a tag composed of HTTP method and path endpoint
logger: this.logger.get(
`${request.route.method.toUpperCase()} ${request.route.path}`,
),
server: {
info: serverInfo,
},
plugins,
security: plugins.wazuhCore.dashboardSecurity,
api: context.wazuh_core.api,
};
});
core.http.registerRouteHandlerContext('wazuh', (context, request) => ({
// Create a custom logger with a tag composed of HTTP method and path endpoint
logger: this.logger.get(
`${request.route.method.toUpperCase()} ${request.route.path}`,
),
server: {
info: serverInfo,
},
plugins,
security: plugins.wazuhCore.dashboardSecurity,
api: context.wazuh_core.api,
}));

// Add custom headers to the responses
core.http.registerOnPreResponse((request, response, toolkit) => {
const additionalHeaders = {
'x-frame-options': 'sameorigin',
};

return toolkit.next({ headers: additionalHeaders });
});

// Routes
const router = core.http.createRouter();

setupRoutes(router, plugins.wazuhCore);

return {};
Expand All @@ -117,7 +109,6 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
await this.initializerContext.config.legacy.globalConfig$
.pipe(first())
.toPromise();

const contextServer = {
config: globalConfiguration,
};
Expand All @@ -134,6 +125,8 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
});

// Sanitize uploaded files tasks
// error: [error][plugins][sanitize-uploaded-files-task][wazuh] sanitize:sanitizeUploadedSVG: Error: Configuration undefined not found
/*
jobSanitizeUploadedFilesTasksRun({
core,
wazuh: {
Expand All @@ -143,6 +136,7 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
wazuh_core: plugins.wazuhCore,
server: contextServer,
});
*/

// Migration tasks
jobMigrationTasksRun({
Expand All @@ -155,7 +149,7 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
server: contextServer,
});

// Monitoring
/* Monitoring
jobMonitoringRun({
core,
wazuh: {
Expand All @@ -165,8 +159,9 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
wazuh_core: plugins.wazuhCore,
server: contextServer,
});
*/

// Scheduler
/* Scheduler
jobSchedulerRun({
core,
wazuh: {
Expand All @@ -176,6 +171,7 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
wazuh_core: plugins.wazuhCore,
server: contextServer,
});
*/

// Queue
jobQueueRun({
Expand All @@ -187,6 +183,7 @@ export class WazuhPlugin implements Plugin<WazuhPluginSetup, WazuhPluginStart> {
wazuh_core: plugins.wazuhCore,
server: contextServer,
});

return {};
}

Expand Down
10 changes: 6 additions & 4 deletions plugins/main/server/routes/wazuh-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IRouter } from 'opensearch_dashboards/server';
import { WazuhApiCtrl } from '../controllers';
import { schema } from '@osd/config-schema';
import { WazuhApiCtrl } from '../controllers';

export function WazuhApiRoutes(router: IRouter) {
const ctrl = new WazuhApiCtrl();
Expand Down Expand Up @@ -28,11 +28,11 @@ export function WazuhApiRoutes(router: IRouter) {
validate: {
body: schema.any({
// TODO: not ready
//id: schema.string(),
// id: schema.string(),
// url: schema.string(),
// port: schema.number(),
// username: schema.string(),
//forceRefresh: schema.boolean({defaultValue:false}),
// forceRefresh: schema.boolean({defaultValue:false}),
// cluster_info: schema.object({
// status: schema.string(),
// manager: schema.string(),
Expand Down Expand Up @@ -128,7 +128,8 @@ export function WazuhApiRoutes(router: IRouter) {
ctrl.getSyscollector(context, request, response),
);

// Return app logos configuration
/* Return app logos configuration
ToDo: Change (maybe) to get the opensearch logo settings
router.get(
{
path: '/api/logos',
Expand All @@ -138,6 +139,7 @@ export function WazuhApiRoutes(router: IRouter) {
async (context, request, response) =>
ctrl.getAppLogos(context, request, response),
);
*/

// Return binary dashboard
router.get(
Expand Down
1 change: 0 additions & 1 deletion plugins/main/server/start/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from './cron-scheduler';
export * from './initialize';
export * from './monitoring';
export * from './queue';
export * from './tryCatchForIndexPermissionError';
export * from './migration-tasks';
Expand Down
Loading

0 comments on commit 09dd139

Please sign in to comment.