From 885f8d5538cecc687a624c4aafa37620878c3ec2 Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:13:20 +0200 Subject: [PATCH] [Backport 4.4-7.16] Fix IPV6 visualizations (#5559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix IPV6 visualizations (#5471) * add ipv6 service * add test for service * Fix issue in agents-table * fix issue in agents-info * fix groups agents issue * Fix width in groups agents * use mapResponseItem * Add copy button to groups * Add copy button to info * fix for node list * Optimize code * Fix styles * Edit changelog * Edit changelog * Add imposter changes to test ipv6 * Replace onMouseDown with onClick * Move copy buttons to the left * fix: removed compressipv6 property of TableWzAPI * feat: add tableLayout property to some tables and remove IPv6 address compression add tableLayout=auto property to some tables: - Agents/{agent_id}/Inventory data - Management/Cluster/Nodes - Agents - Management/Configuration/Client - Management/Global configuration/Remote remove IPv6 address compression * remove: remove unused service to IPv6 compression * revert: revert changes in TableWzAPI component * add: add mocked responses to some syscollector endpoints * remove: unwanted table columns properties * changelog: add pull request entry * Fix imposter --------- Co-authored-by: Antonio David Gutiérrez Co-authored-by: Álex Ruiz Co-authored-by: yenienserrano Co-authored-by: Antonio <34042064+Desvelao@users.noreply.github.com> (cherry picked from commit 1153509927073082167fb61f3aecc87536d8a3f3) Co-authored-by: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> --- CHANGELOG.md | 14 + docker/imposter/agents/agent.json | 74 ++--- docker/imposter/agents/agents.json | 229 ++++++++-------- docker/imposter/agents/group.json | 95 +++++++ .../imposter/cluster/cluster_node_info.json | 199 +++++++------- docker/imposter/syscollector/netaddr.js | 29 ++ docker/imposter/syscollector/ports.js | 192 +++++++++++++ docker/imposter/wazuh-config.yml | 9 + .../components/syscollector-table.tsx | 103 ++++--- .../components/common/welcome/agents-info.js | 147 ++++++---- .../management/cluster/node-list.tsx | 215 ++++++++------- .../agent/components/agents-table.js | 256 +++++++++++------- .../management/configuration/client/client.js | 39 ++- .../global-configuration-remote.js | 31 ++- .../management/groups/group-agents-table.js | 116 ++++---- 15 files changed, 1147 insertions(+), 601 deletions(-) create mode 100644 docker/imposter/agents/group.json create mode 100644 docker/imposter/syscollector/netaddr.js create mode 100644 docker/imposter/syscollector/ports.js diff --git a/CHANGELOG.md b/CHANGELOG.md index b194799bbd..48bf6b35fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to the Wazuh app project will be documented in this file. +## Wazuh v4.4.5 - Kibana 7.10.2, 7.16.x, 7.17.x - Revision 00 + +### Fixed + +- Fixed the rendering of tables that contains IPs and agent overview [#5471](https://github.com/wazuh/wazuh-kibana-app/pull/5471) + +### Removed + +- Removed the agent name in the agent info ribbon [#5497](https://github.com/wazuh/wazuh-kibana-app/pull/5497) + +### Changed + +- Changed windows agent service name in the deploy agent wizard [#5538](https://github.com/wazuh/wazuh-kibana-app/pull/5538) + ## Wazuh v4.4.4 - Kibana 7.10.2, 7.16.x, 7.17.x - Revision 01 ### Added diff --git a/docker/imposter/agents/agent.json b/docker/imposter/agents/agent.json index d11371299b..00a33f70e4 100644 --- a/docker/imposter/agents/agent.json +++ b/docker/imposter/agents/agent.json @@ -1,39 +1,39 @@ { - "data": { - "affected_items": [ - { - "os": { - "arch": "x86_64", - "codename": "stretch", - "major": "9", - "name": "Debian GNU/Linux", - "platform": "debian", - "uname": "Linux |ip-10-0-1-106 |4.9.0-9-amd64 |#1 SMP Debian 4.9.168-1+deb9u2 (2019-05-13) |x86_64", - "version": "9" - }, - "ip": "10.0.1.106", - "configSum": "6f4293818ef64291ca53727fb9ab8958", - "mergedSum": "7976a83d1aebcca09bc14459b5518ed5", - "id": "001", - "registerIP": "any", - "dateAdd": "2022-08-25T16:25:53Z", - "disconnection_time": "2022-08-25T16:36:35Z", - "name": "Debian", - "status": "active", - "manager": "wazuh-manager-master-0", - "node_name": "master", - "group": [ - "default", - "debian" - ], - "lastKeepAlive": "2022-09-12T08:48:40Z", - "version": "Wazuh v4.3.7" - } + "data": { + "affected_items": [ + { + "os": { + "arch": "x86_64", + "codename": "stretch", + "major": "9", + "name": "Debian GNU/Linux", + "platform": "debian", + "uname": "Linux |ip-10-0-1-106 |4.9.0-9-amd64 |#1 SMP Debian 4.9.168-1+deb9u2 (2019-05-13) |x86_64", + "version": "9" + }, + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "configSum": "6f4293818ef64291ca53727fb9ab8958", + "mergedSum": "7976a83d1aebcca09bc14459b5518ed5", + "id": "001", + "registerIP": "any", + "dateAdd": "2022-08-25T16:25:53Z", + "disconnection_time": "2022-08-25T16:36:35Z", + "name": "Debian", + "status": "active", + "manager": "wazuh-manager-master-0", + "node_name": "master", + "group": [ + "default", + "debian" ], - "total_affected_items": 1, - "total_failed_items": 0, - "failed_items": [] - }, - "message": "All selected agents information was returned", - "error": 0 -} \ No newline at end of file + "lastKeepAlive": "2022-09-12T08:48:40Z", + "version": "Wazuh v4.3.7" + } + ], + "total_affected_items": 1, + "total_failed_items": 0, + "failed_items": [] + }, + "message": "All selected agents information was returned", + "error": 0 +} diff --git a/docker/imposter/agents/agents.json b/docker/imposter/agents/agents.json index 07a6f136f2..531599f862 100644 --- a/docker/imposter/agents/agents.json +++ b/docker/imposter/agents/agents.json @@ -1,114 +1,121 @@ { - "data": { - "affected_items": [ - { - "os": { - "arch": "x86_64", - "major": "2", - "name": "Amazon Linux", - "platform": "amzn", - "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", - "version": "2" - }, - "group": [ - "default", - "test", - "test2", - "test3", - "test4", - "test5", - "test6", - "test7", - "test8", - "test9", - "test10" - ], - "ip": "127.0.0.1", - "id": "000", - "registerIP": "127.0.0.1", - "dateAdd": "2022-08-25T16:17:46Z", - "name": "wazuh-manager-master-0", - "status": "active", - "manager": "wazuh-manager-master-0", - "node_name": "master", - "lastKeepAlive": "9999-12-31T23:59:59Z", - "version": "Wazuh v4.4.0", - "group_config_status": "synced" - },{ - "os": { - "arch": "x86_64", - "major": "2", - "name": "Amazon Linux", - "platform": "amzn", - "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", - "version": "2" - }, - "group": [ - "default", - "test", - "test2", - "test3", - "test4", - "test5" - ], - "ip": "127.0.0.1", - "id": "001", - "registerIP": "127.0.0.1", - "dateAdd": "2022-08-25T16:17:46Z", - "name": "wazuh-manager-master-0", - "status": "active", - "manager": "wazuh-manager-master-0", - "node_name": "master", - "lastKeepAlive": "9999-12-31T23:59:59Z", - "version": "Wazuh v4.4.0", - "group_config_status": "not synced" - },{ - "os": { - "arch": "x86_64", - "major": "2", - "name": "Amazon Linux", - "platform": "amzn", - "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", - "version": "2" - }, - "group": ["default", "test", "test2"], - "ip": "127.0.0.1", - "id": "002", - "registerIP": "127.0.0.1", - "dateAdd": "2022-08-25T16:17:46Z", - "name": "wazuh-manager-master-0", - "status": "active", - "manager": "wazuh-manager-master-0", - "node_name": "master", - "lastKeepAlive": "9999-12-31T23:59:59Z", - "version": "Wazuh v4.4.0", - "group_config_status": "synced" - },{ - "os": { - "arch": "x86_64", - "major": "2", - "name": "Amazon Linux", - "platform": "amzn", - "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", - "version": "2" - }, - "ip": "127.0.0.1", - "id": "003", - "registerIP": "127.0.0.1", - "dateAdd": "2022-08-25T16:17:46Z", - "name": "wazuh-manager-master-0", - "status": "active", - "manager": "wazuh-manager-master-0", - "node_name": "master", - "lastKeepAlive": "9999-12-31T23:59:59Z", - "version": "Wazuh v4.4.0", - "group_config_status": "not synced" - } + "data": { + "affected_items": [ + { + "os": { + "arch": "x86_64", + "major": "2", + "name": "Amazon Linux", + "platform": "amzn", + "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", + "version": "2" + }, + "group": [ + "default", + "test", + "test2", + "test3", + "test4", + "test5", + "test6", + "test7", + "test8", + "test9", + "test10" ], - "total_affected_items": 4, - "total_failed_items": 0, - "failed_items": [] - }, - "message": "All selected agents information was returned", - "error": 0 + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "id": "000", + "registerIP": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "dateAdd": "2022-08-25T16:17:46Z", + "name": "wazuh-manager-master-0", + "status": "active", + "manager": "wazuh-manager-master-0", + "node_name": "master", + "lastKeepAlive": "9999-12-31T23:59:59Z", + "version": "Wazuh v4.4.0", + "group_config_status": "synced" + }, + { + "os": { + "arch": "x86_64", + "major": "2", + "name": "Amazon Linux", + "platform": "amzn", + "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", + "version": "2" + }, + "group": [ + "default", + "test", + "test2", + "test3", + "test4", + "test5" + ], + "ip": "FE80:1234:2223:A000:2202:B3FF:FE1E:8329", + "id": "001", + "registerIP": "FE80:1234:2223:A000:2202:B3FF:FE1E:8329", + "dateAdd": "2022-08-25T16:17:46Z", + "name": "wazuh-manager-master-0", + "status": "active", + "manager": "wazuh-manager-master-0", + "node_name": "master", + "lastKeepAlive": "9999-12-31T23:59:59Z", + "version": "Wazuh v4.4.0", + "group_config_status": "not synced" + }, + { + "os": { + "arch": "x86_64", + "major": "2", + "name": "Amazon Linux", + "platform": "amzn", + "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", + "version": "2" + }, + "group": [ + "default", + "test", + "test2" + ], + "ip": "127.0.0.1", + "id": "002", + "registerIP": "127.0.0.1", + "dateAdd": "2022-08-25T16:17:46Z", + "name": "wazuh-manager-master-0", + "status": "active", + "manager": "wazuh-manager-master-0", + "node_name": "master", + "lastKeepAlive": "9999-12-31T23:59:59Z", + "version": "Wazuh v4.4.0", + "group_config_status": "synced" + }, + { + "os": { + "arch": "x86_64", + "major": "2", + "name": "Amazon Linux", + "platform": "amzn", + "uname": "Linux |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64", + "version": "2" + }, + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "id": "003", + "registerIP": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "dateAdd": "2022-08-25T16:17:46Z", + "name": "wazuh-manager-master-0", + "status": "active", + "manager": "wazuh-manager-master-0", + "node_name": "master", + "lastKeepAlive": "9999-12-31T23:59:59Z", + "version": "Wazuh v4.4.0", + "group_config_status": "not synced" + } + ], + "total_affected_items": 4, + "total_failed_items": 0, + "failed_items": [] + }, + "message": "All selected agents information was returned", + "error": 0 } diff --git a/docker/imposter/agents/group.json b/docker/imposter/agents/group.json new file mode 100644 index 0000000000..a05fb465ba --- /dev/null +++ b/docker/imposter/agents/group.json @@ -0,0 +1,95 @@ +{ + "data": { + "affected_items": [ + { + "os": { + "arch": "x86_64", + "codename": "Focal Fossa", + "major": 20, + "minor": 4, + "name": "Ubuntu", + "platform": "ubuntu", + "uname": "Linux |b2497efbf876 |5.8.0-45-generic |#51~20.04.1-Ubuntu SMP Tue Feb 23 13:46:31 UTC 2021 |x86_64", + "version": "20.04.2 LTS" + }, + "mergedSum": "2c769b2ea138d472ee8f1ba23412b5d4", + "node_name": "worker1", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "id": 4, + "manager": "wazuh-worker1", + "group": [ + "default", + "group1" + ], + "name": "b2497efbf876", + "configSum": "052374472f3a0d5c8508241dcc455ea7", + "status": "active", + "dateAdd": "2021-05-27T09:14:19Z", + "registerIP": "any", + "lastKeepAlive": "2021-05-27T09:23:59Z", + "version": "Wazuh v4.3.0" + }, + { + "os": { + "arch": "x86_64", + "codename": "Focal Fossa", + "major": 20, + "minor": 4, + "name": "Ubuntu", + "platform": "ubuntu", + "uname": "Linux |600e27371700 |5.8.0-45-generic |#51~20.04.1-Ubuntu SMP Tue Feb 23 13:46:31 UTC 2021 |x86_64", + "version": "20.04.2 LTS" + }, + "mergedSum": "9a016508cea1e997ab8569f5cfab30f5", + "node_name": "worker1", + "ip": "FE80:1234:2223:A000:2202:B3FF:FE1E:8329", + "id": 5, + "manager": "wazuh-worker1", + "group": [ + "default", + "group2" + ], + "name": "Infinity", + "configSum": "ab73af41699f13fdd81903b5f23d8d00", + "status": "active", + "dateAdd": "2021-05-27T09:14:19Z", + "registerIP": "any", + "lastKeepAlive": "2021-05-27T09:23:52Z", + "version": "Wazuh v4.3.0" + }, + { + "os": { + "arch": "x86_64", + "codename": "Focal Fossa", + "major": 20, + "minor": 4, + "name": "Ubuntu", + "platform": "ubuntu", + "uname": "Linux |4bdac19ce5e3 |5.8.0-45-generic |#51~20.04.1-Ubuntu SMP Tue Feb 23 13:46:31 UTC 2021 |x86_64", + "version": "20.04.2 LTS" + }, + "mergedSum": "9a016508cea1e997ab8569f5cfab30f5", + "node_name": "worker2", + "ip": "172.20.0.10", + "id": 6, + "manager": "wazuh-worker2", + "group": [ + "default", + "group3" + ], + "name": "4bdac19ce5e3", + "configSum": "ab73af41699f13fdd81903b5f23d8d00", + "status": "active", + "dateAdd": "2021-05-27T09:14:19Z", + "registerIP": "any", + "lastKeepAlive": "2021-05-27T09:23:52Z", + "version": "Wazuh v4.3.0" + } + ], + "total_affected_items": 3, + "total_failed_items": 0, + "failed_items": [] + }, + "message": "All selected agents information was returned", + "error": 0 +} diff --git a/docker/imposter/cluster/cluster_node_info.json b/docker/imposter/cluster/cluster_node_info.json index a12f21a54a..8456a62b26 100644 --- a/docker/imposter/cluster/cluster_node_info.json +++ b/docker/imposter/cluster/cluster_node_info.json @@ -1,99 +1,102 @@ { - "data": { - "affected_items": [ - { - "name": "master-node", - "type": "master", - "version": "4.3.0", - "ip": "wazuh-master", - "connection_date": "2020-05-27T10:50:49.175Z" - }, - { - "name": "worker1", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.7", - "connection_date": "2021-05-27T10:50:51.342Z" - }, - { - "name": "worker2", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.6", - "connection_date": "2021-05-27T10:48:54.093Z" - },{ - "name": "worker3", - "type": "worker", - "version": "4.3.0", - "ip": "wazuh-worker", - "connection_date": "2021-05-27T10:50:51.342Z" - }, - { - "name": "worker4", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.7", - "connection_date": "2021-05-27T10:50:51.342Z" - }, - { - "name": "worker5", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.6", - "connection_date": "2021-05-27T10:48:54.093Z" - },{ - "name": "worker6", - "type": "worker", - "version": "4.3.0", - "ip": "wazuh-worker", - "connection_date": "2021-05-27T10:50:51.342Z" - }, - { - "name": "worker7", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.7", - "connection_date": "2021-05-27T10:48:54.093Z" - }, - { - "name": "worker8", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.6", - "connection_date": "2021-05-27T10:50:51.342Z" - }, - { - "name": "worker9", - "type": "worker", - "version": "4.3.0", - "ip": "wazuh-worker", - "connection_date": "2019-05-27T10:48:54.093Z" - }, - { - "name": "worker10", - "type": "worker", - "version": "4.3.0", - "ip": "wazuh-worker", - "connection_date": "2022-05-27T10:48:54.093Z" - }, - { - "name": "worker11", - "type": "worker", - "version": "4.3.0", - "ip": "172.26.0.6", - "connection_date": "2019-05-27T10:48:54.093Z" - },{ - "name": "worker12", - "type": "worker", - "version": "4.3.0", - "ip": "wazuh-worker", - "connection_date": "2021-05-27T10:50:51.342Z" - } - ], - "total_affected_items": 3, - "total_failed_items": 0, - "failed_items": [] - }, - "message": "All selected nodes information was returned", - "error": 0 -} \ No newline at end of file + "data": { + "affected_items": [ + { + "name": "master-node", + "type": "master", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:49.175Z" + }, + { + "name": "worker1", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:1234:2223:A000:2202:B3FF:FE1E:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + }, + { + "name": "worker2", + "type": "worker", + "version": "4.3.0", + "ip": "127.0.0.2", + "connection_date": "2021-05-27T10:48:54.093Z" + }, + { + "name": "worker3", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + }, + { + "name": "worker4", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + }, + { + "name": "worker5", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:48:54.093Z" + }, + { + "name": "worker6", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + }, + { + "name": "worker7", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:48:54.093Z" + }, + { + "name": "worker8", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + }, + { + "name": "worker9", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2019-05-27T10:48:54.093Z" + }, + { + "name": "worker10", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2022-05-27T10:48:54.093Z" + }, + { + "name": "worker11", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2019-05-27T10:48:54.093Z" + }, + { + "name": "worker12", + "type": "worker", + "version": "4.3.0", + "ip": "FE80:0034:0223:A000:0002:B3FF:0000:8329", + "connection_date": "2021-05-27T10:50:51.342Z" + } + ], + "total_affected_items": 3, + "total_failed_items": 0, + "failed_items": [] + }, + "message": "All selected nodes information was returned", + "error": 0 +} diff --git a/docker/imposter/syscollector/netaddr.js b/docker/imposter/syscollector/netaddr.js new file mode 100644 index 0000000000..6cccddf671 --- /dev/null +++ b/docker/imposter/syscollector/netaddr.js @@ -0,0 +1,29 @@ +var data = { + data: { + affected_items: [ + { + address: '172.26.0.7', + iface: 'eth0', + netmask: '255.255.0.0', + broadcast: '172.26.255.255', + proto: 'ipv4', + agent_id: 1, + }, + { + address: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + iface: 'eth0', + netmask: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + broadcast: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + proto: 'ipv6', + agent_id: 1, + }, + ], + total_affected_items: 1, + total_failed_items: 0, + failed_items: [], + }, + message: 'All specified syscollector information was returned', + error: 0, +}; + +respond().withStatusCode(200).withData(JSON.stringify(data)); diff --git a/docker/imposter/syscollector/ports.js b/docker/imposter/syscollector/ports.js new file mode 100644 index 0000000000..f81206de5e --- /dev/null +++ b/docker/imposter/syscollector/ports.js @@ -0,0 +1,192 @@ +var agentID = context.request.pathParams.agent_id; + +var ipv4_01 = { + local: { + ip: '0.0.0.0', + port: 46841, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 0, + time: '2021-05-28T11:16:14Z', + }, + inode: 12387152, + rx_queue: 0, + protocol: 'tcp', + pid: 0, + tx_queue: 0, + agent_id: agentID, +}; + +var ipv4_02 = { + local: { + ip: '0.0.0.0', + port: 80, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 0, + time: '2021-05-28T11:16:14Z', + }, + inode: 12387152, + rx_queue: 0, + protocol: 'tcp', + pid: 0, + tx_queue: 0, + agent_id: agentID, +}; + +var ipv4_03 = { + local: { + ip: '0.0.0.0', + port: 443, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 0, + time: '2021-05-28T11:16:14Z', + }, + state: 'listening', + inode: 12387152, + rx_queue: 0, + protocol: 'tcp', + pid: 0, + tx_queue: 0, + agent_id: agentID, +}; + +var ipv6_01 = { + local: { + ip: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + port: 1515, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 315935312, + time: '2020-04-15T11:02:07Z', + }, + state: 'listening', + inode: 12397153, + rx_queue: 0, + protocol: 'tcp', + tx_queue: 0, + agent_id: agentID, +}; + +var ipv6_02 = { + local: { + ip: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + port: 80, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 315935312, + time: '2020-04-15T11:02:07Z', + }, + state: 'listening', + inode: 12397153, + rx_queue: 0, + protocol: 'tcp', + tx_queue: 0, + agent_id: agentID, +}; + +var ipv6_03 = { + local: { + ip: 'FE80:0034:0223:A000:0002:B3FF:0000:8329', + port: 443, + }, + remote: { + ip: '0.0.0.0', + port: 0, + }, + scan: { + id: 315935312, + time: '2020-04-15T11:02:07Z', + }, + state: 'listening', + inode: 12397153, + rx_queue: 0, + protocol: 'tcp', + tx_queue: 0, + agent_id: agentID, +}; + +var affected_items_agents = { + '001': [ + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv6_01, + ipv4_03, + ipv4_01, + ipv4_02, + ipv4_03, + ], + '002': [ipv4_01, ipv4_02, ipv4_03], + '003': [ipv6_01, ipv6_02, ipv6_03], +}; + +var affected_items = + affected_items_agents[agentID] || affected_items_agents['001']; +var total_affected_items = affected_items.length; + +var limit = context.request.queryParams.limit; +var offset = context.request.queryParams.offset; + +if (offset || limit) { + affected_items = affected_items.slice(offset, offset + limit); +} + +var response = { + data: { + affected_items: affected_items, + total_affected_items: total_affected_items, + total_failed_items: 0, + failed_items: [], + }, + message: 'All specified syscollector information was returned', + error: 0, +}; + +respond().withStatusCode(200).withData(JSON.stringify(response)); diff --git a/docker/imposter/wazuh-config.yml b/docker/imposter/wazuh-config.yml index 4c9c2d65ed..1cc5ca24b3 100755 --- a/docker/imposter/wazuh-config.yml +++ b/docker/imposter/wazuh-config.yml @@ -370,6 +370,9 @@ resources: # Get agents in a group - method: GET path: /groups/{group_id}/agents + response: + statusCode: 200 + staticFile: agents/group.json # Get group configuration - method: GET @@ -805,6 +808,9 @@ resources: # Get agent netaddr - method: GET path: /syscollector/{agent_id}/netaddr + response: + statusCode: 200 + scriptFile: syscollector/netaddr.js # Get agent netiface - method: GET @@ -825,6 +831,9 @@ resources: # Get agent ports - method: GET path: /syscollector/{agent_id}/ports + response: + statusCode: 200 + scriptFile: syscollector/ports.js # Get agent processes - method: GET diff --git a/public/components/agents/syscollector/components/syscollector-table.tsx b/public/components/agents/syscollector/components/syscollector-table.tsx index 4df55316fd..e5e5b0056f 100644 --- a/public/components/agents/syscollector/components/syscollector-table.tsx +++ b/public/components/agents/syscollector/components/syscollector-table.tsx @@ -1,18 +1,33 @@ -import React, { useState } from "react"; -import { EuiPanel, EuiFlexGroup, EuiButtonEmpty, EuiFlexItem, EuiText, EuiLoadingSpinner, EuiFieldSearch, EuiHorizontalRule, EuiIcon, EuiBasicTable } from "@elastic/eui"; +import React, { useState } from 'react'; +import { + EuiPanel, + EuiFlexGroup, + EuiButtonEmpty, + EuiFlexItem, + EuiText, + EuiLoadingSpinner, + EuiFieldSearch, + EuiHorizontalRule, + EuiIcon, + EuiBasicTable, +} from '@elastic/eui'; import { useApiRequest } from '../../../common/hooks/useApiRequest'; import { KeyEquivalence } from '../../../../../common/csv-key-equivalence'; import { AppState } from '../../../../react-services/app-state'; - export function SyscollectorTable({ tableParams }) { - const [params, setParams] = useState<{ limit: number, offset: number, select:string, q?: string}>({ + const [params, setParams] = useState<{ + limit: number; + offset: number; + select: string; + q?: string; + }>({ limit: 10, offset: 0, - select: tableParams.columns.map(({id}) => id).join(",") + select: tableParams.columns.map(({ id }) => id).join(','), }); const [pageIndex, setPageIndex] = useState(0); - const [searchBarValue, setSearchBarValue] = useState(""); + const [searchBarValue, setSearchBarValue] = useState(''); const [pageSize, setPageSize] = useState(10); const [sortField, setSortField] = useState(''); const [timerDelaySearch, setTimerDelaySearch] = useState(); @@ -26,17 +41,16 @@ export function SyscollectorTable({ tableParams }) { setPageSize(pageSize); setSortField(sortField); setSortDirection(sortDirection); - const field = (sortField === 'os_name') ? '' : sortField; - const direction = (sortDirection === 'asc') ? '+' : '-'; + const field = sortField === 'os_name' ? '' : sortField; + const direction = sortDirection === 'asc' ? '+' : '-'; const newParams = { ...params, limit: pageSize, offset: Math.floor((pageIndex * pageSize) / params.limit) * params.limit, - ...(!!field ? { sort: `${direction}${field}` } : {}) - } + ...(!!field ? { sort: `${direction}${field}` } : {}), + }; setParams(newParams); - }; const buildColumns = () => { @@ -63,51 +77,70 @@ export function SyscollectorTable({ tableParams }) { sort: { field: sortField, direction: sortDirection, - } + }, }; - const onChange = (e) => { + const onChange = e => { const value = e.target.value; setSearchBarValue(value); timerDelaySearch && clearTimeout(timerDelaySearch); const timeoutId = setTimeout(() => { - const { q, ...rest} = params; + const { q, ...rest } = params; const newParams = { ...rest, - ...(value ? { - q: tableParams.columns.map(({id}) => `${id}~${value}`).join(",") - }: {}) - }; + ...(value + ? { + q: tableParams.columns + .map(({ id }) => `${id}~${value}`) + .join(','), + } + : {}), + }; setParams(newParams); setPageIndex(0); - }, 400) + }, 400); setTimerDelaySearch(timeoutId); - } + }; const getTotal = () => { if (loading) - return <>{'( '}{' )'}; - else - return `(${data.total_affected_items})`; - } + return ( + <> + {'( '} + + {' )'} + + ); + else return `(${data.total_affected_items})`; + }; const downloadCsv = async () => { await AppState.downloadCsv( tableParams.path, tableParams.exportFormatted, - !!params.q ? [{ name: 'q', value: params.q }] : [] - ) - } + !!params.q ? [{ name: 'q', value: params.q }] : [], + ); + }; return ( - + -   {tableParams.title} {tableParams.hasTotal ? getTotal() : ''} + + {' '} + {' '} +  {' '} + + {tableParams.title} {tableParams.hasTotal ? getTotal() : ''} + {' '} + - - {tableParams.searchBar && + + {tableParams.searchBar && ( - } + )} - + Download CSV diff --git a/public/components/common/welcome/agents-info.js b/public/components/common/welcome/agents-info.js index f570fc89e5..17a57793fd 100644 --- a/public/components/common/welcome/agents-info.js +++ b/public/components/common/welcome/agents-info.js @@ -12,18 +12,12 @@ * Find more information about this on the LICENSE file. */ import React, { Component, Fragment } from 'react'; -import { - EuiStat, - EuiFlexItem, - EuiFlexGroup, - EuiBadge -} from '@elastic/eui'; +import { EuiFlexItem, EuiFlexGroup, EuiBadge } from '@elastic/eui'; import { WzRequest } from '../../../react-services/wz-request'; import { formatUIDate } from '../../../react-services/time-service'; - import WzTextWithTooltipIfTruncated from '../wz-text-with-tooltip-if-truncated'; import { WzStat } from '../../wz-stat'; -import { GroupTruncate } from '../util/agent-group-truncate' +import { GroupTruncate } from '../util/agent-group-truncate'; import { AgentStatus } from '../../agents/agent_status'; export class AgentInfo extends Component { @@ -33,11 +27,11 @@ export class AgentInfo extends Component { this.state = {}; } - async componentDidMount() { const managerVersion = await WzRequest.apiReq('GET', '/', {}); this.setState({ - managerVersion: (((managerVersion || {}).data || {}).data || {}).api_version || {} + managerVersion: + (((managerVersion || {}).data || {}).data || {}).api_version || {}, }); } @@ -53,13 +47,14 @@ export class AgentInfo extends Component { icon = 'apple'; } - return + return ( + + ); } - addTextPlatformRender(agent, style) { const checkField = field => { return field !== undefined ? field : '-'; @@ -73,30 +68,32 @@ export class AgentInfo extends Component { const osName = os_name === '- -' ? '-' : os_name; return ( - - {this.getPlatformIcon(this.props.agent)} - {' '}{osName} + + {this.getPlatformIcon(this.props.agent)} {osName} - ) + ); } addGroupsRender(agent) { // this was rendered with a EuiHealth, but EuiHealth has a div wrapper, and this section is rendered within a

tag.

tags aren't allowed within

tags. return ( - { - agent.group.map((group, key) => ( - this.props.goGroups(this.props.agent, key)}> - {group} - - )) - } + {agent.group.map((group, key) => ( + this.props.goGroups(this.props.agent, key)} + > + {group} + + ))} - ) + ); } buildStats(items) { @@ -105,7 +102,10 @@ export class AgentInfo extends Component { }; const stats = items.map(item => { // We add tooltipProps, so that the ClusterNode and Operating System fields occupy their space and do not exceed this, overlapping with the one on the right - const tooltipProps = item.description === 'Cluster node' ? { anchorClassName: 'wz-width-100'} : {}; + const tooltipProps = + item.description === 'Cluster node' + ? { anchorClassName: 'wz-width-100' } + : {}; return ( + {...this.props} + /> ) : item.description === 'Operating system' ? ( this.addTextPlatformRender(this.props.agent, item.style) ) : item.description === 'Status' ? ( - + ) : ( - + {checkField(item.title)} ) } description={item.description} - titleSize="xs" + titleSize='xs' /> ); @@ -145,25 +153,64 @@ export class AgentInfo extends Component { if (this.props.isCondensed) { arrayStats = [ { title: agent.id, description: 'ID', style: { maxWidth: 100 } }, - { title: agent.status, description: 'Status', style: { maxWidth: 150 } }, - { title: agent.version, description: 'Version', style: { maxWidth: 150 } }, + { + title: agent.status, + description: 'Status', + style: { maxWidth: 150 }, + }, + { + title: agent.version, + description: 'Version', + style: { maxWidth: 150 }, + }, { title: agent.name, description: 'Operating system', - style: { minWidth: 200, maxWidth: 200 } - } + style: { minWidth: 200, maxWidth: 200 }, + }, ]; } else { arrayStats = [ { title: agent.id, description: 'ID', style: { minWidth: 30 } }, - { title: agent.status, description: 'Status', style: { minWidth: 130 } }, - { title: agent.ip, description: 'IP address', style: { minWidth: 80 } }, - { title: agent.version, description: 'Version', style: { minWidth: 100 } }, + { + title: agent.status, + description: 'Status', + style: { minWidth: 100 }, + }, + { + title: agent.ip, + description: 'IP address', + style: { minwidth: 150 }, + }, + { + title: agent.version, + description: 'Version', + style: { minWidth: 100 }, + }, { title: agent.group, description: 'Groups', style: { minWidth: 150 } }, - { title: agent.name, description: 'Operating system', style: { minWidth: 150 } }, - { title: agent.node_name && agent.node_name !== 'unknown' ? agent.node_name : '-', description: 'Cluster node', style: { minWidth: 120 } }, - { title: formatUIDate(agent.dateAdd), description: 'Registration date', style: { minWidth: 180 } }, - { title: formatUIDate(agent.lastKeepAlive), description: 'Last keep alive', style: { minWidth: 180 } }, + { + title: agent.name, + description: 'Operating system', + style: { minWidth: 150 }, + }, + { + title: + agent.node_name && agent.node_name !== 'unknown' + ? agent.node_name + : '-', + description: 'Cluster node', + style: { minWidth: 120 }, + }, + { + title: formatUIDate(agent.dateAdd), + description: 'Registration date', + style: { minWidth: 180 }, + }, + { + title: formatUIDate(agent.lastKeepAlive), + description: 'Last keep alive', + style: { minWidth: 180 }, + }, ]; } @@ -173,7 +220,11 @@ export class AgentInfo extends Component { return ( - + {stats} diff --git a/public/components/management/cluster/node-list.tsx b/public/components/management/cluster/node-list.tsx index 4a5288db33..580c747d14 100644 --- a/public/components/management/cluster/node-list.tsx +++ b/public/components/management/cluster/node-list.tsx @@ -1,113 +1,128 @@ -import React, { Component } from 'react'; -import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiButtonIcon, EuiTitle, EuiInMemoryTable, EuiFieldSearch } from '@elastic/eui'; +import React, { Component, Fragment } from 'react'; +import { + EuiPanel, + EuiFlexGroup, + EuiFlexItem, + EuiToolTip, + EuiButtonIcon, + EuiTitle, + EuiInMemoryTable, + EuiFieldSearch, +} from '@elastic/eui'; import { WzRequest } from '../../../react-services/wz-request'; import { withErrorBoundary } from '../../common/hocs'; -export const NodeList = withErrorBoundary (class NodeList extends Component { +export const NodeList = withErrorBoundary( + class NodeList extends Component { constructor(props) { - super(props); - this.state = { - nodes: [], - loading: false - }; + super(props); + this.state = { + nodes: [], + loading: false, + }; } async componentDidMount() { - this.search(); + this.search(); } async search(searchTerm = false) { - let params = {}; - if (searchTerm) { - params.search = searchTerm; - } - this.setState({ loading: true }); - try{ - const request = await WzRequest.apiReq('GET', '/cluster/nodes', {params}); - this.setState({ nodes: (((request || {}).data || {}).data || {}).affected_items || [], loading: false }); - }catch(error){ - this.setState({ loading: false }); - } + let params = {}; + if (searchTerm) { + params.search = searchTerm; + } + this.setState({ loading: true }); + try { + const request = await WzRequest.apiReq('GET', '/cluster/nodes', { + params, + }); + this.setState({ + nodes: (((request || {}).data || {}).data || {}).affected_items || [], + loading: false, + }); + } catch (error) { + this.setState({ loading: false }); + } } - render() { - const columns = [ - { - field: 'name', - name: 'Name', - sortable: true, - truncateText: true, - }, - { - field: 'version', - name: 'Version', - sortable: true, - }, - { - field: 'ip', - name: 'IP address', - sortable: true, - }, - { - field: 'type', - name: 'Type', - sortable: true, - } - ]; + const columns = [ + { + field: 'name', + name: 'Name', + sortable: true, + }, + { + field: 'version', + name: 'Version', + sortable: true, + }, + { + field: 'ip', + name: 'IP address', + sortable: true, + }, + { + field: 'type', + name: 'Type', + sortable: true, + }, + ]; - const sorting = { - sort: { - field: 'name', - direction: 'asc', - }, - }; - return ( - - - - - - - this.props.goBack()} - /> - - - - -

Nodes

- - - - - - - - this.search(e)} - isClearable={true} - fullWidth={true} - aria-label="Filter" - /> - - - - - - - - - ); + const sorting = { + sort: { + field: 'name', + direction: 'asc', + }, + }; + return ( + + + + + + + this.props.goBack()} + /> + + + + +

Nodes

+
+
+
+
+
+ + + this.search(e)} + isClearable={true} + fullWidth={true} + aria-label='Filter' + /> + + + + + + + +
+ ); } -}); + }, +); diff --git a/public/controllers/agent/components/agents-table.js b/public/controllers/agent/components/agents-table.js index 55ce4d48d9..828db0afd6 100644 --- a/public/controllers/agent/components/agents-table.js +++ b/public/controllers/agent/components/agents-table.js @@ -11,7 +11,7 @@ * Find more information about this on the LICENSE file. */ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { EuiBasicTable, @@ -31,12 +31,20 @@ import { import { getToasts } from '../../../kibana-services'; import { AppNavigate } from '../../../react-services/app-navigate'; import { GroupTruncate } from '../../../components/common/util'; -import { WzSearchBar, filtersToObject } from '../../../components/wz-search-bar'; +import { + WzSearchBar, + filtersToObject, +} from '../../../components/wz-search-bar'; import { getAgentFilterValues } from '../../../controllers/management/components/management/groups/get-agents-filters-values'; import { WzButtonPermissions } from '../../../components/common/permissions/button'; import { formatUIDate } from '../../../react-services/time-service'; import { withErrorBoundary } from '../../../components/common/hocs'; -import { API_NAME_AGENT_STATUS, UI_LOGGER_LEVELS, UI_ORDER_AGENT_STATUS, AGENT_SYNCED_STATUS } from '../../../../common/constants'; +import { + API_NAME_AGENT_STATUS, + UI_LOGGER_LEVELS, + UI_ORDER_AGENT_STATUS, + AGENT_SYNCED_STATUS, +} from '../../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; import { getErrorOrchestrator } from '../../../react-services/common-services'; import { AgentStatus } from '../../../components/agents/agent_status'; @@ -60,7 +68,9 @@ export const AgentsTable = withErrorBoundary( purgeModal: false, isFilterColumnOpen: false, filters: sessionStorage.getItem('agents_preview_selected_options') - ? JSON.parse(sessionStorage.getItem('agents_preview_selected_options')) + ? JSON.parse( + sessionStorage.getItem('agents_preview_selected_options'), + ) : [], }; this.suggestions = [ @@ -83,84 +93,96 @@ export const AgentsTable = withErrorBoundary( label: 'os.platform', description: 'Filter by operating system platform', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('os.platform', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('os.platform', value, { q: 'id!=000' }), }, { type: 'q', label: 'ip', description: 'Filter by agent IP address', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('ip', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('ip', value, { q: 'id!=000' }), }, { type: 'q', label: 'name', description: 'Filter by agent name', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('name', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('name', value, { q: 'id!=000' }), }, { type: 'q', label: 'id', description: 'Filter by agent id', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('id', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('id', value, { q: 'id!=000' }), }, { type: 'q', label: 'group', description: 'Filter by agent group', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('group', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('group', value, { q: 'id!=000' }), }, { type: 'q', label: 'node_name', description: 'Filter by node name', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('node_name', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('node_name', value, { q: 'id!=000' }), }, { type: 'q', label: 'manager', description: 'Filter by manager', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('manager', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('manager', value, { q: 'id!=000' }), }, { type: 'q', label: 'version', description: 'Filter by agent version', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('version', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('version', value, { q: 'id!=000' }), }, { type: 'q', label: 'configSum', description: 'Filter by agent config sum', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('configSum', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('configSum', value, { q: 'id!=000' }), }, { type: 'q', label: 'mergedSum', description: 'Filter by agent merged sum', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('mergedSum', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('mergedSum', value, { q: 'id!=000' }), }, { type: 'q', label: 'dateAdd', description: 'Filter by add date', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('dateAdd', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('dateAdd', value, { q: 'id!=000' }), }, { type: 'q', label: 'lastKeepAlive', description: 'Filter by last keep alive', operators: ['=', '!='], - values: async (value) => getAgentFilterValues('lastKeepAlive', value, { q: 'id!=000' }), + values: async value => + getAgentFilterValues('lastKeepAlive', value, { q: 'id!=000' }), }, ]; this.downloadCsv.bind(this); @@ -220,17 +242,25 @@ export const AgentsTable = withErrorBoundary( const selectFieldsList = this.defaultColumns .filter(field => field.field != 'actions') .map(field => field.field.replace('os_', 'os.')); // "os_name" subfield should be specified as 'os.name' - const selectFields = [...selectFieldsList, 'os.platform', 'os.uname', 'os.version'].join(','); // Add version and uname fields to render the OS icon and version in the table - - const rawAgents = await this.props.wzReq('GET', '/agents', { params: { ...this.buildFilter(), select: selectFields } }); - const formatedAgents = (((rawAgents || {}).data || {}).data || {}).affected_items.map( - this.formatAgent.bind(this) - ); + const selectFields = [ + ...selectFieldsList, + 'os.platform', + 'os.uname', + 'os.version', + ].join(','); // Add version and uname fields to render the OS icon and version in the table + + const rawAgents = await this.props.wzReq('GET', '/agents', { + params: { ...this.buildFilter(), select: selectFields }, + }); + const formatedAgents = ( + ((rawAgents || {}).data || {}).data || {} + ).affected_items.map(this.formatAgent.bind(this)); this._isMount && this.setState({ agents: formatedAgents, - totalItems: (((rawAgents || {}).data || {}).data || {}).total_affected_items, + totalItems: (((rawAgents || {}).data || {}).data || {}) + .total_affected_items, isLoading: false, }); } catch (error) { @@ -250,7 +280,6 @@ export const AgentsTable = withErrorBoundary( } } - buildFilter() { const { pageIndex, pageSize, filters } = this.state; @@ -280,11 +309,15 @@ export const AgentsTable = withErrorBoundary( } formatAgent(agent) { - const checkField = (field) => { + const checkField = field => { return field !== undefined ? field : '-'; }; - const agentVersion = agent.version !== undefined ? agent.version.split(' ')[1] : '-'; - const node_name = agent.node_name && agent.node_name !== 'unknown' ? agent.node_name : '-'; + const agentVersion = + agent.version !== undefined ? agent.version.split(' ')[1] : '-'; + const node_name = + agent.node_name && agent.node_name !== 'unknown' + ? agent.node_name + : '-'; return { id: agent.id, @@ -297,7 +330,9 @@ export const AgentsTable = withErrorBoundary( version: agentVersion, node_name: node_name, dateAdd: agent.dateAdd ? formatUIDate(agent.dateAdd) : '-', - lastKeepAlive: agent.lastKeepAlive ? formatUIDate(agent.lastKeepAlive) : '-', + lastKeepAlive: agent.lastKeepAlive + ? formatUIDate(agent.lastKeepAlive) + : '-', actions: agent, upgrading: false, }; @@ -306,28 +341,34 @@ export const AgentsTable = withErrorBoundary( actionButtonsRender(agent) { return (
- + { + onClick={ev => { ev.stopPropagation(); this.props.clickAction(agent, 'default'); }} - iconType="eye" + iconType='eye' color={'primary'} - aria-label="Open summary panel for this agent" + aria-label='Open summary panel for this agent' />   {agent.status !== API_NAME_AGENT_STATUS.NEVER_CONNECTED && ( - + { + onClick={ev => { ev.stopPropagation(); this.props.clickAction(agent, 'configuration'); }} color={'primary'} - iconType="wrench" - aria-label="Open configuration for this agent" + iconType='wrench' + aria-label='Open configuration for this agent' /> )} @@ -337,7 +378,7 @@ export const AgentsTable = withErrorBoundary( addIconPlatformRender(agent) { let icon = false; - const checkField = (field) => { + const checkField = field => { return field !== undefined ? field : '-'; }; const os = (agent || {}).os; @@ -350,16 +391,16 @@ export const AgentsTable = withErrorBoundary( icon = 'apple'; } const os_name = - checkField(agent?.os?.name) + - ' ' + - checkField(agent?.os?.version); + checkField(agent?.os?.name) + ' ' + checkField(agent?.os?.version); return ( - - {' '} + + + + {' '} {os_name === '- -' ? '-' : os_name} ); @@ -376,8 +417,8 @@ export const AgentsTable = withErrorBoundary( downloadCsv = () => { const filters = this.buildFilter(); const formatedFilters = Object.keys(filters) - .filter((field) => !['limit', 'offset', 'sort'].includes(field)) - .map((field) => ({ name: field, value: filters[field] })); + .filter(field => !['limit', 'offset', 'sort'].includes(field)) + .map(field => ({ name: field, value: filters[field] })); this.props.downloadCsv(formatedFilters); }; @@ -391,14 +432,14 @@ export const AgentsTable = withErrorBoundary( return ( <> - + Export formatted - + - + @@ -423,11 +464,13 @@ export const AgentsTable = withErrorBoundary( } else if (selectedItems.length === pageSize) { return (
- + @@ -435,7 +478,7 @@ export const AgentsTable = withErrorBoundary( { this._isMount && - this.setState((prevState) => ({ + this.setState(prevState => ({ allSelected: !prevState.allSelected, })); }} @@ -447,18 +490,24 @@ export const AgentsTable = withErrorBoundary( - +
); } } getTableColumnsSelected() { - return JSON.parse(window.localStorage.getItem('columnsSelectedTableAgent')) || []; + return ( + JSON.parse(window.localStorage.getItem('columnsSelectedTableAgent')) || + [] + ); } setTableColumnsSelected(data) { - window.localStorage.setItem('columnsSelectedTableAgent', JSON.stringify(data)); + window.localStorage.setItem( + 'columnsSelectedTableAgent', + JSON.stringify(data), + ); } // Columns with the property truncateText: true won't wrap the text @@ -487,7 +536,7 @@ export const AgentsTable = withErrorBoundary( name: 'Group(s)', sortable: true, show: true, - render: (groups) => (groups !== '-' ? this.renderGroups(groups) : '-'), + render: groups => (groups !== '-' ? this.renderGroups(groups) : '-'), }, { field: 'os_name', @@ -526,14 +575,19 @@ export const AgentsTable = withErrorBoundary( truncateText: true, sortable: true, show: true, - render: (status) => , + render: status => ( + + ), }, { field: 'group_config_status', name: 'Synced', sortable: true, show: false, - render: (synced) => , + render: synced => , }, { align: 'right', @@ -541,7 +595,7 @@ export const AgentsTable = withErrorBoundary( field: 'actions', name: 'Actions', show: true, - render: (agent) => this.actionButtonsRender(agent), + render: agent => this.actionButtonsRender(agent), }, ]; @@ -550,15 +604,17 @@ export const AgentsTable = withErrorBoundary( if (selectedColumns.length != 0) { const newSelectedColumns = []; - selectedColumns.forEach((item) => { + selectedColumns.forEach(item => { if (item.show) { - const column = this.defaultColumns.find((column) => column.field === item.field); + const column = this.defaultColumns.find( + column => column.field === item.field, + ); newSelectedColumns.push(column); } }); return newSelectedColumns; } else { - const fieldColumns = this.defaultColumns.map((item) => { + const fieldColumns = this.defaultColumns.map(item => { return { field: item.field, name: item.name, @@ -588,9 +644,9 @@ export const AgentsTable = withErrorBoundary( this.props.addingNewAgent()} > Deploy new agent @@ -598,7 +654,7 @@ export const AgentsTable = withErrorBoundary( {formattedButton}
- +
); } @@ -611,12 +667,18 @@ export const AgentsTable = withErrorBoundary( noDeleteFiltersOnUpdateSuggests filters={this.state.filters} suggestions={this.suggestions} - onFiltersChange={(filters) => this.setState({ filters, pageIndex: 0 })} - placeholder="Filter or search agent" + onFiltersChange={filters => + this.setState({ filters, pageIndex: 0 }) + } + placeholder='Filter or search agent' /> - this.reloadAgents()}> + this.reloadAgents()} + > Refresh @@ -627,15 +689,15 @@ export const AgentsTable = withErrorBoundary( selectColumnsRender() { const columnsSelected = this.getTableColumnsSelected(); - const onChange = (optionId) => { - let item = columnsSelected.find((item) => item.field === optionId); + const onChange = optionId => { + let item = columnsSelected.find(item => item.field === optionId); item.show = !item.show; this.setTableColumnsSelected(columnsSelected); this.forceUpdate(); }; const options = () => { - return columnsSelected.map((item) => { + return columnsSelected.map(item => { return { id: item.field, label: item.name, @@ -650,7 +712,7 @@ export const AgentsTable = withErrorBoundary( @@ -661,12 +723,12 @@ export const AgentsTable = withErrorBoundary( } tableRender() { - const getRowProps = (item) => { + const getRowProps = item => { const { id } = item; return { 'data-test-subj': `row-${id}`, className: 'customRowClass', - onClick: () => { }, + onClick: () => {}, }; }; @@ -675,8 +737,11 @@ export const AgentsTable = withErrorBoundary( return; } return { - onMouseDown: (ev) => { - AppNavigate.navigateToModule(ev, 'agents', { tab: 'welcome', agent: item.id }); + onClick: ev => { + AppNavigate.navigateToModule(ev, 'agents', { + tab: 'welcome', + agent: item.id, + }); ev.stopPropagation(); }, }; @@ -695,11 +760,11 @@ export const AgentsTable = withErrorBoundary( const pagination = totalItems > 15 ? { - pageIndex: pageIndex, - pageSize: pageSize, - totalItemCount: totalItems, - pageSizeOptions: [15, 25, 50, 100], - } + pageIndex: pageIndex, + pageSize: pageSize, + totalItemCount: totalItems, + pageSizeOptions: [15, 25, 50, 100], + } : false; const sorting = { sort: { @@ -712,19 +777,19 @@ export const AgentsTable = withErrorBoundary( // Previously the tableLayout is set to "fixed" with percentage width for each column, but the use of space was not optimal. // Important: If all the columns have the truncateText property set to true, the table cannot adjust properly when the viewport size is small. return ( - + @@ -732,14 +797,16 @@ export const AgentsTable = withErrorBoundary( ); } - filterGroupBadge = (group) => { + filterGroupBadge = group => { const { filters } = this.state; - let auxFilters = filters.map((filter) => filter.value.match(/group=(.*S?)/)[1]); + let auxFilters = filters.map( + filter => filter.value.match(/group=(.*S?)/)[1], + ); if (filters.length > 0) { !auxFilters.includes(group) ? this.setState({ - filters: [...filters, { field: 'q', value: `group=${group}` }], - }) + filters: [...filters, { field: 'q', value: `group=${group}` }], + }) : false; } else { this.setState({ @@ -760,7 +827,6 @@ export const AgentsTable = withErrorBoundary( /> ); } - render() { const title = this.headRender(); const filter = this.filterBarRender(); @@ -772,8 +838,8 @@ export const AgentsTable = withErrorBoundary( return (
{filter} - - + + {title} {loadItems} {callOut} @@ -784,7 +850,7 @@ export const AgentsTable = withErrorBoundary(
); } - } + }, ); AgentsTable.propTypes = { diff --git a/public/controllers/management/components/management/configuration/client/client.js b/public/controllers/management/components/management/configuration/client/client.js index 7c569fd5e6..d5e2ada8c6 100644 --- a/public/controllers/management/components/management/configuration/client/client.js +++ b/public/controllers/management/components/management/configuration/client/client.js @@ -22,7 +22,7 @@ import WzConfigurationSettingsGroup from '../util-components/configuration-setti import { isString, renderValueOrDefault, - renderValueOrNoValue + renderValueOrNoValue, } from '../utils/utils'; import withWzConfig from '../util-hocs/wz-config'; import { webDocumentationLink } from '../../../../../../../common/services/web_documentation'; @@ -30,12 +30,12 @@ import { webDocumentationLink } from '../../../../../../../common/services/web_d const helpLinks = [ { text: 'Checking connection with manager', - href: webDocumentationLink('user-manual/agents/agent-connection.html') + href: webDocumentationLink('user-manual/agents/agent-connection.html'), }, { text: 'Client reference', - href: webDocumentationLink('user-manual/reference/ossec-conf/client.html') - } + href: webDocumentationLink('user-manual/reference/ossec-conf/client.html'), + }, ]; const mainSettings = [ @@ -44,29 +44,37 @@ const mainSettings = [ { field: 'auto_restart', label: - 'Auto-restart the agent when receiving valid configuration from manager' + 'Auto-restart the agent when receiving valid configuration from manager', }, { field: 'notify_time', - label: 'Time (in seconds) between agent checkings to the manager' + label: 'Time (in seconds) between agent checkings to the manager', }, { field: 'time-reconnect', - label: 'Time (in seconds) before attempting to reconnect' + label: 'Time (in seconds) before attempting to reconnect', }, { field: 'config-profile', label: 'Configuration profiles' }, { field: 'local_ip', - label: 'IP address used when the agent has multiple network interfaces' - } + label: 'IP address used when the agent has multiple network interfaces', + }, ]; const columns = [ { field: 'address', name: 'Address', render: renderValueOrNoValue }, { field: 'port', name: 'Port', render: renderValueOrDefault('1514') }, { field: 'protocol', name: 'Protocol', render: renderValueOrDefault('udp') }, - { field: 'max_retries', name: 'Maximum retries to connect', render: renderValueOrNoValue }, - { field: 'retry_interval', name: 'Retry interval to connect', render: renderValueOrNoValue }, + { + field: 'max_retries', + name: 'Maximum retries to connect', + render: renderValueOrNoValue, + }, + { + field: 'retry_interval', + name: 'Retry interval to connect', + render: renderValueOrNoValue, + }, ]; class WzConfigurationClient extends Component { @@ -87,8 +95,8 @@ class WzConfigurationClient extends Component { {currentConfig['agent-client'] && !isString(currentConfig['agent-client']) && ( )} diff --git a/public/controllers/management/components/management/configuration/global-configuration/global-configuration-remote.js b/public/controllers/management/components/management/configuration/global-configuration/global-configuration-remote.js index 2c0a2bddae..f72cd44fea 100644 --- a/public/controllers/management/components/management/configuration/global-configuration/global-configuration-remote.js +++ b/public/controllers/management/components/management/configuration/global-configuration/global-configuration-remote.js @@ -19,7 +19,7 @@ import WzNoConfig from '../util-components/no-config'; import { isString, renderValueOrNoValue, - renderValueOrDefault + renderValueOrDefault, } from '../utils/utils'; import { webDocumentationLink } from '../../../../../../../common/services/web_documentation'; @@ -40,12 +40,14 @@ const renderAllowedDeniedIPs = (items, label) => { const helpLinks = [ { text: 'Remote daemon reference', - href: webDocumentationLink('user-manual/reference/daemons/wazuh-remoted.html') + href: webDocumentationLink( + 'user-manual/reference/daemons/wazuh-remoted.html', + ), }, { text: 'Remote configuration reference', - href: webDocumentationLink('user-manual/reference/ossec-conf/remote.html') - } + href: webDocumentationLink('user-manual/reference/ossec-conf/remote.html'), + }, ]; class WzConfigurationGlobalConfigurationRemote extends Component { @@ -57,29 +59,29 @@ class WzConfigurationGlobalConfigurationRemote extends Component { { field: 'protocol', name: 'Protocol', - render: renderValueOrDefault('udp') + render: renderValueOrDefault('udp'), }, { field: 'ipv6', name: 'IPv6', render: renderValueOrNoValue }, { field: 'allowed-ips', name: 'Allowed IP addresses', - render: item => renderAllowedDeniedIPs(item, 'allowed') + render: item => renderAllowedDeniedIPs(item, 'allowed'), }, { field: 'denied-ips', name: 'Denied IP addresses', - render: item => renderAllowedDeniedIPs(item, 'denied') + render: item => renderAllowedDeniedIPs(item, 'denied'), }, { field: 'local_ip', name: 'Local IP address', - render: renderValueOrDefault('All interfaces') + render: renderValueOrDefault('All interfaces'), }, { field: 'queue_size', name: 'Queue size', - render: renderValueOrDefault('16384') - } + render: renderValueOrDefault('16384'), + }, ]; } render() { @@ -96,21 +98,22 @@ class WzConfigurationGlobalConfigurationRemote extends Component { {currentConfig['request-remote'] && !isString(currentConfig['request-remote']) && !currentConfig['request-remote'].remote && ( - + )} {currentConfig['request-remote'] && currentConfig['request-remote'].remote && ( - + )} diff --git a/public/controllers/management/components/management/groups/group-agents-table.js b/public/controllers/management/components/management/groups/group-agents-table.js index 534726d6aa..e7c4a11aba 100644 --- a/public/controllers/management/components/management/groups/group-agents-table.js +++ b/public/controllers/management/components/management/groups/group-agents-table.js @@ -9,13 +9,11 @@ * * Find more information about this on the LICENSE file. */ -import React, { Component } from 'react'; -import { EuiCallOut } from '@elastic/eui'; +import React, { Component, Fragment } from 'react'; import { connect } from 'react-redux'; import GroupsHandler from './utils/groups-handler'; import { getToasts } from '../../../../../kibana-services'; - import { updateLoadingStatus, updateFileContent, @@ -27,16 +25,18 @@ import { updateSortFieldAgents, updateReload, } from '../../../../../redux/actions/groupsActions'; - +import { EuiCallOut } from '@elastic/eui'; import { getAgentFilterValues } from './get-agents-filters-values'; import { TableWzAPI } from '../../../../../components/common/tables'; import { WzButtonPermissions } from '../../../../../components/common/permissions/button'; import { WzButtonPermissionsModalConfirm } from '../../../../../components/common/buttons'; -import { UI_LOGGER_LEVELS, UI_ORDER_AGENT_STATUS } from '../../../../../../common/constants'; +import { + UI_LOGGER_LEVELS, + UI_ORDER_AGENT_STATUS, +} from '../../../../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../../../../react-services/error-orchestrator/types'; import { getErrorOrchestrator } from '../../../../../react-services/common-services'; - class WzGroupAgentsTable extends Component { _isMounted = false; constructor(props) { @@ -54,7 +54,7 @@ class WzGroupAgentsTable extends Component { label: 'os.platform', description: 'Filter by operating system platform', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('os.platform', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -64,31 +64,37 @@ class WzGroupAgentsTable extends Component { label: 'ip', description: 'Filter by agent IP address', operators: ['=', '!='], - values: async (value) => - getAgentFilterValues('ip', value, { q: `group=${this.props.state.itemDetail.name}` }), + values: async value => + getAgentFilterValues('ip', value, { + q: `group=${this.props.state.itemDetail.name}`, + }), }, { type: 'q', label: 'name', description: 'Filter by agent name', operators: ['=', '!='], - values: async (value) => - getAgentFilterValues('name', value, { q: `group=${this.props.state.itemDetail.name}` }), + values: async value => + getAgentFilterValues('name', value, { + q: `group=${this.props.state.itemDetail.name}`, + }), }, { type: 'q', label: 'id', description: 'Filter by agent id', operators: ['=', '!='], - values: async (value) => - getAgentFilterValues('id', value, { q: `group=${this.props.state.itemDetail.name}` }), + values: async value => + getAgentFilterValues('id', value, { + q: `group=${this.props.state.itemDetail.name}`, + }), }, { type: 'q', label: 'node_name', description: 'Filter by node name', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('node_name', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -98,7 +104,7 @@ class WzGroupAgentsTable extends Component { label: 'manager', description: 'Filter by manager', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('manager', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -108,7 +114,7 @@ class WzGroupAgentsTable extends Component { label: 'version', description: 'Filter by agent version', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('version', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -118,7 +124,7 @@ class WzGroupAgentsTable extends Component { label: 'configSum', description: 'Filter by agent config sum', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('configSum', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -128,7 +134,7 @@ class WzGroupAgentsTable extends Component { label: 'mergedSum', description: 'Filter by agent merged sum', operators: ['=', '!='], - values: async (value) => + values: async value => getAgentFilterValues('mergedSum', value, { q: `group=${this.props.state.itemDetail.name}`, }), @@ -154,8 +160,8 @@ class WzGroupAgentsTable extends Component { { field: 'ip', name: 'IP address', - align: 'left', sortable: true, + show: true, }, { field: 'status', @@ -184,49 +190,57 @@ class WzGroupAgentsTable extends Component { { name: 'Actions', align: 'left', - render: (item) => { + render: item => { return (
({ + ...(item.group || []).map(group => ({ action: 'agent:read', resource: `agent:group:${group}`, })), ], ]} tooltip={{ position: 'top', content: 'Go to the agent' }} - aria-label="Go to the agent" - iconType="eye" + aria-label='Go to the agent' + iconType='eye' onClick={async () => { this.props.groupsProps.showAgent(item); }} - color="primary" + color='primary' /> {this.props?.state?.itemDetail?.name !== 'default' && ( ({ + { + action: 'agent:modify_group', + resource: `agent:id:${item.id}`, + }, + ...(item.group || []).map(group => ({ action: 'agent:modify_group', resource: `agent:group:${group}`, })), ], ]} - tooltip={{ position: 'top', content: 'Remove agent from this group' }} - aria-label="Remove agent from this group" - iconType="trash" + tooltip={{ + position: 'top', + content: 'Remove agent from this group', + }} + aria-label='Remove agent from this group' + iconType='trash' onConfirm={async () => { this.removeItems([item]); }} - color="danger" + color='danger' isDisabled={item.name === 'default'} - modalTitle={`Remove ${item.file || item.name} agent from this group?`} + modalTitle={`Remove ${ + item.file || item.name + } agent from this group?`} modalProps={{ buttonColor: 'danger', }} @@ -242,22 +256,22 @@ class WzGroupAgentsTable extends Component { componentWillUnmount() { this._isMounted = false; } - render() { const { error } = this.props.state; if (!error) { return ( ); } else { - return ; + return ; } } @@ -274,7 +288,11 @@ class WzGroupAgentsTable extends Component { const { itemDetail } = this.props.state; this.props.updateLoadingStatus(true); try { - await Promise.all(items.map(item => this.groupsHandler.deleteAgent(item.id, itemDetail.name))); + await Promise.all( + items.map(item => + this.groupsHandler.deleteAgent(item.id, itemDetail.name), + ), + ); this.props.updateIsProcessing(true); this.props.updateLoadingStatus(false); this.props.updateReload(); @@ -299,23 +317,27 @@ class WzGroupAgentsTable extends Component { } } -const mapStateToProps = (state) => { +const mapStateToProps = state => { return { state: state.groupsReducers, }; }; -const mapDispatchToProps = (dispatch) => { +const mapDispatchToProps = dispatch => { return { - updateLoadingStatus: (status) => dispatch(updateLoadingStatus(status)), - updateFileContent: (content) => dispatch(updateFileContent(content)), - updateIsProcessing: (isProcessing) => dispatch(updateIsProcessing(isProcessing)), - updatePageIndexAgents: (pageIndexAgents) => dispatch(updatePageIndexAgents(pageIndexAgents)), - updateShowModal: (showModal) => dispatch(updateShowModal(showModal)), - updateListItemsForRemove: (itemList) => dispatch(updateListItemsForRemove(itemList)), - updateSortDirectionAgents: (sortDirectionAgents) => + updateLoadingStatus: status => dispatch(updateLoadingStatus(status)), + updateFileContent: content => dispatch(updateFileContent(content)), + updateIsProcessing: isProcessing => + dispatch(updateIsProcessing(isProcessing)), + updatePageIndexAgents: pageIndexAgents => + dispatch(updatePageIndexAgents(pageIndexAgents)), + updateShowModal: showModal => dispatch(updateShowModal(showModal)), + updateListItemsForRemove: itemList => + dispatch(updateListItemsForRemove(itemList)), + updateSortDirectionAgents: sortDirectionAgents => dispatch(updateSortDirectionAgents(sortDirectionAgents)), - updateSortFieldAgents: (sortFieldAgents) => dispatch(updateSortFieldAgents(sortFieldAgents)), + updateSortFieldAgents: sortFieldAgents => + dispatch(updateSortFieldAgents(sortFieldAgents)), updateReload: () => dispatch(updateReload()), }; };