From a049ec48ac79eebd9aec13634abb89a2b11dbacb Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Fri, 19 Apr 2024 17:35:25 -0300 Subject: [PATCH 01/12] Create AgentView component to replace controller --- .../common/welcome/agents-welcome.js | 13 +- .../endpoints-summary/agent/index.tsx | 283 ++++++++++++++++++ .../endpoints-summary/services/get-agents.tsx | 7 +- .../main/public/controllers/agent/index.js | 2 + plugins/main/public/services/routes.js | 1 + .../templates/agents/dashboards copy.html | 138 +++++++++ .../public/templates/agents/dashboards.html | 139 +-------- 7 files changed, 437 insertions(+), 146 deletions(-) create mode 100644 plugins/main/public/components/endpoints-summary/agent/index.tsx create mode 100644 plugins/main/public/templates/agents/dashboards copy.html diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index cb4b63fb54..956ee54b08 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -49,10 +49,10 @@ import { updateCurrentAgentData, } from '../../../redux/actions/appStateActions'; import { - getAngularModule, getChrome, getCore, getDataPlugin, + getAngularModule, } from '../../../kibana-services'; import { hasAgentSupportModule } from '../../../react-services/wz-agents'; import { @@ -150,6 +150,9 @@ export const AgentsWelcome = compose( this.sidebarSizeDefault = 320; + const $injector = getAngularModule().$injector; + this.location = $injector.get('$location'); + this.state = { lastScans: [], isLoading: true, @@ -200,8 +203,8 @@ export const AgentsWelcome = compose( of duplicating it. It was duplicated due to the differences of requirements in the Explore agent button for the modules and agent welcome */ - async removeAgentsFilter() { - await this.props.setAgent(false); + removeAgentsFilter() { + this.props.setAgent(false); const currentAppliedFilters = getDataPlugin().query.filterManager.filters; const agentFilters = currentAppliedFilters.filter(x => { return x.meta.key !== 'agent.id'; @@ -227,7 +230,7 @@ export const AgentsWelcome = compose( welcome: 8, }); const filterHandler = new FilterHandler(AppState.getCurrentPattern()); - const $injector = getAngularModule().$injector; + this.drawerLokedSubscribtion = getChrome() .getIsNavDrawerLocked$() .subscribe(isLocked => { @@ -235,8 +238,6 @@ export const AgentsWelcome = compose( this.updateWidth(); }); }); - this.router = $injector.get('$route'); - this.location = $injector.get('$location'); window.addEventListener('resize', this.updateWidth); //eslint-disable-line await VisFactoryHandler.buildAgentsVisualizations( filterHandler, diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx new file mode 100644 index 0000000000..29e81c7681 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -0,0 +1,283 @@ +import React, { useState, useEffect } from 'react'; +import { EuiPage, EuiPageBody, EuiProgress } from '@elastic/eui'; +import { getErrorOrchestrator } from '../../../react-services/common-services'; +import { UI_LOGGER_LEVELS } from '../../../../common/constants'; +import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; +import { AgentsWelcome } from '../../common/welcome/agents-welcome'; +import { Agent } from '../types'; +import { getAngularModule, getDataPlugin } from '../../../kibana-services'; +import { MainSyscollector } from '../../agents/syscollector/main'; +import { MainAgentStats } from '../../agents/stats'; +import WzManagementConfiguration from '../../../controllers/management/components/management/configuration/configuration-main.js'; +import { getAgentsService } from '../services'; +import { ShareAgent } from '../../../factories/share-agent'; +import { FilterHandler } from '../../../utils/filter-handler'; +import { AppState } from '../../../react-services'; +import { TabVisualizations } from '../../../factories/tab-visualizations'; +import store from '../../../redux/store'; +import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; + +export const AgentView = () => { + AppState.removeSessionStorageItem('configSubTab'); + + const $injector = getAngularModule().$injector; + + const router = $injector.get('$route'); + const location = $injector.get('$location'); + const commonData = $injector.get('commonData'); + const visFactoryService = $injector.get('visFactoryService'); + const reportingService = $injector.get('reportingService'); + + const shareAgent = new ShareAgent(); + + const tabVisualizations = new TabVisualizations(); + + const { agent: agentId } = router.current.params; + + const [agent, setAgent] = useState(); + const [isLoadingAgent, setIsLoadingAgent] = useState(true); + const [tab, setTab] = useState('welcome'); + const [tabview, setTabview] = useState(); + + const init = async () => { + const savedTimefilter = commonData.getTimefilter(); + if (savedTimefilter) { + getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); + commonData.removeTimefilter(); + } + + location.search('_a', null); + const filterHandler = new FilterHandler(AppState.getCurrentPattern()); + + visFactoryService.clearAll(); + + // Getting possible target location + const targetLocation = shareAgent.getTargetLocation(); + + setTabview(targetLocation?.tabview || commonData.checkTabViewLocation()); + setTab(targetLocation?.tab || commonData.checkTabLocation()); + + //TODO: Investigate + // this.tabHistory = []; + // if (!this.ignoredTabs.includes(this.$scope.tab)) + // this.tabHistory.push(this.$scope.tab); + + tabVisualizations.assign('agents'); + + await getAgent(); + }; + + const getAgent = async () => { + try { + setIsLoadingAgent(true); + + const globalAgent = new ShareAgent().getAgent(); + const id = commonData.checkLocationAgentId(agentId, globalAgent); + + if (!id) { + return; + } + + const { affected_items } = await getAgentsService({ + agents: [agentId], + }); + if (!affected_items?.length) { + throw 'Not found'; + } + + const agent = affected_items[0]; + setAgent(agent); + store.dispatch(updateCurrentAgentData(agent)); + } catch (error) { + const options = { + context: `AgentView.getAgent`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.CRITICAL, + store: true, + error: { + error, + message: error.message || error, + title: `Error getting the agent: ${error.message || error}`, + }, + }; + getErrorOrchestrator().handleError(options); + } finally { + setIsLoadingAgent(false); + } + }; + + const goGroup = (agent, group) => { + shareAgent.setAgent(agent, group); + location.path('/manager/groups'); + }; + + const exportConfiguration = enabledComponents => { + reportingService.startConfigReport(agent, 'agentConfig', enabledComponents); + }; + + useEffect(() => { + init(); + return () => { + visFactoryService.clearAll(); + }; + }, []); + + const switchTab = async (tab: string, force = false) => { + const timefilter = getDataPlugin().query.timefilter.timefilter; + setTab(tab); + // this.$rootScope.rendered = false; + // this.$rootScope.$applyAsync(); + // this.falseAllExpand(); + // if (this.ignoredTabs.includes(tab)) { + // this.commonData.setRefreshInterval(timefilter.getRefreshInterval()); + // timefilter.setRefreshInterval({ + // pause: true, + // value: 0, + // }); + // } else if (this.ignoredTabs.includes(this.$scope.tab)) { + // timefilter.setRefreshInterval(this.commonData.getRefreshInterval()); + // } + // // Update agent status + // if (!force && this.$scope.agent) { + // try { + // const agentInfo = await WzRequest.apiReq('GET', '/agents', { + // params: { + // agents_list: this.$scope.agent.id, + // select: 'status', + // }, + // }); + // this.$scope.agent.status = + // agentInfo?.data?.data?.affected_items?.[0]?.status || + // this.$scope.agent.status; + // this.$scope.$applyAsync(); + // } catch (error) { + // throw new Error(error); + // } + // } + // try { + // if (tab === 'configuration') { + // this.$scope.switchConfigurationTab('welcome'); + // } else { + // this.configurationHandler.reset(this.$scope); + // } + // if (!this.ignoredTabs.includes(tab)) this.tabHistory.push(tab); + // if (this.tabHistory.length > 2) + // this.tabHistory = this.tabHistory.slice(-2); + // if (this.$scope.tab === tab && !force) { + // this.$scope.$applyAsync(); + // return; + // } + // const onlyAgent = this.$scope.tab === tab && force; + // const sameTab = this.$scope.tab === tab; + // this.$location.search('tab', tab); + // const preserveDiscover = + // this.tabHistory.length === 2 && + // this.tabHistory[0] === this.tabHistory[1] && + // !force; + // this.$scope.tab = tab; + // const targetSubTab = + // this.targetLocation && typeof this.targetLocation === 'object' + // ? this.targetLocation.subTab + // : 'panels'; + // if (!this.ignoredTabs.includes(this.$scope.tab)) { + // this.$scope.switchSubtab( + // targetSubTab, + // true, + // onlyAgent, + // sameTab, + // preserveDiscover, + // ); + // } + // this.shareAgent.deleteTargetLocation(); + // this.targetLocation = null; + // this.$scope.$applyAsync(); + // } catch (error) { + // const options = { + // context: `${AgentsController.name}.switchTab`, + // level: UI_LOGGER_LEVELS.ERROR, + // severity: UI_ERROR_SEVERITIES.CRITICAL, + // store: true, + // error: { + // error: error, + // message: error.message || error, + // title: error.message || error, + // }, + // }; + // getErrorOrchestrator().handleError(options); + // } + // this.$scope.configurationTabsProps = {}; + // this.$scope.buildProps = tabs => { + // const cleanTabs = []; + // tabs.forEach(x => { + // if ( + // this.$scope.configurationTab === 'integrity-monitoring' && + // x.id === 'fim-whodata' && + // x.agent && + // x.agent.agentPlatform !== 'linux' + // ) + // return; + // cleanTabs.push({ + // id: x.id, + // name: x.name, + // }); + // }); + // this.$scope.configurationTabsProps = { + // clickAction: tab => { + // this.$scope.switchConfigurationSubTab(tab); + // }, + // selectedTab: + // this.$scope.configurationSubTab || (tabs && tabs.length) + // ? tabs[0].id + // : '', + // tabs: cleanTabs, + // }; + // }; + }; + + // if (error) { + // const options = { + // context: `AgentView.getAgent`, + // level: UI_LOGGER_LEVELS.ERROR, + // severity: UI_ERROR_SEVERITIES.CRITICAL, + // store: true, + // error: { + // error, + // message: error.message || error, + // title: `Could not get agent`, + // }, + // }; + // getErrorOrchestrator().handleError(options); + // } + + if (isLoadingAgent) { + return ( + + + + + + ); + } + + if (tab === 'welcome') { + return ; + } + + if (tab === 'syscollector' && agent) { + return ; + } + + if (tab === 'stats' && agent) { + return ; + } + + if (tab === 'configuration' && agent) { + return ( + + ); + } +}; diff --git a/plugins/main/public/components/endpoints-summary/services/get-agents.tsx b/plugins/main/public/components/endpoints-summary/services/get-agents.tsx index ebe67f445e..5040a34335 100644 --- a/plugins/main/public/components/endpoints-summary/services/get-agents.tsx +++ b/plugins/main/public/components/endpoints-summary/services/get-agents.tsx @@ -4,11 +4,13 @@ import { Agent } from '../types'; export const getAgentsService = async ({ filters, + agents, limit, offset, pageSize = 1000, }: { - filters: any; + filters?: any; + agents?: string[]; limit?: number; offset?: number; pageSize?: number; @@ -27,7 +29,8 @@ export const getAgentsService = async ({ params: { limit: queryLimit, offset: queryOffset, - q: filters, + ...(agents?.length ? { agents_list: agents?.join(',') } : {}), + ...(filters ? { q: filters } : {}), wait_for_complete: true, }, })) as IApiResponse; diff --git a/plugins/main/public/controllers/agent/index.js b/plugins/main/public/controllers/agent/index.js index 960ac79295..06afcac098 100644 --- a/plugins/main/public/controllers/agent/index.js +++ b/plugins/main/public/controllers/agent/index.js @@ -20,6 +20,7 @@ import { MainSyscollector } from '../../components/agents/syscollector/main'; import { MainAgentStats } from '../../components/agents/stats'; import { getAngularModule } from '../../kibana-services'; import { MainEndpointsSummary } from '../../components/endpoints-summary'; +import { AgentView } from '../../components/endpoints-summary/agent'; const app = getAngularModule(); @@ -28,6 +29,7 @@ app .value('RegisterAgent', RegisterAgent) .value('ExportConfiguration', ExportConfiguration) .value('AgentsWelcome', AgentsWelcome) + .value('AgentView', AgentView) .value('Mitre', Mitre) .value('AgentsTable', AgentsTable) .value('MainSyscollector', MainSyscollector) diff --git a/plugins/main/public/services/routes.js b/plugins/main/public/services/routes.js index 06107272ca..e9f87269e8 100644 --- a/plugins/main/public/services/routes.js +++ b/plugins/main/public/services/routes.js @@ -20,6 +20,7 @@ import { settingsWizard, getSavedSearch, getIp, getWzConfig } from './resolves'; // HTML templates import healthCheckTemplate from '../templates/health-check/health-check.html'; import agentsTemplate from '../templates/agents/dashboards.html'; +// import agentsTemplate from '../templates/agents/dashboards copy.html'; import agentDeployTemplate from '../templates/agents/deploy/agent-deploy.html'; import agentsPrevTemplate from '../templates/agents-prev/agents-prev.html'; import managementTemplate from '../templates/management/management.html'; diff --git a/plugins/main/public/templates/agents/dashboards copy.html b/plugins/main/public/templates/agents/dashboards copy.html new file mode 100644 index 0000000000..33fe5c8c5e --- /dev/null +++ b/plugins/main/public/templates/agents/dashboards copy.html @@ -0,0 +1,138 @@ + +
+
+ +
+ + + +
+
+
+ +
+
+
+ + +
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+ + +
+
+
+ + + + + + +
+
{{loadingStatus}}
+
+
+ + +
+
+
+ + + + + + +
+
{{reportStatus}}
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+ + +
+ +
+ + +
+ +
+ + +
diff --git a/plugins/main/public/templates/agents/dashboards.html b/plugins/main/public/templates/agents/dashboards.html index 33fe5c8c5e..93330667b7 100644 --- a/plugins/main/public/templates/agents/dashboards.html +++ b/plugins/main/public/templates/agents/dashboards.html @@ -1,138 +1 @@ - -
-
- -
- - - -
-
-
- -
-
-
- - -
-
- -
-
-
-
- -
-
-
- -
- -
- - -
-
-
- - - - - - -
-
{{loadingStatus}}
-
-
- - -
-
-
- - - - - - -
-
{{reportStatus}}
-
-
-
- -
- -
- - -
-
- -
-
-
- - -
- -
- - -
- -
- - -
+ From d6f1860414c3d3b6b62d3cb9e76af4f269b61d2f Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Mon, 22 Apr 2024 15:23:11 -0300 Subject: [PATCH 02/12] Replace Kibana visualization --- .../components/common/welcome/EventsCount.tsx | 90 ++++++++ .../common/welcome/agents-welcome.js | 40 +--- .../welcome/dashboard/dashboard_panels.ts | 138 +++++++++++++ .../visualizations/agents/agents-welcome.ts | 192 +++++++----------- 4 files changed, 308 insertions(+), 152 deletions(-) create mode 100644 plugins/main/public/components/common/welcome/EventsCount.tsx create mode 100644 plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts diff --git a/plugins/main/public/components/common/welcome/EventsCount.tsx b/plugins/main/public/components/common/welcome/EventsCount.tsx new file mode 100644 index 0000000000..4a49e0efd4 --- /dev/null +++ b/plugins/main/public/components/common/welcome/EventsCount.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { AlertsDataSource } from '../data-source/pattern/alerts/alerts-data-source'; +import { AlertsDataSourceRepository } from '../data-source/pattern/alerts/alerts-data-source-repository'; +import { getPlugins } from '../../../kibana-services'; +import { getDashboardPanels } from './dashboard/dashboard_panels'; +import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; +import { useDataSource } from '../data-source/hooks'; +import { PatternDataSource, tParsedIndexPattern } from '../data-source'; +import { + EuiPanel, + EuiFlexItem, + EuiFlexGroup, + EuiSpacer, + EuiText, + EuiLoadingChart, +} from '@elastic/eui'; +import WzReduxProvider from '../../../redux/wz-redux-provider'; +import useSearchBar from '../search-bar/use-search-bar'; + +const plugins = getPlugins(); +const DashboardByRenderer = plugins.dashboard.DashboardContainerByValueRenderer; + +export const EventsCount = () => { + const { dataSource, fetchFilters, isLoading } = useDataSource< + tParsedIndexPattern, + PatternDataSource + >({ + DataSource: AlertsDataSource, + repository: new AlertsDataSourceRepository(), + }); + + const { searchBarProps } = useSearchBar({ + indexPattern: dataSource?.indexPattern as any, + }); + + return ( + + + + +

+ +

Events count evolution

+
+

+
+
+ + {!isLoading && dataSource && ( + + + + )} + {/* +
+ +
*/} +
+
+ ); +}; diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 956ee54b08..23a098bb20 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -80,6 +80,7 @@ import { malwareDetection, } from '../../../utils/applications'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; +import { EventsCount } from './EventsCount'; const mapStateToProps = state => ({ agent: state.appStateReducers.currentAgentData, @@ -570,44 +571,7 @@ export const AgentsWelcome = compose( } renderEventCountVisualization() { - return ( - - - - -

- -

Events count evolution

-
-

-
-
- -
- - - -
-
- -
-
-
- ); + return ; } renderSCALastScan() { diff --git a/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts b/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts new file mode 100644 index 0000000000..6da5f83ef7 --- /dev/null +++ b/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts @@ -0,0 +1,138 @@ +import { DashboardPanelState } from '../../../../../../../src/plugins/dashboard/public/application'; +import { EmbeddableInput } from '../../../../../../../src/plugins/embeddable/public'; + +const getVisStateEventsCountEvolution = (indexPatternId: string) => ({ + id: 'App-Agents-Welcome-Events-Evolution', + title: 'Events count evolution', + type: 'line', + params: { + type: 'line', + grid: { categoryLines: false }, + categoryAxes: [ + { + id: 'CategoryAxis-1', + type: 'category', + position: 'bottom', + show: true, + style: {}, + scale: { type: 'linear' }, + labels: { show: true, filter: true, truncate: 100 }, + title: {}, + }, + ], + valueAxes: [ + { + id: 'ValueAxis-1', + name: 'LeftAxis-1', + type: 'value', + position: 'left', + show: true, + style: {}, + scale: { type: 'linear', mode: 'normal' }, + labels: { show: true, rotate: 0, filter: false, truncate: 100 }, + title: { text: 'Count' }, + }, + ], + seriesParams: [ + { + show: true, + type: 'line', + mode: 'normal', + data: { label: 'Count', id: '1' }, + valueAxis: 'ValueAxis-1', + drawLinesBetweenPoints: true, + lineWidth: 2, + interpolate: 'linear', + showCircles: true, + }, + ], + addTooltip: true, + addLegend: false, + legendPosition: 'right', + times: [], + addTimeMarker: false, + labels: {}, + thresholdLine: { + show: false, + value: 10, + width: 1, + style: 'full', + color: '#E7664C', + }, + dimensions: { + x: null, + y: [ + { + accessor: 0, + format: { id: 'number' }, + params: {}, + label: 'Count', + aggType: 'count', + }, + ], + }, + }, + uiState: { + vis: { params: { sort: { columnIndex: 2, direction: 'desc' } } }, + }, + data: { + searchSource: { + query: { + language: 'kuery', + query: '', + }, + filter: [], + index: indexPatternId, + }, + references: [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: indexPatternId, + }, + ], + aggs: [ + { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '2', + enabled: true, + type: 'date_histogram', + schema: 'segment', + params: { + field: 'timestamp', + useNormalizedEsInterval: true, + scaleMetricValues: false, + interval: 'auto', + drop_partials: false, + min_doc_count: 1, + extended_bounds: {}, + }, + }, + ], + }, +}); + +export const getDashboardPanels = ( + indexPatternId: string, +): { + [panelId: string]: DashboardPanelState< + EmbeddableInput & { [k: string]: unknown } + >; +} => { + return { + '1': { + gridData: { + w: 48, + h: 12, + x: 0, + y: 0, + i: '1', + }, + type: 'visualization', + explicitInput: { + id: '1', + savedVis: getVisStateEventsCountEvolution(indexPatternId), + }, + }, + }; +}; diff --git a/plugins/main/server/integration-files/visualizations/agents/agents-welcome.ts b/plugins/main/server/integration-files/visualizations/agents/agents-welcome.ts index 27db0c5f70..20e62748bd 100644 --- a/plugins/main/server/integration-files/visualizations/agents/agents-welcome.ts +++ b/plugins/main/server/integration-files/visualizations/agents/agents-welcome.ts @@ -24,7 +24,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -57,7 +62,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -105,7 +116,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -138,7 +154,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -186,7 +208,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -219,7 +246,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -267,7 +300,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -300,7 +338,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -348,7 +392,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -381,7 +430,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -429,7 +484,12 @@ export default [ addLegend: true, legendPosition: 'right', isDonut: true, - labels: { show: false, values: true, last_level: true, truncate: 100 }, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, dimensions: { metric: { accessor: 1, @@ -462,7 +522,13 @@ export default [ }, }, aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, + { + id: '1', + enabled: true, + type: 'count', + schema: 'metric', + params: {}, + }, { id: '2', enabled: true, @@ -496,106 +562,4 @@ export default [ }, }, }, - { - _id: 'Wazuh-App-Agents-Welcome-Events-Evolution', - _type: 'visualization', - _source: { - title: 'Events evolution', - visState: JSON.stringify({ - title: 'event evolution', - type: 'line', - params: { - type: 'line', - grid: { categoryLines: false }, - categoryAxes: [ - { - id: 'CategoryAxis-1', - type: 'category', - position: 'bottom', - show: true, - style: {}, - scale: { type: 'linear' }, - labels: { show: true, filter: true, truncate: 100 }, - title: {}, - }, - ], - valueAxes: [ - { - id: 'ValueAxis-1', - name: 'LeftAxis-1', - type: 'value', - position: 'left', - show: true, - style: {}, - scale: { type: 'linear', mode: 'normal' }, - labels: { show: true, rotate: 0, filter: false, truncate: 100 }, - title: { text: 'Count' }, - }, - ], - seriesParams: [ - { - show: true, - type: 'line', - mode: 'normal', - data: { label: 'Count', id: '1' }, - valueAxis: 'ValueAxis-1', - drawLinesBetweenPoints: true, - lineWidth: 2, - interpolate: 'linear', - showCircles: true, - }, - ], - addTooltip: true, - addLegend: false, - legendPosition: 'right', - times: [], - addTimeMarker: false, - labels: {}, - thresholdLine: { show: false, value: 10, width: 1, style: 'full', color: '#E7664C' }, - dimensions: { - x: null, - y: [ - { - accessor: 0, - format: { id: 'number' }, - params: {}, - label: 'Count', - aggType: 'count', - }, - ], - }, - }, - aggs: [ - { id: '1', enabled: true, type: 'count', schema: 'metric', params: {} }, - { - id: '2', - enabled: true, - type: 'date_histogram', - schema: 'segment', - params: { - field: 'timestamp', - useNormalizedEsInterval: true, - scaleMetricValues: false, - interval: 'auto', - drop_partials: false, - min_doc_count: 1, - extended_bounds: {}, - }, - }, - ], - }), - uiStateJSON: JSON.stringify({ - vis: { params: { sort: { columnIndex: 2, direction: 'desc' } } }, - }), - description: '', - version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'wazuh-alerts', - query: { query: '', language: 'lucene' }, - filter: [], - }), - }, - }, - }, ]; From 6974fa26d103a82398d5cb04a0ef539317848b43 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Mon, 22 Apr 2024 17:56:19 -0300 Subject: [PATCH 03/12] Improve Events count evolution chart --- .../common/welcome/agents-welcome.js | 2 +- .../events-count.tsx} | 43 ++--- .../endpoints-summary/agent/index.tsx | 173 ++++++++++-------- 3 files changed, 111 insertions(+), 107 deletions(-) rename plugins/main/public/components/common/welcome/{EventsCount.tsx => dashboard/events-count.tsx} (58%) diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 23a098bb20..2d26e716fc 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -80,7 +80,7 @@ import { malwareDetection, } from '../../../utils/applications'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { EventsCount } from './EventsCount'; +import { EventsCount } from './dashboard/events-count'; const mapStateToProps = state => ({ agent: state.appStateReducers.currentAgentData, diff --git a/plugins/main/public/components/common/welcome/EventsCount.tsx b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx similarity index 58% rename from plugins/main/public/components/common/welcome/EventsCount.tsx rename to plugins/main/public/components/common/welcome/dashboard/events-count.tsx index 4a49e0efd4..48aa201619 100644 --- a/plugins/main/public/components/common/welcome/EventsCount.tsx +++ b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx @@ -1,21 +1,21 @@ import React from 'react'; -import { AlertsDataSource } from '../data-source/pattern/alerts/alerts-data-source'; -import { AlertsDataSourceRepository } from '../data-source/pattern/alerts/alerts-data-source-repository'; -import { getPlugins } from '../../../kibana-services'; -import { getDashboardPanels } from './dashboard/dashboard_panels'; -import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; -import { useDataSource } from '../data-source/hooks'; -import { PatternDataSource, tParsedIndexPattern } from '../data-source'; +import { AlertsDataSource } from '../../data-source/pattern/alerts/alerts-data-source'; +import { AlertsDataSourceRepository } from '../../data-source/pattern/alerts/alerts-data-source-repository'; +import { getPlugins } from '../../../../kibana-services'; +import { getDashboardPanels } from './dashboard_panels'; +import { ViewMode } from '../../../../../../../src/plugins/embeddable/public'; +import { useDataSource } from '../../data-source/hooks'; +import { PatternDataSource, tParsedIndexPattern } from '../../data-source'; import { EuiPanel, EuiFlexItem, EuiFlexGroup, EuiSpacer, EuiText, - EuiLoadingChart, } from '@elastic/eui'; -import WzReduxProvider from '../../../redux/wz-redux-provider'; -import useSearchBar from '../search-bar/use-search-bar'; +import WzReduxProvider from '../../../../redux/wz-redux-provider'; +import { useTimeFilter } from '../../hooks'; +import { LoadingSpinner } from '../../loading-spinner/loading-spinner'; const plugins = getPlugins(); const DashboardByRenderer = plugins.dashboard.DashboardContainerByValueRenderer; @@ -29,9 +29,7 @@ export const EventsCount = () => { repository: new AlertsDataSourceRepository(), }); - const { searchBarProps } = useSearchBar({ - indexPattern: dataSource?.indexPattern as any, - }); + const { timeFilter } = useTimeFilter(); return ( @@ -46,7 +44,7 @@ export const EventsCount = () => { - {!isLoading && dataSource && ( + {!isLoading && dataSource ? ( { useMargins: true, id: 'agent-events-count-evolution', timeRange: { - from: searchBarProps.dateRangeFrom, - to: searchBarProps.dateRangeTo, + from: timeFilter.from, + to: timeFilter.to, }, title: 'Events count evolution', description: 'Dashboard of Events count evolution', @@ -72,18 +70,9 @@ export const EventsCount = () => { }} /> + ) : ( + )} - {/* -
- -
*/}
); diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index 29e81c7681..cd522a478a 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -12,7 +12,7 @@ import WzManagementConfiguration from '../../../controllers/management/component import { getAgentsService } from '../services'; import { ShareAgent } from '../../../factories/share-agent'; import { FilterHandler } from '../../../utils/filter-handler'; -import { AppState } from '../../../react-services'; +import { AppState, WzRequest } from '../../../react-services'; import { TabVisualizations } from '../../../factories/tab-visualizations'; import store from '../../../redux/store'; import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; @@ -34,6 +34,8 @@ export const AgentView = () => { const { agent: agentId } = router.current.params; + const ignoredTabs = ['syscollector', 'welcome', 'configuration', 'stats']; + const [agent, setAgent] = useState(); const [isLoadingAgent, setIsLoadingAgent] = useState(true); const [tab, setTab] = useState('welcome'); @@ -124,87 +126,97 @@ export const AgentView = () => { const switchTab = async (tab: string, force = false) => { const timefilter = getDataPlugin().query.timefilter.timefilter; - setTab(tab); + tabVisualizations.setTab(tab); // this.$rootScope.rendered = false; // this.$rootScope.$applyAsync(); // this.falseAllExpand(); - // if (this.ignoredTabs.includes(tab)) { - // this.commonData.setRefreshInterval(timefilter.getRefreshInterval()); - // timefilter.setRefreshInterval({ - // pause: true, - // value: 0, - // }); - // } else if (this.ignoredTabs.includes(this.$scope.tab)) { - // timefilter.setRefreshInterval(this.commonData.getRefreshInterval()); - // } - // // Update agent status - // if (!force && this.$scope.agent) { - // try { - // const agentInfo = await WzRequest.apiReq('GET', '/agents', { - // params: { - // agents_list: this.$scope.agent.id, - // select: 'status', - // }, - // }); - // this.$scope.agent.status = - // agentInfo?.data?.data?.affected_items?.[0]?.status || - // this.$scope.agent.status; - // this.$scope.$applyAsync(); - // } catch (error) { - // throw new Error(error); - // } - // } - // try { - // if (tab === 'configuration') { - // this.$scope.switchConfigurationTab('welcome'); - // } else { - // this.configurationHandler.reset(this.$scope); - // } - // if (!this.ignoredTabs.includes(tab)) this.tabHistory.push(tab); - // if (this.tabHistory.length > 2) - // this.tabHistory = this.tabHistory.slice(-2); - // if (this.$scope.tab === tab && !force) { - // this.$scope.$applyAsync(); - // return; - // } - // const onlyAgent = this.$scope.tab === tab && force; - // const sameTab = this.$scope.tab === tab; - // this.$location.search('tab', tab); - // const preserveDiscover = - // this.tabHistory.length === 2 && - // this.tabHistory[0] === this.tabHistory[1] && - // !force; - // this.$scope.tab = tab; - // const targetSubTab = - // this.targetLocation && typeof this.targetLocation === 'object' - // ? this.targetLocation.subTab - // : 'panels'; - // if (!this.ignoredTabs.includes(this.$scope.tab)) { - // this.$scope.switchSubtab( - // targetSubTab, - // true, - // onlyAgent, - // sameTab, - // preserveDiscover, - // ); - // } - // this.shareAgent.deleteTargetLocation(); - // this.targetLocation = null; - // this.$scope.$applyAsync(); - // } catch (error) { - // const options = { - // context: `${AgentsController.name}.switchTab`, - // level: UI_LOGGER_LEVELS.ERROR, - // severity: UI_ERROR_SEVERITIES.CRITICAL, - // store: true, - // error: { - // error: error, - // message: error.message || error, - // title: error.message || error, - // }, - // }; - // getErrorOrchestrator().handleError(options); - // } + if (ignoredTabs.includes(tab)) { + commonData.setRefreshInterval(timefilter.getRefreshInterval()); + timefilter.setRefreshInterval({ + pause: true, + value: 0, + }); + } else if (ignoredTabs.includes(tab)) { + timefilter.setRefreshInterval(commonData.getRefreshInterval()); + } + + // Update agent status + if (!force && agent) { + try { + const agentInfo = await WzRequest.apiReq('GET', '/agents', { + params: { + agents_list: agent.id, + select: 'status', + }, + }); + setAgent(agentInfo?.data?.data?.affected_items?.[0]); + + // this.$scope.$applyAsync(); + } catch (error) { + throw new Error(error); + } + } + + try { + if (tab === 'configuration') { + // this.$scope.switchConfigurationTab('welcome'); + } else { + // this.configurationHandler.reset(this.$scope); + } + + if (!ignoredTabs.includes(tab)) { + // this.tabHistory.push(tab); + } + // if (this.tabHistory.length > 2) + // this.tabHistory = this.tabHistory.slice(-2); + + // if (this.$scope.tab === tab && !force) { + // this.$scope.$applyAsync(); + // return; + // } + + // const onlyAgent = this.$scope.tab === tab && force; + // const sameTab = this.$scope.tab === tab; + // this.$location.search('tab', tab); + // const preserveDiscover = + // this.tabHistory.length === 2 && + // this.tabHistory[0] === this.tabHistory[1] && + // !force; + // this.$scope.tab = tab; + + // const targetSubTab = + // this.targetLocation && typeof this.targetLocation === 'object' + // ? this.targetLocation.subTab + // : 'panels'; + + // if (!this.ignoredTabs.includes(this.$scope.tab)) { + // this.$scope.switchSubtab( + // targetSubTab, + // true, + // onlyAgent, + // sameTab, + // preserveDiscover, + // ); + // } + + // this.shareAgent.deleteTargetLocation(); + // this.targetLocation = null; + // this.$scope.$applyAsync(); + } catch (error) { + const options = { + context: `AgentView.switchTab`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.CRITICAL, + store: true, + error: { + error: error, + message: error.message || error, + title: error.message || error, + }, + }; + getErrorOrchestrator().handleError(options); + } + // this.$scope.configurationTabsProps = {}; // this.$scope.buildProps = tabs => { // const cleanTabs = []; @@ -216,6 +228,7 @@ export const AgentView = () => { // x.agent.agentPlatform !== 'linux' // ) // return; + // cleanTabs.push({ // id: x.id, // name: x.name, @@ -232,6 +245,8 @@ export const AgentView = () => { // tabs: cleanTabs, // }; // }; + + // this.setTabs(); }; // if (error) { From 039057cf9f4603a46873ef131b4358edcbb8f198 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Tue, 23 Apr 2024 14:02:58 -0300 Subject: [PATCH 04/12] Fix Dashboard embeddable --- .../pattern-data-source-filter-manager.ts | 2 +- .../welcome/dashboard/dashboard_panels.ts | 1 - .../common/welcome/dashboard/events-count.tsx | 59 +++++++++---------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/plugins/main/public/components/common/data-source/pattern/pattern-data-source-filter-manager.ts b/plugins/main/public/components/common/data-source/pattern/pattern-data-source-filter-manager.ts index 2fe50d2721..01cae2cfac 100644 --- a/plugins/main/public/components/common/data-source/pattern/pattern-data-source-filter-manager.ts +++ b/plugins/main/public/components/common/data-source/pattern/pattern-data-source-filter-manager.ts @@ -257,7 +257,7 @@ export class PatternDataSourceFilterManager isCluster ? AppState.getClusterInfo().cluster : AppState.getClusterInfo().manager, - true, + isCluster, key, ); managerFilter.meta = { diff --git a/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts b/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts index 6da5f83ef7..7d250e7d05 100644 --- a/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts +++ b/plugins/main/public/components/common/welcome/dashboard/dashboard_panels.ts @@ -81,7 +81,6 @@ const getVisStateEventsCountEvolution = (indexPatternId: string) => ({ language: 'kuery', query: '', }, - filter: [], index: indexPatternId, }, references: [ diff --git a/plugins/main/public/components/common/welcome/dashboard/events-count.tsx b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx index 48aa201619..e88da5a930 100644 --- a/plugins/main/public/components/common/welcome/dashboard/events-count.tsx +++ b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx @@ -13,7 +13,6 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import WzReduxProvider from '../../../../redux/wz-redux-provider'; import { useTimeFilter } from '../../hooks'; import { LoadingSpinner } from '../../loading-spinner/loading-spinner'; @@ -21,10 +20,11 @@ const plugins = getPlugins(); const DashboardByRenderer = plugins.dashboard.DashboardContainerByValueRenderer; export const EventsCount = () => { - const { dataSource, fetchFilters, isLoading } = useDataSource< - tParsedIndexPattern, - PatternDataSource - >({ + const { + dataSource, + fetchFilters, + isLoading: isDataSourceLoading, + } = useDataSource({ DataSource: AlertsDataSource, repository: new AlertsDataSourceRepository(), }); @@ -44,32 +44,29 @@ export const EventsCount = () => { - {!isLoading && dataSource ? ( - - - + {!isDataSourceLoading && dataSource ? ( + ) : ( )} From c0db1afd3486f7fc5c24dd3af076bd7b1e1b2011 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Wed, 24 Apr 2024 17:26:03 -0300 Subject: [PATCH 05/12] Fix url update when change tab --- .../common/welcome/agents-welcome.js | 17 +- .../common/welcome/dashboard/events-count.tsx | 1 - .../endpoints-summary/agent/index.tsx | 220 +++--------------- 3 files changed, 38 insertions(+), 200 deletions(-) diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 2d26e716fc..d0795f81cb 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -22,7 +22,6 @@ import { EuiButtonEmpty, EuiPage, EuiPopover, - EuiLoadingChart, EuiToolTip, EuiButtonIcon, EuiPageBody, @@ -39,7 +38,6 @@ import WzReduxProvider from '../../../redux/wz-redux-provider'; import MenuAgent from './components/menu-agent'; import './welcome.scss'; import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker'; -import KibanaVis from '../../../kibana-integrations/kibana-vis'; import { VisFactoryHandler } from '../../../react-services/vis-factory-handler'; import { AppState } from '../../../react-services/app-state'; import { FilterHandler } from '../../../utils/filter-handler'; @@ -356,7 +354,6 @@ export const AgentsWelcome = compose( closePopover={() => { this.setState({ switchModule: false }); }} - switchTab={module => this.props.switchTab(module)} > @@ -368,7 +365,6 @@ export const AgentsWelcome = compose( } renderTitle() { - const notNeedStatus = true; const thereAreAgentSelected = Boolean(this.props.agent?.id); // Calculate if the header buttons should display the name or only the icon to be responsive @@ -413,7 +409,6 @@ export const AgentsWelcome = compose( closePopover={() => { this.setState({ switchModule: false }); }} - switchTab={module => this.props.switchTab(module)} > @@ -462,9 +457,7 @@ export const AgentsWelcome = compose( - this.props.switchTab('syscollector', notNeedStatus) - } + onClick={() => this.props.switchTab('syscollector')} className='wz-it-hygiene-header-button' tooltip={ this.state.maxModules === null @@ -479,7 +472,7 @@ export const AgentsWelcome = compose( this.props.switchTab('stats', notNeedStatus)} + onClick={() => this.props.switchTab('stats')} className='wz-it-hygiene-header-button' tooltip={ this.state.maxModules === null @@ -494,9 +487,7 @@ export const AgentsWelcome = compose( - this.props.switchTab('configuration', notNeedStatus) - } + onClick={() => this.props.switchTab('configuration')} className='wz-it-hygiene-header-button' tooltip={ this.state.maxModules === null @@ -577,7 +568,7 @@ export const AgentsWelcome = compose( renderSCALastScan() { return ( - + ); } diff --git a/plugins/main/public/components/common/welcome/dashboard/events-count.tsx b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx index e88da5a930..e41f399a5f 100644 --- a/plugins/main/public/components/common/welcome/dashboard/events-count.tsx +++ b/plugins/main/public/components/common/welcome/dashboard/events-count.tsx @@ -59,7 +59,6 @@ export const EventsCount = () => { }, title: 'Events count evolution', description: 'Dashboard of Events count evolution', - // query: {}, refreshConfig: { pause: false, value: 15, diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index cd522a478a..505e2cf633 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -5,66 +5,50 @@ import { UI_LOGGER_LEVELS } from '../../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; import { AgentsWelcome } from '../../common/welcome/agents-welcome'; import { Agent } from '../types'; -import { getAngularModule, getDataPlugin } from '../../../kibana-services'; +import { + getAngularModule, + getCore, + getDataPlugin, +} from '../../../kibana-services'; import { MainSyscollector } from '../../agents/syscollector/main'; import { MainAgentStats } from '../../agents/stats'; import WzManagementConfiguration from '../../../controllers/management/components/management/configuration/configuration-main.js'; import { getAgentsService } from '../services'; import { ShareAgent } from '../../../factories/share-agent'; -import { FilterHandler } from '../../../utils/filter-handler'; -import { AppState, WzRequest } from '../../../react-services'; -import { TabVisualizations } from '../../../factories/tab-visualizations'; +import { AppState } from '../../../react-services'; import store from '../../../redux/store'; import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; +import { endpointSummary } from '../../../utils/applications'; export const AgentView = () => { AppState.removeSessionStorageItem('configSubTab'); const $injector = getAngularModule().$injector; - const router = $injector.get('$route'); - const location = $injector.get('$location'); - const commonData = $injector.get('commonData'); - const visFactoryService = $injector.get('visFactoryService'); - const reportingService = $injector.get('reportingService'); + const $router = $injector.get('$route'); + const $commonData = $injector.get('commonData'); + const $reportingService = $injector.get('reportingService'); const shareAgent = new ShareAgent(); - const tabVisualizations = new TabVisualizations(); + const targetLocation = shareAgent.getTargetLocation(); + // const ignoreTabs = ['syscollector', 'welcome', 'configuration', 'stats']; - const { agent: agentId } = router.current.params; - - const ignoredTabs = ['syscollector', 'welcome', 'configuration', 'stats']; + const { agent: agentId } = $router.current.params; const [agent, setAgent] = useState(); const [isLoadingAgent, setIsLoadingAgent] = useState(true); - const [tab, setTab] = useState('welcome'); - const [tabview, setTabview] = useState(); + const [tab, setTab] = useState(); + // const [tabHistory, setTabHistory] = useState([]); const init = async () => { - const savedTimefilter = commonData.getTimefilter(); + const savedTimefilter = $commonData.getTimefilter(); if (savedTimefilter) { getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); - commonData.removeTimefilter(); + $commonData.removeTimefilter(); } - location.search('_a', null); - const filterHandler = new FilterHandler(AppState.getCurrentPattern()); - - visFactoryService.clearAll(); - - // Getting possible target location - const targetLocation = shareAgent.getTargetLocation(); - - setTabview(targetLocation?.tabview || commonData.checkTabViewLocation()); - setTab(targetLocation?.tab || commonData.checkTabLocation()); - - //TODO: Investigate - // this.tabHistory = []; - // if (!this.ignoredTabs.includes(this.$scope.tab)) - // this.tabHistory.push(this.$scope.tab); - - tabVisualizations.assign('agents'); + setTab(targetLocation?.tab || $commonData.checkTabLocation()); await getAgent(); }; @@ -73,8 +57,10 @@ export const AgentView = () => { try { setIsLoadingAgent(true); - const globalAgent = new ShareAgent().getAgent(); - const id = commonData.checkLocationAgentId(agentId, globalAgent); + const id = $commonData.checkLocationAgentId( + agentId, + shareAgent.getAgent(), + ); if (!id) { return; @@ -108,161 +94,24 @@ export const AgentView = () => { } }; - const goGroup = (agent, group) => { - shareAgent.setAgent(agent, group); - location.path('/manager/groups'); - }; - - const exportConfiguration = enabledComponents => { - reportingService.startConfigReport(agent, 'agentConfig', enabledComponents); - }; - useEffect(() => { init(); - return () => { - visFactoryService.clearAll(); - }; }, []); - const switchTab = async (tab: string, force = false) => { - const timefilter = getDataPlugin().query.timefilter.timefilter; - tabVisualizations.setTab(tab); - // this.$rootScope.rendered = false; - // this.$rootScope.$applyAsync(); - // this.falseAllExpand(); - if (ignoredTabs.includes(tab)) { - commonData.setRefreshInterval(timefilter.getRefreshInterval()); - timefilter.setRefreshInterval({ - pause: true, - value: 0, - }); - } else if (ignoredTabs.includes(tab)) { - timefilter.setRefreshInterval(commonData.getRefreshInterval()); - } - - // Update agent status - if (!force && agent) { - try { - const agentInfo = await WzRequest.apiReq('GET', '/agents', { - params: { - agents_list: agent.id, - select: 'status', - }, - }); - setAgent(agentInfo?.data?.data?.affected_items?.[0]); - - // this.$scope.$applyAsync(); - } catch (error) { - throw new Error(error); - } - } - - try { - if (tab === 'configuration') { - // this.$scope.switchConfigurationTab('welcome'); - } else { - // this.configurationHandler.reset(this.$scope); - } - - if (!ignoredTabs.includes(tab)) { - // this.tabHistory.push(tab); - } - // if (this.tabHistory.length > 2) - // this.tabHistory = this.tabHistory.slice(-2); - - // if (this.$scope.tab === tab && !force) { - // this.$scope.$applyAsync(); - // return; - // } - - // const onlyAgent = this.$scope.tab === tab && force; - // const sameTab = this.$scope.tab === tab; - // this.$location.search('tab', tab); - // const preserveDiscover = - // this.tabHistory.length === 2 && - // this.tabHistory[0] === this.tabHistory[1] && - // !force; - // this.$scope.tab = tab; - - // const targetSubTab = - // this.targetLocation && typeof this.targetLocation === 'object' - // ? this.targetLocation.subTab - // : 'panels'; - - // if (!this.ignoredTabs.includes(this.$scope.tab)) { - // this.$scope.switchSubtab( - // targetSubTab, - // true, - // onlyAgent, - // sameTab, - // preserveDiscover, - // ); - // } - - // this.shareAgent.deleteTargetLocation(); - // this.targetLocation = null; - // this.$scope.$applyAsync(); - } catch (error) { - const options = { - context: `AgentView.switchTab`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.CRITICAL, - store: true, - error: { - error: error, - message: error.message || error, - title: error.message || error, - }, - }; - getErrorOrchestrator().handleError(options); - } - - // this.$scope.configurationTabsProps = {}; - // this.$scope.buildProps = tabs => { - // const cleanTabs = []; - // tabs.forEach(x => { - // if ( - // this.$scope.configurationTab === 'integrity-monitoring' && - // x.id === 'fim-whodata' && - // x.agent && - // x.agent.agentPlatform !== 'linux' - // ) - // return; - - // cleanTabs.push({ - // id: x.id, - // name: x.name, - // }); - // }); - // this.$scope.configurationTabsProps = { - // clickAction: tab => { - // this.$scope.switchConfigurationSubTab(tab); - // }, - // selectedTab: - // this.$scope.configurationSubTab || (tabs && tabs.length) - // ? tabs[0].id - // : '', - // tabs: cleanTabs, - // }; - // }; - - // this.setTabs(); + const exportConfiguration = enabledComponents => { + $reportingService.startConfigReport( + agent, + 'agentConfig', + enabledComponents, + ); }; - // if (error) { - // const options = { - // context: `AgentView.getAgent`, - // level: UI_LOGGER_LEVELS.ERROR, - // severity: UI_ERROR_SEVERITIES.CRITICAL, - // store: true, - // error: { - // error, - // message: error.message || error, - // title: `Could not get agent`, - // }, - // }; - // getErrorOrchestrator().handleError(options); - // } + const switchTab = (tab: string) => { + setTab(tab); + getCore().application.navigateToApp(endpointSummary.id, { + path: `#/agents?tab=${tab}&agent=${agent?.id}`, + }); + }; if (isLoadingAgent) { return ( @@ -290,7 +139,6 @@ export const AgentView = () => { return ( ); From b59b5bd550ea73bd47c203b550c8555ed1988d8c Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Thu, 25 Apr 2024 10:25:40 -0300 Subject: [PATCH 06/12] Move file export-configuration --- .../components => components/agents}/export-configuration.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/main/public/{controllers/agent/components => components/agents}/export-configuration.js (100%) diff --git a/plugins/main/public/controllers/agent/components/export-configuration.js b/plugins/main/public/components/agents/export-configuration.js similarity index 100% rename from plugins/main/public/controllers/agent/components/export-configuration.js rename to plugins/main/public/components/agents/export-configuration.js From 6365751f3ae93799b3e9680bec219bf62bdc13c3 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Thu, 25 Apr 2024 11:31:13 -0300 Subject: [PATCH 07/12] Fix imports to move file export-configuration --- .../components/agents/export-configuration.js | 273 +++++++++--------- .../main/public/controllers/agent/index.js | 6 +- .../components/files-group-table.js | 52 ++-- .../configuration/configuration-overview.js | 2 +- .../groups/actions-buttons-agents.js | 2 +- .../groups/actions-buttons-files.js | 2 +- 6 files changed, 171 insertions(+), 166 deletions(-) diff --git a/plugins/main/public/components/agents/export-configuration.js b/plugins/main/public/components/agents/export-configuration.js index 0c3ee40f33..995a4d23bc 100644 --- a/plugins/main/public/components/agents/export-configuration.js +++ b/plugins/main/public/components/agents/export-configuration.js @@ -16,157 +16,166 @@ import { EuiButton, EuiCheckboxGroup, EuiSpacer, - EuiButtonEmpty + EuiButtonEmpty, } from '@elastic/eui'; import PropTypes from 'prop-types'; -import { UnsupportedComponents } from '../../../utils/components-os-support'; -import { WAZUH_AGENTS_OS_TYPE } from '../../../../common/constants'; -import { withErrorBoundary } from '../../../components/common/hocs'; +import { UnsupportedComponents } from '../../utils/components-os-support'; +import { WAZUH_AGENTS_OS_TYPE } from '../../../common/constants'; +import { withErrorBoundary } from '../common/hocs'; -export const ExportConfiguration = withErrorBoundary (class ExportConfiguration extends Component { - constructor(props) { - super(props); +export const ExportConfiguration = withErrorBoundary( + class ExportConfiguration extends Component { + constructor(props) { + super(props); - this.state = { - buttonDisabled: false, - isPopoverOpen: false - }; + this.state = { + buttonDisabled: false, + isPopoverOpen: false, + }; - const agentOptions = [ - 'Global configuration', - 'Communication', - 'Anti-flooding settings', - 'Labels', - 'Policy monitoring', - { name: 'oscap', desc: 'OpenSCAP' }, - 'CIS-CAT', - 'Osquery', - 'Inventory data', - 'Active response', - 'Commands', - { name: 'docker', desc: 'Docker listener' }, - 'Log collection', - 'Integrity monitoring' - ]; - const groupOptions = ['Configurations', 'Agents in group']; + const agentOptions = [ + 'Global configuration', + 'Communication', + 'Anti-flooding settings', + 'Labels', + 'Policy monitoring', + { name: 'oscap', desc: 'OpenSCAP' }, + 'CIS-CAT', + 'Osquery', + 'Inventory data', + 'Active response', + 'Commands', + { name: 'docker', desc: 'Docker listener' }, + 'Log collection', + 'Integrity monitoring', + ]; + const groupOptions = ['Configurations', 'Agents in group']; - this.options = []; - const list = this.props.type === 'agent' ? agentOptions : groupOptions; - list.forEach((x, idx) => { - if ( - typeof x === 'string' || - (x.name && - !( - UnsupportedComponents[this.props.agentPlatform] || - UnsupportedComponents[WAZUH_AGENTS_OS_TYPE.OTHERS] - ).includes(x.name)) - ) { - this.options.push({ id: `${idx}`, label: x.desc || x }); - } - }); + this.options = []; + const list = this.props.type === 'agent' ? agentOptions : groupOptions; + list.forEach((x, idx) => { + if ( + typeof x === 'string' || + (x.name && + !( + UnsupportedComponents[this.props.agentPlatform] || + UnsupportedComponents[WAZUH_AGENTS_OS_TYPE.OTHERS] + ).includes(x.name)) + ) { + this.options.push({ id: `${idx}`, label: x.desc || x }); + } + }); - let initialChecks = {}; - this.options.forEach(x => { - initialChecks[x.id] = true; - }); - this.state.checkboxIdToSelectedMap = initialChecks; - } + let initialChecks = {}; + this.options.forEach(x => { + initialChecks[x.id] = true; + }); + this.state.checkboxIdToSelectedMap = initialChecks; + } - selectAll(flag) { - let newCheckboxIdToSelectedMap = {}; - for (let i = 0; i < this.options.length; i++) { - newCheckboxIdToSelectedMap[`${this.options[i].id}`] = flag; + selectAll(flag) { + let newCheckboxIdToSelectedMap = {}; + for (let i = 0; i < this.options.length; i++) { + newCheckboxIdToSelectedMap[`${this.options[i].id}`] = flag; + } + this.setState({ + checkboxIdToSelectedMap: newCheckboxIdToSelectedMap, + buttonDisabled: !flag, + }); } - this.setState({ - checkboxIdToSelectedMap: newCheckboxIdToSelectedMap, - buttonDisabled: !flag - }); - } - exportClick() { - this.setState({ - isPopoverOpen: !this.state.isPopoverOpen - }); - } + exportClick() { + this.setState({ + isPopoverOpen: !this.state.isPopoverOpen, + }); + } - closePopover() { - this.setState({ - isPopoverOpen: false - }); - } + closePopover() { + this.setState({ + isPopoverOpen: false, + }); + } - onChange = optionId => { - const newCheckboxIdToSelectedMap = { - ...this.state.checkboxIdToSelectedMap, - ...{ - [optionId]: !this.state.checkboxIdToSelectedMap[optionId] + onChange = optionId => { + const newCheckboxIdToSelectedMap = { + ...this.state.checkboxIdToSelectedMap, + ...{ + [optionId]: !this.state.checkboxIdToSelectedMap[optionId], + }, + }; + let result = false; + for (let i = 0; i < this.options.length; i++) { + if (newCheckboxIdToSelectedMap[`${this.options[i].id}`] === true) { + result = true; + } } + this.setState({ + checkboxIdToSelectedMap: newCheckboxIdToSelectedMap, + buttonDisabled: !result, + }); }; - let result = false; - for (let i = 0; i < this.options.length; i++) { - if (newCheckboxIdToSelectedMap[`${this.options[i].id}`] === true) { - result = true; - } - } - this.setState({ - checkboxIdToSelectedMap: newCheckboxIdToSelectedMap, - buttonDisabled: !result - }); - }; - render() { - const button = ( - - Export PDF - - ); - return ( - - - - {this.options.length > 3 && - <> this.selectAll(true)}> - Select all - this.selectAll(false)}> - Unselect all - } - - { - this.closePopover(); - this.props.exportConfiguration(this.state.checkboxIdToSelectedMap); - }} - fill + render() { + const button = ( + - Generate PDF report - - - ); - } -}); + Export PDF + + ); + return ( + + + + {this.options.length > 3 && ( + <> + this.selectAll(true)}> + Select all + + + this.selectAll(false)}> + Unselect all + + + )} + + { + this.closePopover(); + this.props.exportConfiguration( + this.state.checkboxIdToSelectedMap, + ); + }} + fill + > + Generate PDF report + + + ); + } + }, +); ExportConfiguration.propTypes = { exportConfiguration: PropTypes.func, type: PropTypes.string, - agentPlatform: PropTypes.string + agentPlatform: PropTypes.string, }; diff --git a/plugins/main/public/controllers/agent/index.js b/plugins/main/public/controllers/agent/index.js index 06afcac098..29c9802867 100644 --- a/plugins/main/public/controllers/agent/index.js +++ b/plugins/main/public/controllers/agent/index.js @@ -9,10 +9,8 @@ * * Find more information about this on the LICENSE file. */ -import { AgentsController } from './agents'; import { RegisterAgent } from '../../components/endpoints-summary/register-agent/containers/register-agent/register-agent'; -import { ExportConfiguration } from './components/export-configuration'; -import { AgentsWelcome } from '../../components/common/welcome/agents-welcome'; +import { ExportConfiguration } from '../../components/agents/export-configuration'; import { Mitre } from '../../components/overview'; import { AgentsTable } from '../../components/endpoints-summary/table/agents-table'; import { MainModule } from '../../components/common/modules/main'; @@ -25,10 +23,8 @@ import { AgentView } from '../../components/endpoints-summary/agent'; const app = getAngularModule(); app - .controller('agentsController', AgentsController) .value('RegisterAgent', RegisterAgent) .value('ExportConfiguration', ExportConfiguration) - .value('AgentsWelcome', AgentsWelcome) .value('AgentView', AgentView) .value('Mitre', Mitre) .value('AgentsTable', AgentsTable) diff --git a/plugins/main/public/controllers/management/components/files-group-table.js b/plugins/main/public/controllers/management/components/files-group-table.js index 5736923a07..61ff65dd56 100644 --- a/plugins/main/public/controllers/management/components/files-group-table.js +++ b/plugins/main/public/controllers/management/components/files-group-table.js @@ -21,10 +21,10 @@ import { EuiTitle, EuiButtonEmpty, EuiText, - EuiToolTip + EuiToolTip, } from '@elastic/eui'; -import { ExportConfiguration } from '../../agent/components/export-configuration'; +import { ExportConfiguration } from '../../../components/agents/export-configuration'; import { ReportingService } from '../../../react-services/reporting'; export class FilesInGroupTable extends Component { @@ -36,7 +36,7 @@ export class FilesInGroupTable extends Component { groupName: this.props.group.name || 'Group', files: [], originalfiles: [], - isLoading: false + isLoading: false, }; this.filters = { name: 'search', value: '' }; @@ -47,7 +47,7 @@ export class FilesInGroupTable extends Component { const files = await this.props.getFilesFromGroup(this.props.group.name); this.setState({ files: files, - originalfiles: files + originalfiles: files, }); } catch (error) { console.error('error mounting the component ', error); @@ -66,7 +66,7 @@ export class FilesInGroupTable extends Component { : this.state.originalfiles; this.setState({ isLoading: false, - files: items + files: items, }); } }; @@ -80,7 +80,7 @@ export class FilesInGroupTable extends Component { const files = await this.props.getFilesFromGroup(this.props.group.name); this.setState({ originalfiles: files, - refreshingFiles: false + refreshingFiles: false, }); } catch (error) { this.setState({ refreshingFiles: false }); @@ -93,45 +93,45 @@ export class FilesInGroupTable extends Component { { field: 'filename', name: 'File', - sortable: true + sortable: true, }, { field: 'hash', name: 'Checksum', - sortable: true + sortable: true, }, { name: 'Actions', render: item => { return ( - + + aria-label='See file content' + onClick={() => this.props.openFileContent( this.state.groupName, - item.filename + item.filename, ) } - iconType="eye" + iconType='eye' /> ); - } - } + }, + }, ]; const search = { onChange: this.onQueryChange, box: { incremental: this.state.incremental, - schema: true - } + schema: true, + }, }; return ( - + @@ -144,8 +144,8 @@ export class FilesInGroupTable extends Component { this.props.editConfig()} > Edit group configuration @@ -157,7 +157,7 @@ export class FilesInGroupTable extends Component { this.reportingService.startConfigReport( this.props.state.itemDetail, 'groupConfig', - enabledComponents + enabledComponents, ) } type='group' @@ -165,7 +165,7 @@ export class FilesInGroupTable extends Component { await this.props.export(this.state.groupName, [this.filters]) } @@ -174,21 +174,21 @@ export class FilesInGroupTable extends Component { - this.refresh()}> + this.refresh()}> Refresh - + From here you can list and see your group files, also, you can edit the group configuration Date: Thu, 25 Apr 2024 11:32:58 -0300 Subject: [PATCH 08/12] Delete agents angularjs controller --- .../endpoints-summary/agent/index.tsx | 2 - .../main/public/controllers/agent/agents.js | 784 ------------------ plugins/main/public/services/routes.js | 1 - .../templates/agents/dashboards copy.html | 138 --- 4 files changed, 925 deletions(-) delete mode 100644 plugins/main/public/controllers/agent/agents.js delete mode 100644 plugins/main/public/templates/agents/dashboards copy.html diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index 505e2cf633..0d13be8eb4 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -32,14 +32,12 @@ export const AgentView = () => { const shareAgent = new ShareAgent(); const targetLocation = shareAgent.getTargetLocation(); - // const ignoreTabs = ['syscollector', 'welcome', 'configuration', 'stats']; const { agent: agentId } = $router.current.params; const [agent, setAgent] = useState(); const [isLoadingAgent, setIsLoadingAgent] = useState(true); const [tab, setTab] = useState(); - // const [tabHistory, setTabHistory] = useState([]); const init = async () => { const savedTimefilter = $commonData.getTimefilter(); diff --git a/plugins/main/public/controllers/agent/agents.js b/plugins/main/public/controllers/agent/agents.js deleted file mode 100644 index db8249dedc..0000000000 --- a/plugins/main/public/controllers/agent/agents.js +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Wazuh app - Agents controller - * Copyright (C) 2015-2022 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ -import { FilterHandler } from '../../utils/filter-handler'; -import { TabNames } from '../../utils/tab-names'; -import { visualizations } from '../../templates/agents/visualizations'; - -import { ConfigurationHandler } from '../../utils/config-handler'; -import { AppState } from '../../react-services/app-state'; -import { WazuhConfig } from '../../react-services/wazuh-config'; -import { GenericRequest } from '../../react-services/generic-request'; -import { WzRequest } from '../../react-services/wz-request'; -import { - getToasts, - getDataPlugin, - getWazuhCorePlugin, -} from '../../kibana-services'; -import { ShareAgent } from '../../factories/share-agent'; -import { TabVisualizations } from '../../factories/tab-visualizations'; -import { formatUIDate } from '../../react-services/time-service'; -import { hasAgentSupportModule } from '../../react-services/wz-agents'; -import { UI_LOGGER_LEVELS } from '../../../common/constants'; -import { UI_ERROR_SEVERITIES } from '../../react-services/error-orchestrator/types'; -import { getErrorOrchestrator } from '../../react-services/common-services'; -import { updateCurrentAgentData } from '../../redux/actions/appStateActions'; -import store from '../../redux/store'; - -export class AgentsController { - /** - * Class constructor - * @param {Object} $scope - * @param {Object} $location - * @param {Object} $rootScope - * @param {Object} errorHandler - * @param {Object} commonData - * @param {Object} reportingService - * @param {Object} visFactoryService - * @param {Object} csvReq - */ - constructor( - $scope, - $location, - $rootScope, - errorHandler, - commonData, - reportingService, - visFactoryService, - csvReq, - ) { - this.$scope = $scope; - this.$location = $location; - this.$rootScope = $rootScope; - this.errorHandler = errorHandler; - this.tabVisualizations = new TabVisualizations(); - this.$scope.visualizations = visualizations; - this.shareAgent = new ShareAgent(); - this.commonData = commonData; - this.reportingService = reportingService; - this.visFactoryService = visFactoryService; - this.csvReq = csvReq; - this.wazuhConfig = new WazuhConfig(); - this.genericReq = GenericRequest; - - // Config on-demand - this.$scope.isArray = Array.isArray; - this.configurationHandler = new ConfigurationHandler(errorHandler); - this.$scope.currentConfig = null; - this.$scope.configurationTab = ''; - this.$scope.configurationSubTab = ''; - this.$scope.integrations = {}; - this.$scope.selectedItem = 0; - this.targetLocation = null; - this.ignoredTabs = ['syscollector', 'welcome', 'configuration', 'stats']; - - this.$scope.expandArray = [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - ]; - - this.loadWelcomeCardsProps(); - this.$scope.getWelcomeCardsProps = resultState => { - return { ...this.$scope.welcomeCardsProps, resultState }; - }; - } - - /** - * On controller loads - */ - async $onInit() { - const savedTimefilter = this.commonData.getTimefilter(); - if (savedTimefilter) { - getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); - this.commonData.removeTimefilter(); - } - - this.$rootScope.reportStatus = false; - - this.$location.search('_a', null); - this.filterHandler = new FilterHandler(AppState.getCurrentPattern()); - this.visFactoryService.clearAll(); - - // Getting possible target location - this.targetLocation = this.shareAgent.getTargetLocation(); - - if (this.targetLocation && typeof this.targetLocation === 'object') { - this.$scope.tabView = this.targetLocation.subTab; - this.$scope.tab = this.targetLocation.tab; - } else { - this.$scope.tabView = this.commonData.checkTabViewLocation(); - this.$scope.tab = this.commonData.checkTabLocation(); - } - this.tabHistory = []; - if (!this.ignoredTabs.includes(this.$scope.tab)) - this.tabHistory.push(this.$scope.tab); - - // Tab names - this.$scope.tabNames = TabNames; - - this.tabVisualizations.assign('agents'); - - /** - * This check if given array of items contais a single given item - * @param {Object} item - * @param {Array} array - */ - this.$scope.inArray = (item, array) => - item && Array.isArray(array) && array.includes(item); - - this.$scope.switchSubtab = async ( - subtab, - force = false, - onlyAgent = false, - ) => this.switchSubtab(subtab, force, onlyAgent); - - this.changeAgent = false; - - this.$scope.switchTab = (tab, force = false) => this.switchTab(tab, force); - this.$scope.getAgent = async newAgentId => this.getAgent(newAgentId); - this.$scope.goGroups = (agent, group) => this.goGroups(agent, group); - - this.$scope.search = (term, specificPath) => - this.$scope.$broadcast('wazuhSearch', { - term, - specificPath, - }); - - this.$scope.searchSyscheckFile = (term, specificFilter) => - this.$scope.$broadcast('wazuhSearch', { - term, - specificFilter, - }); - - this.$scope.searchRootcheck = (term, specificFilter) => - this.$scope.$broadcast('wazuhSearch', { - term, - specificFilter, - }); - - this.$scope.shouldShowComponent = component => - this.shouldShowComponent(component); - - this.$scope.$on('$destroy', () => { - this.visFactoryService.clearAll(); - }); - - this.$scope.isArray = Array.isArray; - - this.$scope.goGroup = () => { - this.shareAgent.setAgent(this.$scope.agent); - this.$location.path('/manager/groups'); - }; - - this.$scope.exportConfiguration = enabledComponents => { - this.reportingService.startConfigReport( - this.$scope.agent, - 'agentConfig', - enabledComponents, - ); - }; - - //Load - try { - this.$scope.getAgent(); - } catch (error) { - const options = { - context: `${AgentsController.name}.$onInit`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: true, - error: { - error: error, - message: error.message || error, - title: `Error getting the agent: ${error.message || error}`, - }, - }; - getErrorOrchestrator().handleError(options); - } - - // Config on demand - this.$scope.getXML = () => this.configurationHandler.getXML(this.$scope); - this.$scope.getJSON = () => this.configurationHandler.getJSON(this.$scope); - this.$scope.isString = item => typeof item === 'string'; - this.$scope.hasSize = obj => - obj && typeof obj === 'object' && Object.keys(obj).length; - this.$scope.offsetTimestamp = (text, time) => - this.offsetTimestamp(text, time); - this.$scope.switchConfigTab = ( - configurationTab, - sections, - navigate = true, - ) => { - this.$scope.navigate = navigate; - try { - this.$scope.configSubTab = JSON.stringify({ - configurationTab: configurationTab, - sections: sections, - }); - if (!this.$location.search().configSubTab) { - AppState.setSessionStorageItem( - 'configSubTab', - this.$scope.configSubTab, - ); - this.$location.search('configSubTab', true); - } - } catch (error) { - const options = { - context: `${AgentsController.name}.switchConfigTab`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: true, - error: { - error: error, - message: error.message || error, - title: `${error.message || error} Set configuration path`, - }, - }; - getErrorOrchestrator().handleError(options); - } - this.configurationHandler.switchConfigTab( - configurationTab, - sections, - this.$scope, - this.$scope.agent.id, - ); - }; - - this.$scope.switchWodle = (wodleName, navigate = true) => { - this.$scope.navigate = navigate; - this.$scope.configWodle = wodleName; - if (!this.$location.search().configWodle) { - this.$location.search('configWodle', this.$scope.configWodle); - } - this.configurationHandler.switchWodle( - wodleName, - this.$scope, - this.$scope.agent.id, - ); - }; - - this.$scope.switchConfigurationTab = (configurationTab, navigate) => { - this.$scope.navigate = navigate; - this.configurationHandler.switchConfigurationTab( - configurationTab, - this.$scope, - ); - if (!this.$scope.navigate) { - const configSubTab = this.$location.search().configSubTab; - if (configSubTab) { - try { - const config = AppState.getSessionStorageItem('configSubTab'); - const configSubTabObj = JSON.parse(config); - this.$scope.switchConfigTab( - configSubTabObj.configurationTab, - configSubTabObj.sections, - false, - ); - } catch (error) { - throw new Error(error); - } - } else { - const configWodle = this.$location.search().configWodle; - if (configWodle) { - this.$scope.switchWodle(configWodle, false); - } - } - } else { - this.$location.search('configSubTab', null); - AppState.removeSessionStorageItem('configSubTab'); - this.$location.search('configWodle', null); - } - }; - this.$scope.switchConfigurationSubTab = configurationSubTab => { - this.configurationHandler.switchConfigurationSubTab( - configurationSubTab, - this.$scope, - ); - if (configurationSubTab === 'pm-sca') { - this.$scope.currentConfig.sca = this.configurationHandler.parseWodle( - this.$scope.currentConfig, - 'sca', - ); - } - }; - this.$scope.updateSelectedItem = i => (this.$scope.selectedItem = i); - this.$scope.getIntegration = list => - this.configurationHandler.getIntegration(list, this.$scope); - - this.$scope.$on('$routeChangeStart', () => { - return AppState.removeSessionStorageItem('configSubTab'); - }); - - this.$scope.expand = i => this.expand(i); - this.setTabs(); - } - - // Switch subtab - async switchSubtab(subtab, force = false, onlyAgent = false) { - try { - if (this.$scope.tabView === subtab && !force) return; - this.tabVisualizations.clearDeadVis(); - this.visFactoryService.clear(onlyAgent); - this.$location.search('tabView', subtab); - if ( - (subtab === 'panels' || - (this.targetLocation && - typeof this.targetLocation === 'object' && - this.targetLocation.subTab === 'discover' && - subtab === 'discover')) && - !this.ignoredTabs.includes(this.$scope.tab) - ) { - await this.visFactoryService.buildAgentsVisualizations( - this.filterHandler, - this.$scope.tab, - subtab, - this.$scope.agent.id, - ); - - this.changeAgent = false; - } else { - this.$scope.$emit('changeTabView', { - tabView: subtab, - tab: this.$scope.tab, - }); - } - this.$scope.tabView = subtab; - } catch (error) { - throw new Error(error); - } - } - - /** - * Switch tab - * @param {*} tab - * @param {*} force - */ - async switchTab(tab, force = false) { - const timefilter = getDataPlugin().query.timefilter.timefilter; - this.tabVisualizations.setTab(tab); - this.$rootScope.rendered = false; - this.$rootScope.$applyAsync(); - this.falseAllExpand(); - if (this.ignoredTabs.includes(tab)) { - this.commonData.setRefreshInterval(timefilter.getRefreshInterval()); - timefilter.setRefreshInterval({ - pause: true, - value: 0, - }); - } else if (this.ignoredTabs.includes(this.$scope.tab)) { - timefilter.setRefreshInterval(this.commonData.getRefreshInterval()); - } - - // Update agent status - if (!force && this.$scope.agent) { - try { - const agentInfo = await WzRequest.apiReq('GET', '/agents', { - params: { - agents_list: this.$scope.agent.id, - select: 'status', - }, - }); - this.$scope.agent.status = - agentInfo?.data?.data?.affected_items?.[0]?.status || - this.$scope.agent.status; - - this.$scope.$applyAsync(); - } catch (error) { - throw new Error(error); - } - } - - try { - if (tab === 'configuration') { - this.$scope.switchConfigurationTab('welcome'); - } else { - this.configurationHandler.reset(this.$scope); - } - - if (!this.ignoredTabs.includes(tab)) this.tabHistory.push(tab); - if (this.tabHistory.length > 2) - this.tabHistory = this.tabHistory.slice(-2); - - if (this.$scope.tab === tab && !force) { - this.$scope.$applyAsync(); - return; - } - - const onlyAgent = this.$scope.tab === tab && force; - const sameTab = this.$scope.tab === tab; - this.$location.search('tab', tab); - const preserveDiscover = - this.tabHistory.length === 2 && - this.tabHistory[0] === this.tabHistory[1] && - !force; - this.$scope.tab = tab; - - const targetSubTab = - this.targetLocation && typeof this.targetLocation === 'object' - ? this.targetLocation.subTab - : 'panels'; - - if (!this.ignoredTabs.includes(this.$scope.tab)) { - this.$scope.switchSubtab( - targetSubTab, - true, - onlyAgent, - sameTab, - preserveDiscover, - ); - } - - this.shareAgent.deleteTargetLocation(); - this.targetLocation = null; - this.$scope.$applyAsync(); - } catch (error) { - const options = { - context: `${AgentsController.name}.switchTab`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.CRITICAL, - store: true, - error: { - error: error, - message: error.message || error, - title: error.message || error, - }, - }; - getErrorOrchestrator().handleError(options); - } - - this.$scope.configurationTabsProps = {}; - this.$scope.buildProps = tabs => { - const cleanTabs = []; - tabs.forEach(x => { - if ( - this.$scope.configurationTab === 'integrity-monitoring' && - x.id === 'fim-whodata' && - x.agent && - x.agent.agentPlatform !== 'linux' - ) - return; - - cleanTabs.push({ - id: x.id, - name: x.name, - }); - }); - this.$scope.configurationTabsProps = { - clickAction: tab => { - this.$scope.switchConfigurationSubTab(tab); - }, - selectedTab: - this.$scope.configurationSubTab || (tabs && tabs.length) - ? tabs[0].id - : '', - tabs: cleanTabs, - }; - }; - - this.setTabs(); - } - - /** - * Filter by Mitre.ID - * @param {*} id - */ - addMitrefilter(id) { - const filter = `{"meta":{"index": ${ - AppState.getCurrentPattern() || - getWazuhCorePlugin().configuration.getSettingValue('pattern') - }},"query":{"match":{"rule.mitre.id":{"query":"${id}","type":"phrase"}}}}`; - this.$rootScope.$emit('addNewKibanaFilter', { - filter: JSON.parse(filter), - }); - } - - /** - * Build the current section tabs - */ - setTabs() { - this.$scope.agentsTabsProps = false; - if (this.$scope.agent) { - this.currentPanel = this.commonData.getCurrentPanel( - this.$scope.tab, - true, - ); - - if (!this.currentPanel) return; - - const tabs = this.commonData.getTabsFromCurrentPanel( - this.currentPanel, - this.$scope.tabNames, - ); - - const cleanTabs = []; - tabs.forEach(x => { - if (!hasAgentSupportModule(this.$scope.agent, x.id)) return; - - cleanTabs.push({ - id: x.id, - name: x.name, - }); - }); - - this.$scope.agentsTabsProps = { - clickAction: tab => { - this.switchTab(tab, true); - }, - selectedTab: - this.$scope.tab || - (this.currentPanel && this.currentPanel.length - ? this.currentPanel[0] - : ''), - tabs: cleanTabs, - }; - this.$scope.$applyAsync(); - } - } - - showToast = (color, title, text, time) => { - getToasts().add({ - color: color, - title: title, - text: text, - toastLifeTimeMs: time, - }); - }; - - // Agent data - - /** - * Checks rootcheck of selected agent - */ - validateRootCheck() { - const result = this.commonData.validateRange(this.$scope.agent.rootcheck); - this.$scope.agent.rootcheck = result; - } - - /** - * Checks syscheck of selected agent - */ - validateSysCheck() { - const result = this.commonData.validateRange(this.$scope.agent.syscheck); - this.$scope.agent.syscheck = result; - } - - /** - * Get the needed data for load syscollector - * @param {*} id - */ - async loadSyscollector(id) { - try { - const syscollectorData = await this.genericReq.request( - 'GET', - `/api/syscollector/${id}`, - ); - this.$scope.syscollector = syscollectorData?.data || {}; - return; - } catch (error) { - throw new Error(error); - } - } - - /** - * Get all data from agent - * @param {*} newAgentId - */ - async getAgent(newAgentId) { - try { - this.$scope.emptyAgent = false; - this.$scope.load = true; - this.changeAgent = true; - - const globalAgent = this.shareAgent.getAgent(); - - const id = this.commonData.checkLocationAgentId(newAgentId, globalAgent); - - this.loadWelcomeCardsProps(); - this.$scope.getWelcomeCardsProps = resultState => { - return { ...this.$scope.welcomeCardsProps, resultState }; - }; - - if (!id) { - this.$scope.load = false; - // We set some properties used by the rendered component to work and allowing - // to manage when there is not selected agent. - await this.$scope.switchTab(this.$scope.tab, true); - this.loadWelcomeCardsProps(); - this.$scope.getWelcomeCardsProps = resultState => { - return { ...this.$scope.welcomeCardsProps, resultState }; - }; - this.$scope.$applyAsync(); - return; - } - - const data = await WzRequest.apiReq('GET', `/agents`, { - params: { - agents_list: id, - }, - }); - - const agentInfo = data?.data?.data?.affected_items[0] || false; - // Agent - this.$scope.agent = agentInfo; - - if (!this.$scope.agent) return; - - // Sync the selected agent on Redux store - if ( - store.getState().appStateReducers.currentAgentData.id !== - this.$scope.agent.id - ) { - store.dispatch(updateCurrentAgentData(this.$scope.agent)); - } - - if (agentInfo && this.$scope.agent.os) { - this.$scope.agentOS = - this.$scope.agent.os.name + ' ' + this.$scope.agent.os.version; - const isLinux = this.$scope.agent.os.uname.includes('Linux'); - this.$scope.agent.agentPlatform = isLinux - ? 'linux' - : this.$scope.agent.os.platform; - } else { - this.$scope.agentOS = '-'; - this.$scope.agent.agentPlatform = false; - } - - await this.$scope.switchTab(this.$scope.tab, true); - - this.loadWelcomeCardsProps(); - this.$scope.getWelcomeCardsProps = resultState => { - return { ...this.$scope.welcomeCardsProps, resultState }; - }; - this.$scope.load = false; - this.$scope.$applyAsync(); - return; - } catch (error) { - if (!this.$scope.agent) { - if ((error || {}).status === -1) { - this.$scope.emptyAgent = 'API timeout.'; - } - } - if ( - error && - typeof error === 'string' && - error.includes('Agent does not exist') - ) { - this.$location.search('agent', null); - this.$location.path('/agents-preview'); - } - this.$scope.load = false; - this.$scope.$applyAsync(); - throw new Error(error); - } - } - - shouldShowComponent(component) { - return hasAgentSupportModule(this.$scope.agent, component); - } - - setAgent(agent) { - this.$scope.agent = agent; - } - /** - * Get available welcome cards after getting the agent - */ - loadWelcomeCardsProps() { - this.$scope.welcomeCardsProps = { - switchTab: (tab, force) => this.switchTab(tab, force), - agent: this.$scope.agent, - api: AppState.getCurrentAPI(), - setAgent: agent => this.setAgent(agent), - goGroups: (agent, group) => this.goGroups(agent, group), - }; - } - - /** - * This adds timezone offset to a given date - * @param {String} binding_text - * @param {String} date - */ - offsetTimestamp(text, time) { - try { - return text + formatUIDate(time); - } catch (error) { - const options = { - context: `${AgentsController.name}.offsetTimestamp`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: false, - error: { - error: error, - message: error.message || error, - title: error.message || error, - }, - }; - getErrorOrchestrator().handleError(options); - return time !== '-' ? `${text}${time} (UTC)` : time; - } - } - - /** - * Navigate to the groups of an agent - * @param {*} agent - * @param {*} group - */ - goGroups(agent, group) { - AppState.setNavigation({ - status: true, - }); - this.visFactoryService.clearAll(); - this.shareAgent.setAgent(agent, group); - this.$location.search('tab', 'groups'); - this.$location.search('navigation', true); - this.$location.path('/manager'); - } - - falseAllExpand() { - this.$scope.expandArray = [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - ]; - } - - expand(i) { - const oldValue = this.$scope.expandArray[i]; - this.falseAllExpand(); - this.$scope.expandArray[i] = !oldValue; - } -} diff --git a/plugins/main/public/services/routes.js b/plugins/main/public/services/routes.js index e9f87269e8..06107272ca 100644 --- a/plugins/main/public/services/routes.js +++ b/plugins/main/public/services/routes.js @@ -20,7 +20,6 @@ import { settingsWizard, getSavedSearch, getIp, getWzConfig } from './resolves'; // HTML templates import healthCheckTemplate from '../templates/health-check/health-check.html'; import agentsTemplate from '../templates/agents/dashboards.html'; -// import agentsTemplate from '../templates/agents/dashboards copy.html'; import agentDeployTemplate from '../templates/agents/deploy/agent-deploy.html'; import agentsPrevTemplate from '../templates/agents-prev/agents-prev.html'; import managementTemplate from '../templates/management/management.html'; diff --git a/plugins/main/public/templates/agents/dashboards copy.html b/plugins/main/public/templates/agents/dashboards copy.html deleted file mode 100644 index 33fe5c8c5e..0000000000 --- a/plugins/main/public/templates/agents/dashboards copy.html +++ /dev/null @@ -1,138 +0,0 @@ - -
-
- -
- - - -
-
-
- -
-
-
- - -
-
- -
-
-
-
- -
-
-
- -
- -
- - -
-
-
- - - - - - -
-
{{loadingStatus}}
-
-
- - -
-
-
- - - - - - -
-
{{reportStatus}}
-
-
-
- -
- -
- - -
-
- -
-
-
- - -
- -
- - -
- -
- - -
From df413a44a48b94ad51dd716e245317662ad99300 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Thu, 25 Apr 2024 12:12:57 -0300 Subject: [PATCH 09/12] Get agent on change tab --- .../common/charts/visualizations/basic.tsx | 6 ++++- .../endpoints-summary/agent/index.tsx | 27 ++++++------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/plugins/main/public/components/common/charts/visualizations/basic.tsx b/plugins/main/public/components/common/charts/visualizations/basic.tsx index 2e48e5e734..eaca2e6270 100644 --- a/plugins/main/public/components/common/charts/visualizations/basic.tsx +++ b/plugins/main/public/components/common/charts/visualizations/basic.tsx @@ -160,7 +160,11 @@ export const VisualizationBasicWidgetSelector = ({ return ( <> - + {title && (

diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index 0d13be8eb4..c3d80ca430 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -15,14 +15,11 @@ import { MainAgentStats } from '../../agents/stats'; import WzManagementConfiguration from '../../../controllers/management/components/management/configuration/configuration-main.js'; import { getAgentsService } from '../services'; import { ShareAgent } from '../../../factories/share-agent'; -import { AppState } from '../../../react-services'; import store from '../../../redux/store'; import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; import { endpointSummary } from '../../../utils/applications'; export const AgentView = () => { - AppState.removeSessionStorageItem('configSubTab'); - const $injector = getAngularModule().$injector; const $router = $injector.get('$route'); @@ -31,25 +28,17 @@ export const AgentView = () => { const shareAgent = new ShareAgent(); - const targetLocation = shareAgent.getTargetLocation(); + const savedTimefilter = $commonData.getTimefilter(); + if (savedTimefilter) { + getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); + $commonData.removeTimefilter(); + } const { agent: agentId } = $router.current.params; const [agent, setAgent] = useState(); const [isLoadingAgent, setIsLoadingAgent] = useState(true); - const [tab, setTab] = useState(); - - const init = async () => { - const savedTimefilter = $commonData.getTimefilter(); - if (savedTimefilter) { - getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); - $commonData.removeTimefilter(); - } - - setTab(targetLocation?.tab || $commonData.checkTabLocation()); - - await getAgent(); - }; + const [tab, setTab] = useState($commonData.checkTabLocation()); const getAgent = async () => { try { @@ -93,8 +82,8 @@ export const AgentView = () => { }; useEffect(() => { - init(); - }, []); + getAgent(); + }, [tab]); const exportConfiguration = enabledComponents => { $reportingService.startConfigReport( From b2799121c3e396cf2cd1b876fca897b140025ee0 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Thu, 25 Apr 2024 12:28:01 -0300 Subject: [PATCH 10/12] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b769600104..5b093d4e62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Enhance the validation for `enrollment.dns` on App Settings application [#6573](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6573) - Remove AngularJS controller for manage groups [#6543](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6543) - Remove some branding references across the application. [#6155](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6155) +- Remove AngularJS controller for the agent view [#6618](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6618) ### Fixed From e7c0d03d6c41e6c151d850121ef8ac6718b71c92 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Fri, 26 Apr 2024 18:00:10 -0300 Subject: [PATCH 11/12] Remove unused VisFactoryHandler --- .../common/welcome/agents-welcome.js | 90 +++++++++---------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index d0795f81cb..350d5fa896 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -38,9 +38,6 @@ import WzReduxProvider from '../../../redux/wz-redux-provider'; import MenuAgent from './components/menu-agent'; import './welcome.scss'; import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker'; -import { VisFactoryHandler } from '../../../react-services/vis-factory-handler'; -import { AppState } from '../../../react-services/app-state'; -import { FilterHandler } from '../../../utils/filter-handler'; import { TabVisualizations } from '../../../factories/tab-visualizations'; import { showExploreAgentModalGlobal, @@ -104,11 +101,11 @@ export const AgentsWelcome = compose( }, ...(agent?.name ? [ - { - text: `${agent.name}`, - truncate: true, - }, - ] + { + text: `${agent.name}`, + truncate: true, + }, + ] : []), ]; }), @@ -228,7 +225,6 @@ export const AgentsWelcome = compose( tabVisualizations.assign({ welcome: 8, }); - const filterHandler = new FilterHandler(AppState.getCurrentPattern()); this.drawerLokedSubscribtion = getChrome() .getIsNavDrawerLocked$() @@ -238,12 +234,6 @@ export const AgentsWelcome = compose( }); }); window.addEventListener('resize', this.updateWidth); //eslint-disable-line - await VisFactoryHandler.buildAgentsVisualizations( - filterHandler, - 'welcome', - null, - this.props.agent.id, - ); } componentDidUpdate(prevProps) { @@ -268,13 +258,13 @@ export const AgentsWelcome = compose( ) ? JSON.parse(window.localStorage.getItem('wz-menu-agent-apps-pinned')) : [ - // Default pinned applications - threatHunting.id, - fileIntegrityMonitoring.id, - configurationAssessment.id, - mitreAttack.id, - malwareDetection.id, - ]; + // Default pinned applications + threatHunting.id, + fileIntegrityMonitoring.id, + configurationAssessment.id, + mitreAttack.id, + malwareDetection.id, + ]; } // Ensure the pinned applications are supported @@ -611,7 +601,7 @@ export const AgentsWelcome = compose( > {' '} {/* DatePicker */} - {}} /> + { }} /> {(this.state.widthWindow < 1150 && ( @@ -644,33 +634,33 @@ export const AgentsWelcome = compose( )) || ( - - - - - - {this.renderMitrePanel()} - - {this.renderCompliancePanel()} - - - - - - - - {' '} - {/* Events count evolution */} - {this.renderEventCountVisualization()} - - {this.renderSCALastScan()} - - - )} + + + + + + {this.renderMitrePanel()} + + {this.renderCompliancePanel()} + + + + + + + + {' '} + {/* Events count evolution */} + {this.renderEventCountVisualization()} + + {this.renderSCALastScan()} + + + )} From 3d19dc610654545f0c89dc31e6a52c8c6da6d2f2 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Mon, 29 Apr 2024 11:48:52 -0300 Subject: [PATCH 12/12] Improve code and remove unused code --- .../common/welcome/agents-welcome.js | 2 +- .../endpoints-summary/agent/index.tsx | 35 ++++++++----------- .../main/public/controllers/agent/index.js | 10 ------ .../configuration/configuration-switch.js | 13 ++++--- 4 files changed, 21 insertions(+), 39 deletions(-) diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 350d5fa896..43b19f1556 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -600,7 +600,7 @@ export const AgentsWelcome = compose( }} > {' '} - {/* DatePicker */} + {/* TODO: Replace with SearchBar and replace implementation to get the time range in AgentView component*/} { }} /> diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index c3d80ca430..c7b88c3ad9 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; import { EuiPage, EuiPageBody, EuiProgress } from '@elastic/eui'; +import { useDispatch } from 'react-redux'; import { getErrorOrchestrator } from '../../../react-services/common-services'; import { UI_LOGGER_LEVELS } from '../../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; @@ -15,19 +16,23 @@ import { MainAgentStats } from '../../agents/stats'; import WzManagementConfiguration from '../../../controllers/management/components/management/configuration/configuration-main.js'; import { getAgentsService } from '../services'; import { ShareAgent } from '../../../factories/share-agent'; -import store from '../../../redux/store'; import { updateCurrentAgentData } from '../../../redux/actions/appStateActions'; import { endpointSummary } from '../../../utils/applications'; - -export const AgentView = () => { +import { withErrorBoundary, withReduxProvider } from '../../common/hocs'; +import { compose } from 'redux'; + +export const AgentView = compose( + withErrorBoundary, + withReduxProvider, +)(() => { + //TODO: Replace when implement React router const $injector = getAngularModule().$injector; - const $router = $injector.get('$route'); const $commonData = $injector.get('commonData'); - const $reportingService = $injector.get('reportingService'); const shareAgent = new ShareAgent(); + //TODO: Replace with useDatasource and useSearchBar when replace WzDatePicker with SearchBar in AgentsWelcome component const savedTimefilter = $commonData.getTimefilter(); if (savedTimefilter) { getDataPlugin().query.timefilter.timefilter.setTime(savedTimefilter); @@ -39,6 +44,7 @@ export const AgentView = () => { const [agent, setAgent] = useState(); const [isLoadingAgent, setIsLoadingAgent] = useState(true); const [tab, setTab] = useState($commonData.checkTabLocation()); + const dispatch = useDispatch(); const getAgent = async () => { try { @@ -62,7 +68,7 @@ export const AgentView = () => { const agent = affected_items[0]; setAgent(agent); - store.dispatch(updateCurrentAgentData(agent)); + dispatch(updateCurrentAgentData(agent)); } catch (error) { const options = { context: `AgentView.getAgent`, @@ -85,14 +91,6 @@ export const AgentView = () => { getAgent(); }, [tab]); - const exportConfiguration = enabledComponents => { - $reportingService.startConfigReport( - agent, - 'agentConfig', - enabledComponents, - ); - }; - const switchTab = (tab: string) => { setTab(tab); getCore().application.navigateToApp(endpointSummary.id, { @@ -123,11 +121,6 @@ export const AgentView = () => { } if (tab === 'configuration' && agent) { - return ( - - ); + return ; } -}; +}); diff --git a/plugins/main/public/controllers/agent/index.js b/plugins/main/public/controllers/agent/index.js index 29c9802867..cb75bf45d0 100644 --- a/plugins/main/public/controllers/agent/index.js +++ b/plugins/main/public/controllers/agent/index.js @@ -10,12 +10,7 @@ * Find more information about this on the LICENSE file. */ import { RegisterAgent } from '../../components/endpoints-summary/register-agent/containers/register-agent/register-agent'; -import { ExportConfiguration } from '../../components/agents/export-configuration'; -import { Mitre } from '../../components/overview'; -import { AgentsTable } from '../../components/endpoints-summary/table/agents-table'; import { MainModule } from '../../components/common/modules/main'; -import { MainSyscollector } from '../../components/agents/syscollector/main'; -import { MainAgentStats } from '../../components/agents/stats'; import { getAngularModule } from '../../kibana-services'; import { MainEndpointsSummary } from '../../components/endpoints-summary'; import { AgentView } from '../../components/endpoints-summary/agent'; @@ -24,11 +19,6 @@ const app = getAngularModule(); app .value('RegisterAgent', RegisterAgent) - .value('ExportConfiguration', ExportConfiguration) .value('AgentView', AgentView) - .value('Mitre', Mitre) - .value('AgentsTable', AgentsTable) - .value('MainSyscollector', MainSyscollector) - .value('MainAgentStats', MainAgentStats) .value('MainModule', MainModule) .value('MainEndpointsSummary', MainEndpointsSummary); diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js index 9a59dfa8d4..da03187aad 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js @@ -243,7 +243,6 @@ class WzConfigurationSwitch extends Component { )) || )} @@ -493,12 +492,12 @@ export default compose( props.agent.id === '000' ? { action: 'manager:read', resource: '*:*:*' } : [ - { action: 'agent:read', resource: `agent:id:${props.agent.id}` }, - ...(props.agent.group || []).map(group => ({ - action: 'agent:read', - resource: `agent:group:${group}`, - })), - ], + { action: 'agent:read', resource: `agent:id:${props.agent.id}` }, + ...(props.agent.group || []).map(group => ({ + action: 'agent:read', + resource: `agent:group:${group}`, + })), + ], ]), //TODO: this need cluster:read permission but manager/cluster is managed in WzConfigurationSwitch component withRenderIfOrWrapped( props => props.agent.status === API_NAME_AGENT_STATUS.NEVER_CONNECTED,