Skip to content

Commit

Permalink
POC Spike Fleet Management (#6935)
Browse files Browse the repository at this point in the history
* New plugin wazuh-fleet

* Implement wazuh-fleet sidebar and fleet list components

* Add agents grid

* Add fields to script

* Add visualizations in agents summary

* Improve agent list

* Add agent details page and flyout

* Add groups index script

* Add groups data source

* Add groups components to router

* Add group table

* Add command index script

* Add commands list in fleet management

* Fix get agent details

* Improve and fix minor issues

* Add host and networks to script and improve agent view

* Apply prettier

* Apply prettier

* Upgrade axios dependency

* Prettier

* Fix agent.id field in commands columns

---------

Co-authored-by: Luciano Gorza <[email protected]>
Co-authored-by: Federico Rodriguez <[email protected]>
  • Loading branch information
3 people authored Aug 22, 2024
1 parent 1b0c94e commit a1fc490
Show file tree
Hide file tree
Showing 91 changed files with 4,510 additions and 23 deletions.
17 changes: 0 additions & 17 deletions .vscode/settings.json

This file was deleted.

1 change: 1 addition & 0 deletions docker/osd-dev/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ services:
- '${SRC}/main:/home/node/kbn/plugins/wazuh'
- '${SRC}/wazuh-core:/home/node/kbn/plugins/wazuh-core'
- '${SRC}/wazuh-check-updates:/home/node/kbn/plugins/wazuh-check-updates'
- '${SRC}/wazuh-fleet:/home/node/kbn/plugins/wazuh-fleet'
- wd_certs:/home/node/kbn/certs/
- ${WAZUH_DASHBOARD_CONF}:/home/node/kbn/config/opensearch_dashboards.yml
- ./config/${OSD_MAJOR}/osd/wazuh.yml:/home/node/kbn/data/wazuh/config/wazuh.yml
Expand Down
5 changes: 5 additions & 0 deletions plugins/main/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export const WAZUH_VULNERABILITIES_PATTERN = 'wazuh-states-vulnerabilities-*';
export const WAZUH_INDEX_TYPE_VULNERABILITIES = 'vulnerabilities';
export const VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER = 'wazuh.cluster.name';

// Wazuh Fleet
export const WAZUH_FLEET_PATTERN = 'wazuh-fleet-*';
export const WAZUH_INDEX_TYPE_FLEET = 'fleet';
export const FLEET_IMPLICIT_CLUSTER_MODE_FILTER = 'wazuh.cluster.name';

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

Expand Down
3 changes: 2 additions & 1 deletion plugins/main/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"opensearchDashboardsUtils",
"opensearchDashboardsLegacy",
"wazuhCheckUpdates",
"wazuhCore"
"wazuhCore",
"wazuhFleet"
],
"optionalPlugins": [
"security",
Expand Down
50 changes: 49 additions & 1 deletion plugins/main/public/app-router.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { useEffect } from 'react';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
import { ToolsRouter } from './components/tools/tools-router';
import { getWazuhCorePlugin, getWzMainParams } from './kibana-services';
import {
getWazuhCorePlugin,
getWazuhFleetPlugin,
getWzMainParams,
} from './kibana-services';
import { updateCurrentPlatform } from './redux/actions/appStateActions';
import { useDispatch } from 'react-redux';
import { checkPluginVersion } from './utils';
Expand All @@ -21,12 +25,31 @@ import { Settings } from './components/settings';
import { WzSecurity } from './components/security';
import $ from 'jquery';
import NavigationService from './react-services/navigation-service';
import {
FleetDataSource,
FleetDataSourceRepository,
useDataSource,
FleetGroupsDataSource,
FleetGroupsDataSourceRepository,
FleetCommandsDataSource,
FleetCommandsDataSourceRepository,
AlertsDataSource,
AlertsDataSourceRepository,
} from './components/common/data-source';
import useSearchBar from './components/common/search-bar/use-search-bar';
import { WzSearchBar } from './components/common/search-bar';
import { TableIndexer } from './components/common/tables';
import DocDetails from './components/common/wazuh-discover/components/doc-details';
import { useTimeFilter } from './components/common/hooks';
import { LoadingSpinner } from './components/common/loading-spinner/loading-spinner';

export function Application(props) {
const dispatch = useDispatch();
const navigationService = NavigationService.getInstance();
const history = navigationService.getHistory();

const { FleetManagement } = getWazuhFleetPlugin();

useEffect(() => {
// Get the dashboard security
getWazuhCorePlugin()
Expand Down Expand Up @@ -78,6 +101,31 @@ export function Application(props) {
exact
render={MainEndpointsSummary}
></Route>
<Route
path={'/fleet-management'}
render={() => (
<FleetManagement
navigationService={NavigationService}
useDataSource={useDataSource}
FleetDataSource={FleetDataSource}
FleetDataSourceRepository={FleetDataSourceRepository}
FleetGroupsDataSource={FleetGroupsDataSource}
FleetGroupsDataSourceRepository={FleetGroupsDataSourceRepository}
FleetCommandsDataSource={FleetCommandsDataSource}
FleetCommandsDataSourceRepository={
FleetCommandsDataSourceRepository
}
useSearchBar={useSearchBar}
WzSearchBar={WzSearchBar}
TableIndexer={TableIndexer}
DocDetails={DocDetails}
useTimeFilter={useTimeFilter}
LoadingSpinner={LoadingSpinner}
AlertsDataSource={AlertsDataSource}
AlertsDataSourceRepository={AlertsDataSourceRepository}
/>
)}
></Route>
<Route path={'/manager'} exact render={WzManagement}></Route>
<Route
path={'/overview'}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { PatternDataSourceRepository } from '../../pattern-data-source-repository';
import { tParsedIndexPattern } from '../../../index';

export class FleetCommandsDataSourceRepository extends PatternDataSourceRepository {
constructor() {
super();
}

async get(id: string) {
const dataSource = await super.get(id);
if (this.validate(dataSource)) {
return dataSource;
} else {
throw new Error('Fleet index pattern not found');
}
}

async getAll() {
const indexs = await super.getAll();
return indexs.filter(this.validate);
}

validate(dataSource): boolean {
const stringToSearch = 'commands'; //always in lower case
return (
dataSource.id?.toLowerCase().includes(stringToSearch) ||
dataSource.attributes?.title?.toLowerCase().includes(stringToSearch)
);
}

getDefault() {
return Promise.resolve(null);
}

setDefault(dataSource: tParsedIndexPattern) {
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
} from '../../../../../../../common/constants';
import { tFilter, PatternDataSourceFilterManager } from '../../../index';
import { PatternDataSource } from '../../pattern-data-source';

export class FleetCommandsDataSource extends PatternDataSource {
constructor(id: string, title: string) {
super(id, title);
}

getFixedFilters(): tFilter[] {
return [...this.getClusterManagerFilters(), ...super.getFixedFilters()];
}

getClusterManagerFilters() {
return PatternDataSourceFilterManager.getClusterManagerFilters(
this.id,
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './fleet-commands-data-source';
export * from './fleet-commands-data-source-repository';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { PatternDataSourceRepository } from '../pattern-data-source-repository';
import { tParsedIndexPattern } from '../../index';

export class FleetDataSourceRepository extends PatternDataSourceRepository {
constructor() {
super();
}

async get(id: string) {
const dataSource = await super.get(id);
if (this.validate(dataSource)) {
return dataSource;
} else {
throw new Error('Fleet index pattern not found');
}
}

async getAll() {
const indexs = await super.getAll();
return indexs.filter(this.validate);
}

validate(dataSource): boolean {
const stringToSearch = 'fleet-agents'; //always in lower case
return (
dataSource.id?.toLowerCase().includes(stringToSearch) ||
dataSource.attributes?.title?.toLowerCase().includes(stringToSearch)
);
}

getDefault() {
return Promise.resolve(null);
}

setDefault(dataSource: tParsedIndexPattern) {
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
} from '../../../../../../common/constants';
import { tFilter, PatternDataSourceFilterManager } from '../../index';
import { PatternDataSource } from '../pattern-data-source';

export class FleetDataSource extends PatternDataSource {
constructor(id: string, title: string) {
super(id, title);
}

getFixedFilters(): tFilter[] {
return [...this.getClusterManagerFilters(), ...super.getFixedFilters()];
}

getClusterManagerFilters() {
return PatternDataSourceFilterManager.getClusterManagerFilters(
this.id,
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { PatternDataSourceRepository } from '../../pattern-data-source-repository';
import { tParsedIndexPattern } from '../../../index';

export class FleetGroupsDataSourceRepository extends PatternDataSourceRepository {
constructor() {
super();
}

async get(id: string) {
const dataSource = await super.get(id);
if (this.validate(dataSource)) {
return dataSource;
} else {
throw new Error('Fleet index pattern not found');
}
}

async getAll() {
const indexs = await super.getAll();
return indexs.filter(this.validate);
}

validate(dataSource): boolean {
const stringToSearch = 'fleet-groups'; //always in lower case
return (
dataSource.id?.toLowerCase().includes(stringToSearch) ||
dataSource.attributes?.title?.toLowerCase().includes(stringToSearch)
);
}

getDefault() {
return Promise.resolve(null);
}

setDefault(dataSource: tParsedIndexPattern) {
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
} from '../../../../../../../common/constants';
import { tFilter, PatternDataSourceFilterManager } from '../../../index';
import { PatternDataSource } from '../../pattern-data-source';

export class FleetGroupsDataSource extends PatternDataSource {
constructor(id: string, title: string) {
super(id, title);
}

getFixedFilters(): tFilter[] {
return [...this.getClusterManagerFilters(), ...super.getFixedFilters()];
}

getClusterManagerFilters() {
return PatternDataSourceFilterManager.getClusterManagerFilters(
this.id,
DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER,
FLEET_IMPLICIT_CLUSTER_MODE_FILTER,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './fleet-groups-data-source';
export * from './fleet-groups-data-source-repository';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './fleet-data-source-repository';
export * from './fleet-data-source';
export * from './groups';
export * from './commands';
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export * from './pattern-data-source-factory';
export * from './pattern-data-source-selector';
export * from './pattern-data-source-filter-manager';
export * from './alerts';
export * from './vulnerabilities';
export * from './vulnerabilities';
export * from './fleet';
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const WzSearchBar = ({
return (
<EuiPanel
className='wz-search-bar wz-search-bar-no-padding'
paddingSize='s'
paddingSize='none'
hasShadow={false}
hasBorder={false}
color='transparent'
Expand Down
1 change: 1 addition & 0 deletions plugins/main/public/components/common/tables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
export * from './table-with-search-bar';
export * from './table-wz-api';
export * from './table-default';
export * from './table-indexer';
Loading

0 comments on commit a1fc490

Please sign in to comment.