Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR] Add agent synchronization statistics #3874

Merged
merged 12 commits into from
Sep 6, 2022
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.5 - Kibana 7.10.2, 7.16.x, 7.17.x - Revision 4306

Expand Down
53 changes: 41 additions & 12 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 @@ -716,7 +727,7 @@
{
"name": "/agents/summary/status",
"documentation": "https://documentation.wazuh.com/current/user-manual/api/reference.html#operation/api.controllers.agent_controller.get_agent_summary_status",
"description": "Return a summary of the status of available agents",
"description": "Return a summary of the connection and groups configuration synchronization statuses of available agents",
"summary": "Summarize agents status",
"tags": [
"Agents"
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/current/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 @@
}
]
}
]
]
7 changes: 6 additions & 1 deletion common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,9 @@ export const UI_ORDER_AGENT_STATUS = [
API_NAME_AGENT_STATUS.DISCONNECTED,
API_NAME_AGENT_STATUS.PENDING,
API_NAME_AGENT_STATUS.NEVER_CONNECTED
]
]

export const AGENT_SYNCED_STATUS = {
SYNCED: 'synced',
NOT_SYNCED: 'not synced',
}
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 @@ -76,8 +76,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