Skip to content

Commit

Permalink
[Backport 4.4-1.2-wzd] [PR] Add agent synchronization statistics (#4442)
Browse files Browse the repository at this point in the history
[PR] Add agent synchronization statistics (#3874)

* Added Synced stats and pending agents

* Added mocked column synced

* Changed pending position and color

* add agent-synced.tsx

* change date:data

* Update GET /agents/summary/status response handler

* add changelog

* Deprecated is_sync endpoint

* Created synced constants and updated endpoint definitions

Co-authored-by: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Co-authored-by: yenienserrano <ian.serrano@wazuh.com>
Co-authored-by: Álex <alejandro.ruiz.becerra@wazuh.com>
(cherry picked from commit 4457027)

Co-authored-by: Federico Rodriguez <federico.rodriguez@wazuh.com>
  • Loading branch information
github-actions[bot] and asteriscos authored Sep 6, 2022
1 parent 0a2f940 commit 190d2e4
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 68 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ All notable changes to the Wazuh app project will be documented in this file.
### Added

- Added the option to sort by the agents count in the group table. [#4323](https://github.com/wazuh/wazuh-kibana-app/pull/4323)
- Added agent synchronization status in the agent module. [#3874](https://github.com/wazuh/wazuh-kibana-app/pull/3874)

### Changed

- Changed the HTTP verb from `GET` to `POST` in the requests to login to the Wazuh API [#4103](https://github.com/wazuh/wazuh-kibana-app/pull/4103)
- Endpoint `/agents/summary/status` response was adapted. [#3874](https://github.com/wazuh/wazuh-kibana-app/pull/3874)

## Wazuh v4.3.7 - OpenSearch Dashboards 1.2.0 - Revision 4308

Expand Down
51 changes: 40 additions & 11 deletions common/api-info/endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@
"format": "group_names"
}
},
{
"name": "group_config_status",
"description": "Agent groups configuration sync status",
"schema": {
"type": "string",
"enum": [
"synced",
"not synced"
]
}
},
{
"name": "ip",
"description": "Filter by the IP used by the agent to communicate with the manager. If it's not available, it will have the same value as registerIP",
Expand Down Expand Up @@ -206,7 +217,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -852,7 +863,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -1105,7 +1116,6 @@
"socket",
"syscheck",
"syslog_output",
"agent-key-polling",
"aws-s3",
"azure-logs",
"cis-cat",
Expand Down Expand Up @@ -3226,7 +3236,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -4525,7 +4535,6 @@
"socket",
"syscheck",
"syslog_output",
"agent-key-polling",
"aws-s3",
"azure-logs",
"cis-cat",
Expand Down Expand Up @@ -6904,6 +6913,25 @@
}
]
},
{
"name": "/security/user/authenticate",
"documentation": "https://documentation.wazuh.com/current/user-manual/api/reference.html#operation/api.controllers.security_controller.deprecated_login_user",
"description": "This method should be called to get an API token. This token will expire after auth_token_exp_timeout seconds (default: 900). This value can be changed using PUT /security/config",
"summary": "Login",
"tags": [
"Security"
],
"query": [
{
"name": "raw",
"description": "Format response in plain text",
"required": false,
"schema": {
"type": "boolean"
}
}
]
},
{
"name": "/security/users",
"documentation": "https://documentation.wazuh.com/4.3/user-manual/api/reference.html#operation/api.controllers.security_controller.get_users",
Expand Down Expand Up @@ -9394,7 +9422,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -9548,7 +9576,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -10549,9 +10577,10 @@
"body": [
{
"name": "group_id",
"description": "Group name",
"description": "Group name. It can contain any of the characters between a-z, A-Z, 0-9, '_', '-' and '.'. Names '.' and '..' are restricted.",
"type": "string",
"format": "group_names"
"format": "group_names",
"maxLength": 128
}
]
},
Expand Down Expand Up @@ -11132,7 +11161,7 @@
},
{
"name": "version",
"description": "Filter by agents version",
"description": "Filter by agents version using one of the following formats: 'X.Y.Z', 'vX.Y.Z', 'wazuh X.Y.Z' or 'wazuh vX.Y.Z'. For example: '4.4.0'",
"schema": {
"type": "string",
"format": "alphanumeric"
Expand Down Expand Up @@ -12010,4 +12039,4 @@
}
]
}
]
]
9 changes: 7 additions & 2 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,13 @@ export const UI_ORDER_AGENT_STATUS = [
API_NAME_AGENT_STATUS.ACTIVE,
API_NAME_AGENT_STATUS.DISCONNECTED,
API_NAME_AGENT_STATUS.PENDING,
API_NAME_AGENT_STATUS.NEVER_CONNECTED
];
API_NAME_AGENT_STATUS.NEVER_CONNECTED
]

export const AGENT_SYNCED_STATUS = {
SYNCED: 'synced',
NOT_SYNCED: 'not synced',
}

// Documentation
export const DOCUMENTATION_WEB_BASE_URL = "https://documentation.wazuh.com";
Expand Down
22 changes: 22 additions & 0 deletions public/components/agents/agent-synced.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import { EuiHealth } from "@elastic/eui";
import { AGENT_SYNCED_STATUS } from '../../../common/constants';

interface SyncedProps {
synced: string;
}

export const AgentSynced = ({ synced }: SyncedProps) => {
const color = {
[AGENT_SYNCED_STATUS.SYNCED]: 'success',
[AGENT_SYNCED_STATUS.NOT_SYNCED]: 'subdued',
}[synced];

return (
<EuiHealth color={color}>
<span className={'hide-agent-status'}>
{synced}
</span>
</EuiHealth>
);
}
7 changes: 0 additions & 7 deletions public/components/tools/devtools/api-requests-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,6 @@ export const apiRequestList =
"meta": "endpoint",
"documentationLink": "https://documentation.wazuh.com/current/user-manual/api/reference.html#get-active-configuration"
},
{
"name": "agents/:agent_id/group/is_sync",
"value": "agents/:agent_id/group/is_sync",
"score": 1,
"meta": "endpoint",
"documentationLink": "https://documentation.wazuh.com/current/user-manual/api/reference.html#get-sync-status-of-agent"
},
{
"name": "agents/:agent_id/key",
"value": "agents/:agent_id/key",
Expand Down
4 changes: 2 additions & 2 deletions public/controllers/agent/agents-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ export class AgentsPreviewController {
if (loc && loc.tab) {
this.submenuNavItem = loc.tab;
}
const summaryData = await WzRequest.apiReq('GET', '/agents/summary/status', {});
this.summary = summaryData.data.data;
const {data: {data: summaryData}} = await WzRequest.apiReq('GET', '/agents/summary/status', {});
this.summary = summaryData.connection;
if (this.summary.total === 0) {
if (this.addingNewAgent === undefined) {
this.addNewAgent(true);
Expand Down
21 changes: 4 additions & 17 deletions public/controllers/agent/agents.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ export class AgentsController {
};

this.$scope.switchConfigurationTab = (configurationTab, navigate) => {
// Check if configuration is synced
this.checkSync();
this.$scope.navigate = navigate;
this.configurationHandler.switchConfigurationTab(configurationTab, this.$scope);
if (!this.$scope.navigate) {
Expand Down Expand Up @@ -510,8 +508,11 @@ export class AgentsController {
},
});
this.$scope.agent.status =
(((((agentInfo || {}).data || {}).data || {}).affected_items || [])[0] || {}).status ||
agentInfo?.data?.data?.affected_items?.[0]?.status ||
this.$scope.agent.status;
this.$scope.isSynchronized = this.$scope.agent.status?.synced;

this.$scope.$applyAsync();
} catch (error) {
throw new Error(error);
}
Expand Down Expand Up @@ -738,20 +739,6 @@ export class AgentsController {
this.$scope.agent.syscheck = result;
}

/**
* Checks if configuration is sync
*/
async checkSync() {
const isSync = await WzRequest.apiReq(
'GET',
`/agents/${this.$scope.agent.id}/group/is_sync`,
{}
);
this.$scope.isSynchronized =
(((((isSync || {}).data || {}).data || {}).affected_items || [])[0] || {}).synced || false;
this.$scope.$applyAsync();
}

/**
* Get the needed data for load syscollector
* @param {*} id
Expand Down
15 changes: 13 additions & 2 deletions public/controllers/agent/components/agents-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export const AgentsPreview = compose(
loading: false,
showAgentsEvolutionVisualization: false,
agentTableFilters: [],
agentStatusSummary: {}
agentStatusSummary: {},
agentConfiguration: {},
};
this.wazuhConfig = new WazuhConfig();
this.agentStatus = UI_ORDER_AGENT_STATUS.map(agentStatus => ({
Expand Down Expand Up @@ -110,7 +111,7 @@ export const AgentsPreview = compose(
async fetchAgentStatusDetailsData(){
try {
this.setState({ loading: true });
const {data: {data: agentStatusSummary}} = await WzRequest.apiReq('GET', '/agents/summary/status', {});
const {data: {data: { connection: agentStatusSummary, configuration: agentConfiguration }}} = await WzRequest.apiReq('GET', '/agents/summary/status', {});

const {data: {data: {affected_items: [lastRegisteredAgent]}}} = await WzRequest.apiReq('GET', '/agents', {
params: { limit: 1, sort: '-dateAdd', q: 'id!=000' },
Expand All @@ -121,7 +122,9 @@ export const AgentsPreview = compose(
loading: false,
lastRegisteredAgent,
agentStatusSummary,
agentConfiguration,
agentsActiveCoverage: ((agentStatusSummary.active/agentStatusSummary.total)*100).toFixed(2),
agentsSynced: ((agentConfiguration.synced/agentConfiguration.total)*100).toFixed(2),
agentMostActive
});
} catch (error) {
Expand Down Expand Up @@ -216,6 +219,14 @@ export const AgentsPreview = compose(
className="white-space-nowrap"
/>
</EuiFlexItem>
<EuiFlexItem className="agents-link-item">
<EuiStat
title={`${this.state.agentsSynced}%`}
titleSize='s'
description="Synced agents"
className="white-space-nowrap"
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup className="mt-0">
{this.state.lastRegisteredAgent && (
Expand Down
Loading

0 comments on commit 190d2e4

Please sign in to comment.