diff --git a/CHANGELOG.md b/CHANGELOG.md index 68ab686142..9a7b79a55f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ All notable changes to the Wazuh app project will be documented in this file. +## Wazuh v4.5.1 - OpenSearch Dashboards 2.6.0 - Revision 01 + +### Added + +- Add Apple Silicon architecture button to the register Agent wizard [#5478](https://github.com/wazuh/wazuh-kibana-app/pull/5478) + +### Fixed + +- Fixed the rendering of tables that contains IPs and agent overview [#5471](https://github.com/wazuh/wazuh-kibana-app/pull/5471) +- Fixed the agents active coverage stat as NaN in Details panel of Agents section [#5490](https://github.com/wazuh/wazuh-kibana-app/pull/5490) + +### Removed + +- Removed the agent name in the agent info ribbon [#5497](https://github.com/wazuh/wazuh-kibana-app/pull/5497) + +### Changed + +- Changed method to perform redirection on agent table buttons [#5539](https://github.com/wazuh/wazuh-kibana-app/pull/5539) +- Changed windows agent service name in the deploy agent wizard [#5538](https://github.com/wazuh/wazuh-kibana-app/pull/5538) + ## Wazuh v4.5.0 - OpenSearch Dashboards 2.6.0 - Revision 01 ### Added @@ -16,6 +36,7 @@ All notable changes to the Wazuh app project will be documented in this file. ## Wazuh v4.4.4 - OpenSearch Dashboards 2.6.0 - Revision 01 + ### Added - Support for Wazuh 4.4.4 @@ -62,8 +83,8 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the option to sort by the agent's 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) [#5143](https://github.com/wazuh/wazuh-kibana-app/pull/5143) [#5177](https://github.com/wazuh/wazuh-kibana-app/pull/5177) - Added the ability to set the agent name in the installation command. [#4739](https://github.com/wazuh/wazuh-kibana-app/pull/4739) -- Added validation to the plugin's settings [#4503](https://github.com/wazuh/wazuh-kibana-app/pull/4503)[#4785](https://github.com/wazuh/wazuh-kibana-app/pull/4785) -- Added new settings to customize the header and footer on the PDF reports [#4505](https://github.com/wazuh/wazuh-kibana-app/pull/4505)[#4798](https://github.com/wazuh/wazuh-kibana-app/pull/4798)[#4805](https://github.com/wazuh/wazuh-kibana-app/pull/4805) +- Added validation to the plugin's settings [#4503](https://github.com/wazuh/wazuh-kibana-app/pull/4503) [#4785](https://github.com/wazuh/wazuh-kibana-app/pull/4785) +- Added new settings to customize the header and footer on the PDF reports [#4505](https://github.com/wazuh/wazuh-kibana-app/pull/4505) [#4798](https://github.com/wazuh/wazuh-kibana-app/pull/4798) [#4805](https://github.com/wazuh/wazuh-kibana-app/pull/4805) - Added a new setting to enable or disable the customization [#4507](https://github.com/wazuh/wazuh-kibana-app/pull/4507) - Added the ability to upload an image for the `customization.logo.*` settings in `Settings/Configuration` [#4504](https://github.com/wazuh/wazuh-kibana-app/pull/4504) - Added macOS support to the 'Deploy new agent' section [#4867](https://github.com/wazuh/wazuh-kibana-app/pull/4867) diff --git a/README.md b/README.md index 20c35f1264..dea1aaedf9 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,10 @@ This plugin for OpenSearch Dashboards allows you to visualize and analyze Wazuh ## Requisites -- Wazuh HIDS 4.5.0 -- Wazuh dashboard 4.5.0 -- Wazuh indexer 4.5.0 +- Wazuh HIDS 4.5.1 +- Wazuh dashboard 4.5.1 +- Wazuh indexer 4.5.1 + ## Contribute diff --git a/docker/images/kbn-7.17.11-dev.Dockerfile b/docker/images/kbn-7.17.11-dev.Dockerfile new file mode 100644 index 0000000000..793b08ecb5 --- /dev/null +++ b/docker/images/kbn-7.17.11-dev.Dockerfile @@ -0,0 +1,17 @@ +FROM node:16.20.1 AS builder-kbn-7.17.11 +RUN npm install --global @bazel/bazelisk@1.10.1 +USER node +RUN git clone --depth 1 --branch v7.17.11 https://github.com/elastic/kibana /home/node/kbn +RUN chown node.node /home/node/kbn + +WORKDIR /home/node/kbn +RUN yarn kbn bootstrap +RUN yarn config set registry http://host.docker.internal:4873 && \ + sed -i 's/https:\/\/registry.yarnpkg.com/http:\/\/host.docker.internal:4873/g' yarn.lock +RUN rm -rf /home/node/.cache/yarn && rm -rf /home/node/.cache/Cypress && rm -rf /home/node/.cache/ms-playwright +RUN mkdir -p /home/node/kbn/data/wazuh/config + +FROM node:16.20.1 +USER node +COPY --from=builder-kbn-7.17.11 /home/node/ /home/node/ +WORKDIR /home/node/kbn 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/docker/kbn-dev/dev.sh b/docker/kbn-dev/dev.sh index 70d27c34b2..d0ee3d5bf3 100755 --- a/docker/kbn-dev/dev.sh +++ b/docker/kbn-dev/dev.sh @@ -1,6 +1,5 @@ #!/bin/bash - elastic_versions=( '7.10.2' '7.16.0' @@ -11,23 +10,23 @@ elastic_versions=( '7.17.4' '7.17.5' '7.17.6' - '7.17.7' - '7.17.8' - '7.17.9' - '7.17.10' + '7.17.7' + '7.17.8' + '7.17.9' + '7.17.10' + '7.17.11' '8.0.0' '8.1.0' '8.2.1' '8.2.3' '8.3.0' '8.3.1' - '8.3.3' - '8.4.2' - '8.4.3' - '8.5.0' + '8.3.3' + '8.4.2' + '8.4.3' + '8.5.0' ) - usage() { echo echo "./dev.sh elastic_version /wazuh_app_src action " @@ -39,19 +38,16 @@ usage() { exit -1 } - -if [ $# -ne 3 ] - then - echo "Incorrect number of arguments " $# ", got " $@ - echo - usage +if [ $# -ne 3 ]; then + echo "Incorrect number of arguments " $# ", got " $@ + echo + usage fi -if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]] - then - echo "Version ${1} not found in ${elastic_versions[*]}" - echo - exit -1 +if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]]; then + echo "Version ${1} not found in ${elastic_versions[*]}" + echo + exit -1 fi if [[ $2 != /* ]]; then @@ -71,18 +67,18 @@ export SRC=$2 export COMPOSE_PROJECT_NAME=es-dev-${ES_VERSION//./} # /./ removes dots: 7.10.2 => 7102 case "$3" in - up) - docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} up -Vd - ;; - down) - docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} down -v --remove-orphans - ;; - stop) - docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} stop - ;; - *) - echo "Action must be up | down | stop: " - echo - usage - ;; +up) + docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} up -Vd + ;; +down) + docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} down -v --remove-orphans + ;; +stop) + docker compose -f dev.yml -p ${COMPOSE_PROJECT_NAME} stop + ;; +*) + echo "Action must be up | down | stop: " + echo + usage + ;; esac diff --git a/docker/wazuh-4.4-wz/pre.sh b/docker/wazuh-4.4-wz/pre.sh index 981f2bbd30..9487376cfa 100755 --- a/docker/wazuh-4.4-wz/pre.sh +++ b/docker/wazuh-4.4-wz/pre.sh @@ -2,10 +2,13 @@ versions=( "4.4.0" - "4.4.1" - "4.4.2" - "4.4.3" - "4.4.4" + "4.4.1" + "4.4.2" + "4.4.3" + "4.4.4" + "4.4.5" + "4.5.0" + "4.5.1" ) wazuh_api_version=( @@ -32,26 +35,24 @@ usage() { exit -1 } -if [ $# -ne 3 ] - then - echo "Incorrect number of arguments " $# - usage +if [ $# -ne 3 ]; then + echo "Incorrect number of arguments " $# + usage fi -if [[ ! " ${versions[*]} " =~ " ${1} " ]] - then - echo "Version ${1} not found in ${versions[*]}" - exit -1 +if [[ ! " ${versions[*]} " =~ " ${1} " ]]; then + echo "Version ${1} not found in ${versions[*]}" + exit -1 fi [ -n "$2" ] && [ "$2" -eq "$2" ] 2>/dev/null if [ $? -ne 0 ]; then - echo "$2 is not number" - exit -1 + echo "$2 is not number" + exit -1 fi patch_version=$2 -cat << EOF > config/imposter/api_info.json +cat <config/imposter/api_info.json { "data": { "title": "Wazuh API REST", @@ -72,46 +73,46 @@ export KIBANA_PASSWORD=${PASSWORD:-SecretPassword} export COMPOSE_PROJECT_NAME=wz-pre-${WAZUH_STACK//./} case "$3" in - up) - # recreate volumes - docker compose -f pre.yml up -Vd +up) + # recreate volumes + docker compose -f pre.yml up -Vd - # This installs Wazuh and integrates with a default Wazuh stack - # v=$( echo -n $WAZUH_STACK | sed 's/\.//g' ) - echo - echo "Install the pre-release package manually with:" - echo - echo "1. Uninstall current version of the Wazuh app:" - echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1 /usr/share/wazuh-dashboard/bin/opensearch-dashboards-plugin remove wazuh" - echo - echo "2. Restart Wazuh Dashboard:" - echo "docker restart ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1" - echo - echo "3. Copy the pre-release package to the running Wazuh Dashboard container:" - echo docker cp wazuh-4.4.${patch_version}-1.zip ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1:/tmp - echo - echo "4. Install the package we have just uploaded:" - echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1 /usr/share/wazuh-dashboard/bin/opensearch-dashboards-plugin install file:///tmp/wazuh-4.4.${patch_version}-1.zip" - echo - echo "5. Restart the Wazuh Dashboard container:" - echo "docker restart ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1" - echo - echo "6. Upload the Wazuh app configuration:" - echo "docker cp ./config/wazuh_dashboard/wazuh.yml ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1:/usr/share/wazuh-dashboard/data/wazuh/config/" - echo - echo "7. Access the running instance in:" - echo "https://localhost:${KIBANA_PORT}" - echo - ;; - down) - # delete volumes - docker compose -f pre.yml down -v --remove-orphans - ;; - stop) - docker compose -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop - ;; - *) - echo "Action must be either up or down" - usage - ;; + # This installs Wazuh and integrates with a default Wazuh stack + # v=$( echo -n $WAZUH_STACK | sed 's/\.//g' ) + echo + echo "Install the pre-release package manually with:" + echo + echo "1. Uninstall current version of the Wazuh app:" + echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1 /usr/share/wazuh-dashboard/bin/opensearch-dashboards-plugin remove wazuh" + echo + echo "2. Restart Wazuh Dashboard:" + echo "docker restart ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1" + echo + echo "3. Copy the pre-release package to the running Wazuh Dashboard container:" + echo docker cp wazuh-4.4.${patch_version}-1.zip ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1:/tmp + echo + echo "4. Install the package we have just uploaded:" + echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1 /usr/share/wazuh-dashboard/bin/opensearch-dashboards-plugin install file:///tmp/wazuh-4.4.${patch_version}-1.zip" + echo + echo "5. Restart the Wazuh Dashboard container:" + echo "docker restart ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1" + echo + echo "6. Upload the Wazuh app configuration:" + echo "docker cp ./config/wazuh_dashboard/wazuh.yml ${COMPOSE_PROJECT_NAME}-wazuh.dashboard-1:/usr/share/wazuh-dashboard/data/wazuh/config/" + echo + echo "7. Access the running instance in:" + echo "https://localhost:${KIBANA_PORT}" + echo + ;; +down) + # delete volumes + docker compose -f pre.yml down -v --remove-orphans + ;; +stop) + docker compose -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop + ;; +*) + echo "Action must be either up or down" + usage + ;; esac diff --git a/docker/wazuh-4.4-wz/rel.sh b/docker/wazuh-4.4-wz/rel.sh index 9723041319..cd74d62c4b 100755 --- a/docker/wazuh-4.4-wz/rel.sh +++ b/docker/wazuh-4.4-wz/rel.sh @@ -2,10 +2,13 @@ versions=( "4.4.0" - "4.4.1" - "4.4.2" - "4.4.3" - "4.4.4" + "4.4.1" + "4.4.2" + "4.4.3" + "4.4.4" + "4.4.5" + "4.5.0" + "4.5.1" ) usage() { @@ -18,16 +21,14 @@ usage() { exit -1 } -if [ $# -lt 2 ] - then - echo "Incorrect number of arguments " $# - usage +if [ $# -lt 2 ]; then + echo "Incorrect number of arguments " $# + usage fi -if [[ ! " ${versions[*]} " =~ " ${1} " ]] - then - echo "Version ${1} not found in ${versions[*]}" - exit -1 +if [[ ! " ${versions[*]} " =~ " ${1} " ]]; then + echo "Version ${1} not found in ${versions[*]}" + exit -1 fi export WAZUH_STACK=${1} @@ -39,38 +40,37 @@ profile="standard" export WAZUH_DASHBOARD_CONF=./config/wazuh_dashboard/wazuh_dashboard.yml export SEC_CONFIG_FILE=./config/wazuh_indexer/config.yml -if [[ "$3" =~ "saml" ]] -then +if [[ "$3" =~ "saml" ]]; then profile="saml" export WAZUH_DASHBOARD_CONF=./config/wazuh_dashboard/wazuh_dashboard_saml.yml export SEC_CONFIG_FILE=./config/wazuh_indexer/config-saml.yml fi case "$2" in - up) - docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} up -Vd - echo - echo "1. (Optional) Enroll an agent (Ubuntu 20.04):" - echo "docker run --name ${COMPOSE_PROJECT_NAME}-agent --network ${COMPOSE_PROJECT_NAME} --label com.docker.compose.project=${COMPOSE_PROJECT_NAME} -d ubuntu:20.04 bash -c '" - echo " apt update -y" - echo " apt install -y curl lsb-release" - echo " curl -so \wazuh-agent-${WAZUH_STACK}.deb \\" - echo " https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${WAZUH_STACK}-1_amd64.deb \\" - echo " && WAZUH_MANAGER='wazuh.manager' WAZUH_AGENT_GROUP='default' dpkg -i ./wazuh-agent-${WAZUH_STACK}.deb" - echo - echo " /etc/init.d/wazuh-agent start" - echo " tail -f /var/ossec/logs/ossec.log" - echo "'" - echo - ;; - down) - docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} down -v --remove-orphans - ;; - stop) - docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop - ;; - *) - echo "Action must be either up or down" - usage - ;; +up) + docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} up -Vd + echo + echo "1. (Optional) Enroll an agent (Ubuntu 20.04):" + echo "docker run --name ${COMPOSE_PROJECT_NAME}-agent --network ${COMPOSE_PROJECT_NAME} --label com.docker.compose.project=${COMPOSE_PROJECT_NAME} -d ubuntu:20.04 bash -c '" + echo " apt update -y" + echo " apt install -y curl lsb-release" + echo " curl -so \wazuh-agent-${WAZUH_STACK}.deb \\" + echo " https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${WAZUH_STACK}-1_amd64.deb \\" + echo " && WAZUH_MANAGER='wazuh.manager' WAZUH_AGENT_GROUP='default' dpkg -i ./wazuh-agent-${WAZUH_STACK}.deb" + echo + echo " /etc/init.d/wazuh-agent start" + echo " tail -f /var/ossec/logs/ossec.log" + echo "'" + echo + ;; +down) + docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} down -v --remove-orphans + ;; +stop) + docker compose --profile $profile -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop + ;; +*) + echo "Action must be either up or down" + usage + ;; esac diff --git a/docker/wazuh-4.x-es/pre.sh b/docker/wazuh-4.x-es/pre.sh index e76d4c924c..a16354c02f 100755 --- a/docker/wazuh-4.x-es/pre.sh +++ b/docker/wazuh-4.x-es/pre.sh @@ -12,10 +12,11 @@ elastic_versions=( "7.17.4" "7.17.5" "7.17.6" - "7.17.7" - "7.17.8" - "7.17.9" - "7.17.10" + "7.17.7" + "7.17.8" + "7.17.9" + "7.17.10" + "7.17.11" ) wazuh_api_version=( @@ -32,9 +33,12 @@ wazuh_api_version=( "4.3.10" "4.4.0" "4.4.1" - "4.4.2" - "4.4.3" - "4.4.4" + "4.4.2" + "4.4.3" + "4.4.4" + "4.4.5" + "4.5.0" + "4.5.1" ) usage() { @@ -55,26 +59,24 @@ usage() { exit -1 } -if [ $# -ne 3 ] - then - echo "Incorrect number of arguments " $# - usage +if [ $# -ne 3 ]; then + echo "Incorrect number of arguments " $# + usage fi -if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]] - then - echo "Version ${1} not found in ${elastic_versions[*]}" - exit -1 +if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]]; then + echo "Version ${1} not found in ${elastic_versions[*]}" + exit -1 fi # [ -n "$2" ] && [ "$2" -eq "$2" ] 2>/dev/null if [ $? -ne 0 ]; then - echo "Version ${2} not found in ${wazuh_api_version[*]}" - exit -1 + echo "Version ${2} not found in ${wazuh_api_version[*]}" + exit -1 fi wazuh_version=$2 -cat << EOF > config/imposter/api_info.json +cat <config/imposter/api_info.json { "data": { "title": "Wazuh API REST", @@ -98,39 +100,39 @@ export KIBANA_PORT=${PORT:-5601} export COMPOSE_PROJECT_NAME=es-pre-${ES_VERSION//./} case "$3" in - up) - # recreate volumes - docker compose -f pre.yml up -Vd +up) + # recreate volumes + docker compose -f pre.yml up -Vd - # This installs Wazuh and integrates with a default Elastic stack - # v=$( echo -n $ES_VERSION | sed 's/\.//g' ) - echo - echo "Install the pre-release package manually with:" - echo - echo "1. Copy the pre-release package to the running Kibana container:" - echo "docker cp wazuh_kibana-${wazuh_version}_${ES_VERSION}-1.zip ${COMPOSE_PROJECT_NAME}-kibana-1:/tmp" - echo - echo "2. Install the pre-release package:" - echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-kibana-1 /usr/share/kibana/bin/kibana-plugin install file:///tmp/wazuh_kibana-${wazuh_version}_${ES_VERSION}-1.zip" - echo - echo "3. Restart Kibana:" - echo "docker restart ${COMPOSE_PROJECT_NAME}-kibana-1" - echo - echo "4. Upload the Wazuh app configuration:" - echo "docker cp ./config/kibana/wazuh.yml ${COMPOSE_PROJECT_NAME}-kibana-1:/usr/share/kibana/data/wazuh/config/" - echo - echo "5. Open Kibana in a browser:" - echo "http://localhost:${KIBANA_PORT}" - echo - ;; - down) - # delete volumes - docker compose -f pre.yml down -v --remove-orphans - ;; - stop) - docker compose -f pre.yml -p ${COMPOSE_PROJECT_NAME} stop - ;; - *) - usage - ;; + # This installs Wazuh and integrates with a default Elastic stack + # v=$( echo -n $ES_VERSION | sed 's/\.//g' ) + echo + echo "Install the pre-release package manually with:" + echo + echo "1. Copy the pre-release package to the running Kibana container:" + echo "docker cp wazuh_kibana-${wazuh_version}_${ES_VERSION}-1.zip ${COMPOSE_PROJECT_NAME}-kibana-1:/tmp" + echo + echo "2. Install the pre-release package:" + echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-kibana-1 /usr/share/kibana/bin/kibana-plugin install file:///tmp/wazuh_kibana-${wazuh_version}_${ES_VERSION}-1.zip" + echo + echo "3. Restart Kibana:" + echo "docker restart ${COMPOSE_PROJECT_NAME}-kibana-1" + echo + echo "4. Upload the Wazuh app configuration:" + echo "docker cp ./config/kibana/wazuh.yml ${COMPOSE_PROJECT_NAME}-kibana-1:/usr/share/kibana/data/wazuh/config/" + echo + echo "5. Open Kibana in a browser:" + echo "http://localhost:${KIBANA_PORT}" + echo + ;; +down) + # delete volumes + docker compose -f pre.yml down -v --remove-orphans + ;; +stop) + docker compose -f pre.yml -p ${COMPOSE_PROJECT_NAME} stop + ;; +*) + usage + ;; esac diff --git a/docker/wazuh-4.x-es/rel.sh b/docker/wazuh-4.x-es/rel.sh index d58ecf4e6d..2ef6b36281 100755 --- a/docker/wazuh-4.x-es/rel.sh +++ b/docker/wazuh-4.x-es/rel.sh @@ -12,10 +12,11 @@ elastic_versions=( "7.17.4" "7.17.5" "7.17.6" - "7.17.7" - "7.17.8" - "7.17.9" - "7.17.10" + "7.17.7" + "7.17.8" + "7.17.9" + "7.17.10" + "7.17.11" ) wazuh_versions=( @@ -28,13 +29,16 @@ wazuh_versions=( "4.3.6" "4.3.7" "4.3.8" - "4.3.9" - "4.3.10" - "4.4.0" - "4.4.1" - "4.4.2" - "4.4.3" - "4.4.4" + "4.3.9" + "4.3.10" + "4.4.0" + "4.4.1" + "4.4.2" + "4.4.3" + "4.4.4" + "4.4.5" + "4.5.0" + "4.5.1" ) usage() { @@ -48,22 +52,19 @@ usage() { exit -1 } -if [ $# -ne 3 ] - then - echo "Incorrect number of arguments " $# - usage +if [ $# -ne 3 ]; then + echo "Incorrect number of arguments " $# + usage fi -if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]] - then - echo "Version ${1} not found in ${elastic_versions[*]}" - exit -1 +if [[ ! " ${elastic_versions[*]} " =~ " ${1} " ]]; then + echo "Version ${1} not found in ${elastic_versions[*]}" + exit -1 fi -if [[ ! " ${wazuh_versions[*]} " =~ " ${2} " ]] - then - echo "Version ${2} not found in ${wazuh_versions[*]}" - exit -1 +if [[ ! " ${wazuh_versions[*]} " =~ " ${2} " ]]; then + echo "Version ${2} not found in ${wazuh_versions[*]}" + exit -1 fi export ES_VERSION=$1 @@ -76,48 +77,48 @@ export KIBANA_PORT=${PORT:-5601} export COMPOSE_PROJECT_NAME=es-rel-${ES_VERSION//./} case "$3" in - up) - # recreate volumes - docker compose -f rel.yml up -Vd +up) + # recreate volumes + docker compose -f rel.yml up -Vd - # This installs Wazuh and integrates with a default Elastic stack - # v=$( echo -n $ES_VERSION | sed 's/\.//g' ) - echo - echo "Install Wazuh ${WAZUH_VERSION} into Elastic ${ES_VERSION} manually with:" - echo - echo "1. Install the Wazuh app for Kibana" - echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-kibana-1 /usr/share/kibana/bin/kibana-plugin install https://packages.wazuh.com/4.x/ui/kibana/wazuh_kibana-${WAZUH_VERSION}_${ES_VERSION}-1.zip" - echo - echo "2. Restart Kibana" - echo "docker restart ${COMPOSE_PROJECT_NAME}-kibana-1" - echo - echo "3. Configure Kibana" - echo "docker cp ./config/kibana/wazuh.yml ${COMPOSE_PROJECT_NAME}-kibana-1:/usr/share/kibana/data/wazuh/config/" - echo - echo "4. Open Kibana in a browser:" - echo "http://localhost:${KIBANA_PORT}" - echo - echo "5. (Optional) Enroll an agent (Ubuntu 20.04):" - echo "docker run --name ${COMPOSE_PROJECT_NAME}-agent --network ${COMPOSE_PROJECT_NAME} --label com.docker.compose.project=${COMPOSE_PROJECT_NAME} -d ubuntu:20.04 bash -c '" - echo " apt update -y" - echo " apt install -y curl lsb-release" - echo " curl -so \wazuh-agent-${WAZUH_VERSION}.deb \\" - echo " https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${WAZUH_VERSION}-1_amd64.deb \\" - echo " && WAZUH_MANAGER='wazuh.manager' WAZUH_AGENT_GROUP='default' dpkg -i ./wazuh-agent-${WAZUH_VERSION}.deb" - echo - echo " /etc/init.d/wazuh-agent start" - echo " tail -f /var/ossec/logs/ossec.log" - echo "'" - echo - ;; - down) - # delete volumes - docker compose -f rel.yml down -v --remove-orphans - ;; - stop) - docker compose -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop - ;; - *) - usage - ;; + # This installs Wazuh and integrates with a default Elastic stack + # v=$( echo -n $ES_VERSION | sed 's/\.//g' ) + echo + echo "Install Wazuh ${WAZUH_VERSION} into Elastic ${ES_VERSION} manually with:" + echo + echo "1. Install the Wazuh app for Kibana" + echo "docker exec -ti ${COMPOSE_PROJECT_NAME}-kibana-1 /usr/share/kibana/bin/kibana-plugin install https://packages.wazuh.com/4.x/ui/kibana/wazuh_kibana-${WAZUH_VERSION}_${ES_VERSION}-1.zip" + echo + echo "2. Restart Kibana" + echo "docker restart ${COMPOSE_PROJECT_NAME}-kibana-1" + echo + echo "3. Configure Kibana" + echo "docker cp ./config/kibana/wazuh.yml ${COMPOSE_PROJECT_NAME}-kibana-1:/usr/share/kibana/data/wazuh/config/" + echo + echo "4. Open Kibana in a browser:" + echo "http://localhost:${KIBANA_PORT}" + echo + echo "5. (Optional) Enroll an agent (Ubuntu 20.04):" + echo "docker run --name ${COMPOSE_PROJECT_NAME}-agent --network ${COMPOSE_PROJECT_NAME} --label com.docker.compose.project=${COMPOSE_PROJECT_NAME} -d ubuntu:20.04 bash -c '" + echo " apt update -y" + echo " apt install -y curl lsb-release" + echo " curl -so \wazuh-agent-${WAZUH_VERSION}.deb \\" + echo " https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${WAZUH_VERSION}-1_amd64.deb \\" + echo " && WAZUH_MANAGER='wazuh.manager' WAZUH_AGENT_GROUP='default' dpkg -i ./wazuh-agent-${WAZUH_VERSION}.deb" + echo + echo " /etc/init.d/wazuh-agent start" + echo " tail -f /var/ossec/logs/ossec.log" + echo "'" + echo + ;; +down) + # delete volumes + docker compose -f rel.yml down -v --remove-orphans + ;; +stop) + docker compose -f rel.yml -p ${COMPOSE_PROJECT_NAME} stop + ;; +*) + usage + ;; esac diff --git a/opensearch_dashboards.json b/opensearch_dashboards.json index 1938543556..6f45efb6b6 100644 --- a/opensearch_dashboards.json +++ b/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.5.0-01", + "version": "4.5.1-01", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": [ "wazuh" diff --git a/package.json b/package.json index f68d3601c7..b84e79bdcf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { "name": "wazuh", - "version": "4.5.0", + "version": "4.5.1", "revision": "01", + "stage": "stable", + "commit": "c805cbcd0", "pluginPlatform": { "version": "2.6.0" }, 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/common/welcome/agents-welcome.js b/public/components/common/welcome/agents-welcome.js index 0349028a50..02cb1fcd8c 100644 --- a/public/components/common/welcome/agents-welcome.js +++ b/public/components/common/welcome/agents-welcome.js @@ -30,9 +30,14 @@ import { EuiToolTip, EuiButtonIcon, EuiEmptyPrompt, - EuiPageBody + EuiPageBody, } from '@elastic/eui'; -import { FimEventsTable, ScaScan, MitreTopTactics, RequirementVis } from './components'; +import { + FimEventsTable, + ScaScan, + MitreTopTactics, + RequirementVis, +} from './components'; import { AgentInfo } from './agents-info'; import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; import store from '../../../redux/store'; @@ -58,568 +63,641 @@ import { webDocumentationLink } from '../../../../common/services/web_documentat export const AgentsWelcome = compose( withReduxProvider, - withErrorBoundary)( -class AgentsWelcome extends Component { - _isMount = false; - constructor(props) { - super(props); - - this.offset = 275; - - this.state = { - extensions: this.props.extensions, - lastScans: [], - isLoading: true, - sortField: 'start_scan', - sortDirection: 'desc', - actionAgents: true, // Hide actions agents - selectedRequirement: 'pci', - menuAgent: {}, - maxModules: 6, - widthWindow: window.innerWidth - }; - } - - updateWidth = () => { + withErrorBoundary, +)( + class AgentsWelcome extends Component { + _isMount = false; + constructor(props) { + super(props); + + this.offset = 275; + + this.state = { + extensions: this.props.extensions, + lastScans: [], + isLoading: true, + sortField: 'start_scan', + sortDirection: 'desc', + actionAgents: true, // Hide actions agents + selectedRequirement: 'pci', + menuAgent: {}, + maxModules: 6, + widthWindow: window.innerWidth, + }; + } - let menuSize = (window.innerWidth - this.offset); - let maxModules = 6; - if (menuSize > 1250) { - maxModules = 6; - } else { - if (menuSize > 1100) { - maxModules = 5; + updateWidth = () => { + let menuSize = window.innerWidth - this.offset; + let maxModules = 6; + if (menuSize > 1250) { + maxModules = 6; } else { - if (menuSize > 900) { - maxModules = 4; + if (menuSize > 1100) { + maxModules = 5; } else { - maxModules = 3; - if (menuSize < 750) { - maxModules = null; + if (menuSize > 900) { + maxModules = 4; + } else { + maxModules = 3; + if (menuSize < 750) { + maxModules = null; + } } } } - } - this.setState({ maxModules: maxModules, widthWindow: window.innerWidth }); - }; - - setGlobalBreadcrumb() { - const breadcrumb = [ - { text: '' }, - { - text: 'Agents', - href: "#/agents-preview" - }, - { - text: `${this.props.agent.name}`, - className: 'wz-global-breadcrumb-btn euiBreadcrumb--truncate', - truncate: false, - } - ]; - store.dispatch(updateGlobalBreadcrumb(breadcrumb)); - } - - - async componentDidMount() { - this._isMount = true; - store.dispatch(updateCurrentAgentData(this.props.agent)); - this.updateMenuAgents(); - this.updateWidth(); - this.setGlobalBreadcrumb(); - const tabVisualizations = new TabVisualizations(); - tabVisualizations.removeAll(); - tabVisualizations.setTab('welcome'); - tabVisualizations.assign({ - welcome: 8 - }); - const filterHandler = new FilterHandler(AppState.getCurrentPattern()); - const $injector = getAngularModule().$injector; - this.router = $injector.get('$route'); - window.addEventListener('resize', this.updateWidth); //eslint-disable-line - await VisFactoryHandler.buildAgentsVisualizations( - filterHandler, - 'welcome', - null, - this.props.agent.id - ); - } + this.setState({ maxModules: maxModules, widthWindow: window.innerWidth }); + }; - updateMenuAgents() { - const defaultMenuAgents = { - general: { - id: 'general', - text: 'Security events', - isPin: true, - }, - fim: { - id: 'fim', - text: 'Integrity monitoring', - isPin: true, - }, - sca: { - id: 'sca', - text: 'SCA', - isPin: true, - }, - audit: { - id: 'audit', - text: 'System Auditing', - isPin: true, - }, - vuls: { - id: 'vuls', - text: 'Vulnerabilities', - isPin: true, - }, - mitre: { - id: 'mitre', - text: 'MITRE ATT&CK', - isPin: true, - }, + setGlobalBreadcrumb() { + const breadcrumb = [ + { text: '' }, + { + text: 'Agents', + href: '#/agents-preview', + }, + { + text: `${this.props.agent.name}`, + className: 'wz-global-breadcrumb-btn euiBreadcrumb--truncate', + truncate: false, + }, + ]; + store.dispatch(updateGlobalBreadcrumb(breadcrumb)); } - let menuAgent = JSON.parse(window.localStorage.getItem('menuAgent')); + async componentDidMount() { + this._isMount = true; + store.dispatch(updateCurrentAgentData(this.props.agent)); + this.updateMenuAgents(); + this.updateWidth(); + this.setGlobalBreadcrumb(); + const tabVisualizations = new TabVisualizations(); + tabVisualizations.removeAll(); + tabVisualizations.setTab('welcome'); + tabVisualizations.assign({ + welcome: 8, + }); + const filterHandler = new FilterHandler(AppState.getCurrentPattern()); + const $injector = getAngularModule().$injector; + this.router = $injector.get('$route'); + window.addEventListener('resize', this.updateWidth); //eslint-disable-line + await VisFactoryHandler.buildAgentsVisualizations( + filterHandler, + 'welcome', + null, + this.props.agent.id, + ); + } - // Check if pinned modules to agent menu are enabled in Settings/Modules, if not then modify localstorage removing the disabled modules - if (menuAgent) { - const needUpdateMenuAgent = Object.keys(menuAgent).map(moduleName => menuAgent[moduleName]).reduce((accum, item) => { - if (typeof this.props.extensions[item.id] !== 'undefined' && this.props.extensions[item.id] === false) { - delete menuAgent[item.id]; - accum = true; + updateMenuAgents() { + const defaultMenuAgents = { + general: { + id: 'general', + text: 'Security events', + isPin: true, + }, + fim: { + id: 'fim', + text: 'Integrity monitoring', + isPin: true, + }, + sca: { + id: 'sca', + text: 'SCA', + isPin: true, + }, + audit: { + id: 'audit', + text: 'System Auditing', + isPin: true, + }, + vuls: { + id: 'vuls', + text: 'Vulnerabilities', + isPin: true, + }, + mitre: { + id: 'mitre', + text: 'MITRE ATT&CK', + isPin: true, + }, + }; + + let menuAgent = JSON.parse(window.localStorage.getItem('menuAgent')); + + // Check if pinned modules to agent menu are enabled in Settings/Modules, if not then modify localstorage removing the disabled modules + if (menuAgent) { + const needUpdateMenuAgent = Object.keys(menuAgent) + .map(moduleName => menuAgent[moduleName]) + .reduce((accum, item) => { + if ( + typeof this.props.extensions[item.id] !== 'undefined' && + this.props.extensions[item.id] === false + ) { + delete menuAgent[item.id]; + accum = true; + } + return accum; + }, false); + if (needUpdateMenuAgent) { + // Update the pinned modules matching to enabled modules in Setings/Modules + window.localStorage.setItem('menuAgent', JSON.stringify(menuAgent)); } - return accum; - }, false); - if (needUpdateMenuAgent) { - // Update the pinned modules matching to enabled modules in Setings/Modules - window.localStorage.setItem('menuAgent', JSON.stringify(menuAgent)) + } else { + menuAgent = defaultMenuAgents; + window.localStorage.setItem( + 'menuAgent', + JSON.stringify(defaultMenuAgents), + ); } - } else { - menuAgent = defaultMenuAgents; - window.localStorage.setItem('menuAgent', JSON.stringify(defaultMenuAgents)); + this.setState({ menuAgent: menuAgent }); } - this.setState({ menuAgent: menuAgent }); - } - renderModules() { - const menuAgent = [...Object.keys(this.state.menuAgent).map((item) => { return this.state.menuAgent[item] })]; + renderModules() { + const menuAgent = [ + ...Object.keys(this.state.menuAgent).map(item => { + return this.state.menuAgent[item]; + }), + ]; - return ( - - { - menuAgent.map((menuAgent, i) => { - if (i < this.state.maxModules && hasAgentSupportModule(this.props.agent, menuAgent.id)) { + return ( + + {menuAgent.map((menuAgent, i) => { + if ( + i < this.state.maxModules && + hasAgentSupportModule(this.props.agent, menuAgent.id) + ) { return ( - + { - window.location.href = `#/overview/?tab=${menuAgent.id}&tabView=${menuAgent.text === 'Security configuration assessment' ? 'inventory' : 'panels'}`; + window.location.href = `#/overview/?tab=${ + menuAgent.id + }&tabView=${ + menuAgent.text === 'Security configuration assessment' + ? 'inventory' + : 'panels' + }`; this.router.reload(); - }} style={{ cursor: 'pointer' }}> - {menuAgent.text !== 'Security configuration assessment' ? menuAgent.text : 'SCA'}  + }} + style={{ cursor: 'pointer' }} + > + + {menuAgent.text !== 'Security configuration assessment' + ? menuAgent.text + : 'SCA'} +   + - ) - } - } - )} - - this.setState({ switchModule: !this.state.switchModule })}> - More... - + ); } - isOpen={this.state.switchModule} - closePopover={() => this.setState({ switchModule: false })} - repositionOnScroll={false} - anchorPosition="downCenter"> -

- -
- this.updateMenuAgents()} - closePopover={() => { - this.setState({ switchModule: false }) - } - } - switchTab={(module) => this.props.switchTab(module)}> -
-
-
- - - - ) - } - - renderTitle() { - - return ( - - - - - - -

- {this.state.widthWindow >= 768?( - - {this.props.agent.name} - - ): - ( - - {this.props.agent.name} - - ) - } -

-
-
-
- { - (this.state.maxModules !== null && - this.renderModules()) || - - this.setState({ switchModule: !this.state.switchModule })}> - Modules - + })} + + + this.setState({ switchModule: !this.state.switchModule }) } - isOpen={this.state.switchModule} - closePopover={() => this.setState({ switchModule: false })} - repositionOnScroll={false} - anchorPosition="downCenter"> -
- -
- this.updateMenuAgents()} - closePopover={() => { - this.setState({ switchModule: false }) - } - } - switchTab={(module) => this.props.switchTab(module)}> -
-
-
-
-
+ > + More... + } - + isOpen={this.state.switchModule} + closePopover={() => this.setState({ switchModule: false })} + repositionOnScroll={false} + anchorPosition='downCenter' + > +
+ +
+ this.updateMenuAgents()} + closePopover={() => { + this.setState({ switchModule: false }); + }} + switchTab={module => this.props.switchTab(module)} + > +
+
+
+
+
+ + ); + } + + renderTitle() { + return ( + + + + {(this.state.maxModules !== null && this.renderModules()) || ( + + + this.setState({ + switchModule: !this.state.switchModule, + }) + } + > + Modules + + } + isOpen={this.state.switchModule} + closePopover={() => this.setState({ switchModule: false })} + repositionOnScroll={false} + anchorPosition='downCenter' + > +
+ +
+ this.updateMenuAgents()} + closePopover={() => { + this.setState({ switchModule: false }); + }} + switchTab={module => this.props.switchTab(module)} + > +
+
+
+
+
+ )} + this.props.switchTab('syscollector')}> + iconType='inspect' + onClick={() => this.props.switchTab('syscollector')} + > Inventory data this.props.switchTab('stats')}> + iconType='stats' + onClick={() => this.props.switchTab('stats')} + > Stats this.props.switchTab('configuration')}> + iconType='gear' + onClick={() => this.props.switchTab('configuration')} + > Configuration
- ); - } + ); + } - buildTabCard(tab, icon) { - return ( - - } - className="homSynopsis__card" - title={WAZUH_MODULES[tab].title} - onClick={() => this.props.switchTab(tab)} - description={WAZUH_MODULES[tab].description} - /> - - ); - } - onClickRestartAgent = () => { - const { agent } = this.props; - ActionAgents.restartAgent(agent.id); - }; + buildTabCard(tab, icon) { + return ( + + } + className='homSynopsis__card' + title={WAZUH_MODULES[tab].title} + onClick={() => this.props.switchTab(tab)} + description={WAZUH_MODULES[tab].description} + /> + + ); + } + onClickRestartAgent = () => { + const { agent } = this.props; + ActionAgents.restartAgent(agent.id); + }; - onClickUpgradeAgent = () => { - const { agent } = this.props; - ActionAgents.upgradeAgent(agent.id); - }; + onClickUpgradeAgent = () => { + const { agent } = this.props; + ActionAgents.upgradeAgent(agent.id); + }; - renderUpgradeButton() { - const { managerVersion } = this.state; - const { agent } = this.props; - let outDated = ActionAgents.compareVersions(managerVersion, agent.version); + renderUpgradeButton() { + const { managerVersion } = this.state; + const { agent } = this.props; + let outDated = ActionAgents.compareVersions( + managerVersion, + agent.version, + ); - if (outDated === true) return; - return ( - - - Upgrade - - - ); - } + if (outDated === true) return; + return ( + + + Upgrade + + + ); + } - onTimeChange = (datePicker) => { - const { start: from, end: to } = datePicker; - this.setState({ datePicker: { from, to } }); - } + onTimeChange = datePicker => { + const { start: from, end: to } = datePicker; + this.setState({ datePicker: { from, to } }); + }; - getOptions() { - return [ - { value: 'pci', text: 'PCI DSS' }, - { value: 'gdpr', text: 'GDPR' }, - { value: 'nist', text: 'NIST 800-53' }, - { value: 'hipaa', text: 'HIPAA' }, - { value: 'gpg13', text: 'GPG13' }, - { value: 'tsc', text: 'TSC' }, - ]; - } + getOptions() { + return [ + { value: 'pci', text: 'PCI DSS' }, + { value: 'gdpr', text: 'GDPR' }, + { value: 'nist', text: 'NIST 800-53' }, + { value: 'hipaa', text: 'HIPAA' }, + { value: 'gpg13', text: 'GPG13' }, + { value: 'tsc', text: 'TSC' }, + ]; + } - setSelectValue(e) { - this.setState({ selectedRequirement: e.target.value }); - } + setSelectValue(e) { + this.setState({ selectedRequirement: e.target.value }); + } - getRequirementVis() { - if (this.state.selectedRequirement === 'pci') { + getRequirementVis() { + if (this.state.selectedRequirement === 'pci') { + return 'Wazuh-App-Agents-Welcome-Top-PCI'; + } + if (this.state.selectedRequirement === 'gdpr') { + return 'Wazuh-App-Agents-Welcome-Top-GDPR'; + } + if (this.state.selectedRequirement === 'hipaa') { + return 'Wazuh-App-Agents-Welcome-Top-HIPAA'; + } + if (this.state.selectedRequirement === 'nist') { + return 'Wazuh-App-Agents-Welcome-Top-NIST-800-53'; + } + if (this.state.selectedRequirement === 'gpg13') { + return 'Wazuh-App-Agents-Welcome-Top-GPG-13'; + } + if (this.state.selectedRequirement === 'tsc') { + return 'Wazuh-App-Agents-Welcome-Top-TSC'; + } return 'Wazuh-App-Agents-Welcome-Top-PCI'; } - if (this.state.selectedRequirement === 'gdpr') { - return 'Wazuh-App-Agents-Welcome-Top-GDPR'; - } - if (this.state.selectedRequirement === 'hipaa') { - return 'Wazuh-App-Agents-Welcome-Top-HIPAA'; - } - if (this.state.selectedRequirement === 'nist') { - return 'Wazuh-App-Agents-Welcome-Top-NIST-800-53'; - } - if (this.state.selectedRequirement === 'gpg13') { - return 'Wazuh-App-Agents-Welcome-Top-GPG-13'; + + renderMitrePanel() { + return ( + + + + + +

+ +

MITRE

+
+

+
+ + + { + window.location.href = `#/overview?tab=mitre`; + this.router.reload(); + }} + aria-label='Open MITRE' + /> + + +
+
+ + + + + + +
+
+ ); } - if (this.state.selectedRequirement === 'tsc') { - return 'Wazuh-App-Agents-Welcome-Top-TSC'; + + renderCompliancePanel() { + return ( + + ); } - return 'Wazuh-App-Agents-Welcome-Top-PCI' - } - renderMitrePanel() { - return ( - - + renderEventCountVisualization() { + return ( + -

-

MITRE

+

+ +

Events count evolution

+

- - - { - window.location.href = `#/overview?tab=mitre`; - this.router.reload(); - } - } - aria-label="Open MITRE" /> - -
+ +
+ + + +
+
+ +
- - - - - -
-
- - ) - } - - renderCompliancePanel() { - return ( - - ) - } - - renderEventCountVisualization() { - return ( - - - - -

-

Events count evolution

-

-
-
- -
- - - -
-
- -
-
-
- ) - } - - renderSCALastScan() { - return ( - - - - ) - } - - render() { - const title = this.renderTitle(); + ); + } - if (this.props.agent.status === API_NAME_AGENT_STATUS.NEVER_CONNECTED) { + renderSCALastScan() { return ( - Agent has never connected.} - body={ - -

- The agent has been registered but has not yet connected to the manager. -

- - Checking connection with the Wazuh server - -
- } - actions={ - - Back - - } - />) + + + + ); } - return ( -
-
-
- {title} -
-
-
- - + render() { + const title = this.renderTitle(); + + if (this.props.agent.status === API_NAME_AGENT_STATUS.NEVER_CONNECTED) { + return ( + Agent has never connected.} + body={ + +

+ The agent has been registered but has not yet connected to the + manager. +

+ + Checking connection with the Wazuh server + +
+ } + actions={ + + Back + + } + /> + ); + } -
-
- - - + return ( +
+
+
{title}
+
+
+ + +
+
+ + + +
-
- - - {/* DatePicker */} - { }} /> - - - {this.state.widthWindow < 1150 && ( - - - - {this.renderMitrePanel()} - - {this.renderCompliancePanel()} - - - - - - - - {/* Events count evolution */} - {this.renderEventCountVisualization()} - - - - - - {this.renderSCALastScan()} - - - - ) || ( + + + + {' '} + {/* DatePicker */} + {}} /> + + + {(this.state.widthWindow < 1150 && ( + + + + {this.renderMitrePanel()} + + {this.renderCompliancePanel()} + + + + + + + + + {' '} + {/* Events count evolution */} + {this.renderEventCountVisualization()} + + + + + {this.renderSCALastScan()} + + + )) || ( - + {this.renderMitrePanel()} {this.renderCompliancePanel()} - + - + - {/* Events count evolution */} + + {' '} + {/* Events count evolution */} {this.renderEventCountVisualization()} - - {this.renderSCALastScan()} - + {this.renderSCALastScan()} )} - - - + + +
-
- ); - } -}) + ); + } + }, +); 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/agents-preview.js b/public/controllers/agent/agents-preview.js index 5cc1669c65..6765e20679 100644 --- a/public/controllers/agent/agents-preview.js +++ b/public/controllers/agent/agents-preview.js @@ -35,7 +35,15 @@ export class AgentsPreviewController { * @param {Object} errorHandler * @param {Object} csvReq */ - constructor($scope, $location, $route, errorHandler, csvReq, commonData, $window) { + constructor( + $scope, + $location, + $route, + errorHandler, + csvReq, + commonData, + $window, + ) { this.$scope = $scope; this.genericReq = GenericRequest; this.$location = $location; @@ -57,11 +65,15 @@ export class AgentsPreviewController { this.api = JSON.parse(AppState.getCurrentAPI()).id; const loc = this.$location.search(); if ((loc || {}).agent && (loc || {}).agent !== '000') { - this.commonData.setTimefilter(getDataPlugin().timefilter.timefilter.getTime()); + this.commonData.setTimefilter( + getDataPlugin().timefilter.timefilter.getTime(), + ); return this.showAgent({ id: loc.agent }); } - this.isClusterEnabled = AppState.getClusterInfo() && AppState.getClusterInfo().status === 'enabled'; + this.isClusterEnabled = + AppState.getClusterInfo() && + AppState.getClusterInfo().status === 'enabled'; this.loading = true; this.osPlatforms = []; this.versions = []; @@ -82,7 +94,7 @@ export class AgentsPreviewController { this.$location.search('tab', this.submenuNavItem); }); - this.$scope.$on('wazuhFetched', (evt) => { + this.$scope.$on('wazuhFetched', evt => { evt.stopPropagation(); }); this.registerAgentsProps = { @@ -90,14 +102,14 @@ export class AgentsPreviewController { hasAgents: () => this.hasAgents, reload: () => this.$route.reload(), getWazuhVersion: () => this.getWazuhVersion(), - getCurrentApiAddress: () => this.getCurrentApiAddress() + getCurrentApiAddress: () => this.getCurrentApiAddress(), }; this.hasAgents = true; this.init = false; const instance = new DataFactory(WzRequest.apiReq, '/agents', false, false); //Props this.tableAgentsProps = { - updateSummary: (summary) => { + updateSummary: summary => { this.summary = summary; if (this.summary.total === 0) { if (this.addingNewAgent === undefined) { @@ -117,7 +129,7 @@ export class AgentsPreviewController { this.downloadCsv(filters); this.$scope.$applyAsync(); }, - showAgent: (agent) => { + showAgent: agent => { this.showAgent(agent); this.$scope.$applyAsync(); }, @@ -125,10 +137,17 @@ export class AgentsPreviewController { return await this.getMostActive(); }, clickAction: (item, openAction = false) => { - clickAction(item, openAction, instance, this.shareAgent, this.$location, this.$scope); + clickAction( + item, + openAction, + instance, + this.shareAgent, + this.$location, + this.$scope, + ); this.$scope.$applyAsync(); }, - formatUIDate: (date) => formatUIDate(date), + formatUIDate: date => formatUIDate(date), summary: this.summary, }; //Load @@ -187,14 +206,18 @@ export class AgentsPreviewController { 'GET', `/elastic/top/${this.firstUrlParam}/${this.secondUrlParam}/agent.name/${ this.pattern - }?agentsList=${store.getState().appStateReducers.allowedAgents.toString()}` + }?agentsList=${store + .getState() + .appStateReducers.allowedAgents.toString()}`, ); this.mostActiveAgent.name = data.data.data; const info = await this.genericReq.request( 'GET', `/elastic/top/${this.firstUrlParam}/${this.secondUrlParam}/agent.id/${ this.pattern - }?agentsList=${store.getState().appStateReducers.allowedAgents.toString()}` + }?agentsList=${store + .getState() + .appStateReducers.allowedAgents.toString()}`, ); if (info.data.data === '' && this.mostActiveAgent.name !== '') { this.mostActiveAgent.id = '000'; @@ -227,9 +250,12 @@ export class AgentsPreviewController { try { this.errorInit = false; const clusterInfo = AppState.getClusterInfo(); - this.firstUrlParam = clusterInfo.status === 'enabled' ? 'cluster' : 'manager'; + this.firstUrlParam = + clusterInfo.status === 'enabled' ? 'cluster' : 'manager'; this.secondUrlParam = clusterInfo[this.firstUrlParam]; - this.pattern = (await getDataPlugin().indexPatterns.get(AppState.getCurrentPattern())).title; + this.pattern = ( + await getDataPlugin().indexPatterns.get(AppState.getCurrentPattern()) + ).title; } catch (error) { const options = { context: `${AgentsPreviewController.name}.load`, @@ -252,12 +278,6 @@ export class AgentsPreviewController { this.addingNewAgent = flag; } - openRegistrationDocs() { - this.$window.open(webDocumentationLink(user-manual/registering/index.html), - '_blank' - ); - } - /** * Returns the current API address */ @@ -265,7 +285,7 @@ export class AgentsPreviewController { try { const result = await this.genericReq.request('GET', '/hosts/apis'); const entries = result.data || []; - const host = entries.filter((e) => { + const host = entries.filter(e => { return e.id == this.api; }); const url = host[0].url; @@ -279,7 +299,9 @@ export class AgentsPreviewController { error: { error: error, message: error.message || error, - title: `Could not get the Wazuh API address: ${error.message || error}`, + title: `Could not get the Wazuh API address: ${ + error.message || error + }`, }, }; getErrorOrchestrator().handleError(options); diff --git a/public/controllers/agent/components/agents-preview.js b/public/controllers/agent/components/agents-preview.js index 1d27b4b359..f372bf5202 100644 --- a/public/controllers/agent/components/agents-preview.js +++ b/public/controllers/agent/components/agents-preview.js @@ -41,11 +41,17 @@ import { formatUIDate } from '../../../../public/react-services/time-service'; import { compose } from 'redux'; import { withErrorBoundary } from '../../../components/common/hocs'; import './agents-preview.scss'; -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'; import { VisualizationBasic } from '../../../components/common/charts/visualizations/basic'; -import { agentStatusColorByAgentStatus, agentStatusLabelByAgentStatus } from '../../../../common/services/wz_agent_status'; +import { + agentStatusColorByAgentStatus, + agentStatusLabelByAgentStatus, +} from '../../../../common/services/wz_agent_status'; export const AgentsPreview = compose( withErrorBoundary, @@ -56,7 +62,7 @@ export const AgentsPreview = compose( { action: 'agent:read', resource: 'agent:id:*' }, { action: 'agent:read', resource: 'agent:group:*' }, ], - ]) + ]), )( class AgentsPreview extends Component { _isMount = false; @@ -67,7 +73,13 @@ export const AgentsPreview = compose( loadingSummary: false, showAgentsEvolutionVisualization: true, agentTableFilters: [], - agentStatusSummary: { active: '-', disconnected: '-', total: '-', pending: '-', never_connected: '-' }, + agentStatusSummary: { + active: '-', + disconnected: '-', + total: '-', + pending: '-', + never_connected: '-', + }, agentConfiguration: {}, agentsActiveCoverage: 0, }; @@ -75,7 +87,7 @@ export const AgentsPreview = compose( this.agentStatus = UI_ORDER_AGENT_STATUS.map(agentStatus => ({ status: agentStatus, label: agentStatusLabelByAgentStatus(agentStatus), - color: agentStatusColorByAgentStatus(agentStatus) + color: agentStatusColorByAgentStatus(agentStatus), })); } @@ -83,9 +95,10 @@ export const AgentsPreview = compose( this._isMount = true; this.fetchAgentStatusDetailsData(); if (this.wazuhConfig.getConfig()['wazuh.monitoring.enabled']) { - this._isMount && this.setState({ - showAgentsEvolutionVisualization: true - }); + this._isMount && + this.setState({ + showAgentsEvolutionVisualization: true, + }); const tabVisualizations = new TabVisualizations(); tabVisualizations.removeAll(); tabVisualizations.setTab('general'); @@ -93,7 +106,11 @@ export const AgentsPreview = compose( general: 1, }); const filterHandler = new FilterHandler(AppState.getCurrentPattern()); - await VisFactoryHandler.buildOverviewVisualizations(filterHandler, 'general', null); + await VisFactoryHandler.buildOverviewVisualizations( + filterHandler, + 'general', + null, + ); } } @@ -101,7 +118,6 @@ export const AgentsPreview = compose( this._isMount = false; } - groupBy = function (arr) { return arr.reduce(function (prev, item) { if (item in prev) prev[item]++; @@ -111,30 +127,54 @@ export const AgentsPreview = compose( }; async fetchSummaryStatus() { this.setState({ loadingSummary: true }); - const {data: {data: { connection: agentStatusSummary, configuration: agentConfiguration }}} = await WzRequest.apiReq('GET', '/agents/summary/status', {}); + const { + data: { + data: { + connection: agentStatusSummary, + configuration: agentConfiguration, + }, + }, + } = await WzRequest.apiReq('GET', '/agents/summary/status', {}); this.props.tableProps.updateSummary(agentStatusSummary); + + const agentsActiveCoverage = ( + (agentStatusSummary.active / agentStatusSummary.total) * + 100 + ).toFixed(2); + this.setState({ loadingSummary: false, agentStatusSummary, agentConfiguration, - agentsActiveCoverage: ((agentStatusSummary.active / agentStatusSummary.total) * 100).toFixed(2), + /* Calculate the agents active coverage. + Ensure the calculated value is not a NaN, otherwise set a 0. + */ + agentsActiveCoverage: isNaN(agentsActiveCoverage) + ? 0 + : agentsActiveCoverage, }); } async fetchAgents() { this.setState({ loadingAgents: true }); - const { data: { data: { affected_items: [lastRegisteredAgent] } } } = await WzRequest.apiReq('GET', '/agents', { + const { + data: { + data: { + affected_items: [lastRegisteredAgent], + }, + }, + } = await WzRequest.apiReq('GET', '/agents', { params: { limit: 1, sort: '-dateAdd', q: 'id!=000' }, }); const agentMostActive = await this.props.tableProps.getMostActive(); this.setState({ loadingAgents: false, lastRegisteredAgent, - agentMostActive + agentMostActive, }); } - async fetchAgentStatusDetailsData(){ + async fetchAgentStatusDetailsData() { try { this.fetchSummaryStatus(); this.fetchAgents(); @@ -169,37 +209,44 @@ export const AgentsPreview = compose( agentTableFilters: [{ field: 'q', value: `status=${status}` }], }); } - onRenderComplete(){ + onRenderComplete() { this.setState({ - evolutionRenderComplete: true - }) + evolutionRenderComplete: true, + }); } render() { const evolutionIsReady = this.props.resultState !== 'loading'; return ( - + - - { - ( + + { <> - - + + - + ({ - label, - value: this.state.agentStatusSummary[status] || 0, - color, - onClick: () => this.filterAgentByStatus(status) - }))} + data={this.agentStatus.map( + ({ status, label, color }) => ({ + label, + value: + this.state.agentStatusSummary[status] || 0, + color, + onClick: () => this.filterAgentByStatus(status), + }), + )} noDataTitle='No results' noDataMessage='No results were found.' /> @@ -207,24 +254,32 @@ export const AgentsPreview = compose( - - - - {this.agentStatus.map(({status, label, color}) => ( + + + + {this.agentStatus.map(({ status, label, color }) => ( - this.filterAgentByStatus(status)} style={{cursor: 'pointer'}}> + + + this.filterAgentByStatus(status) + } + style={{ cursor: 'pointer' }} + > {this.state.agentStatusSummary[status]} } - titleSize="s" + titleSize='s' description={label} titleColor={color} - className="white-space-nowrap" + className='white-space-nowrap' /> ))} @@ -233,43 +288,63 @@ export const AgentsPreview = compose( isLoading={this.state.loadingSummary} title={`${this.state.agentsActiveCoverage}%`} titleSize='s' - description="Agents coverage" - className="white-space-nowrap" - /> + description='Agents coverage' + className='white-space-nowrap' + /> - - - - this.showAgent(this.state.lastRegisteredAgent)}> - {this.state.lastRegisteredAgent?.name || '-'} - - - } - titleSize="s" - description="Last registered agent" - titleColor="primary" - /> - + + + + + this.showAgent( + this.state.lastRegisteredAgent, + ) + } + > + {this.state.lastRegisteredAgent?.name || '-'} + + + } + titleSize='s' + description='Last registered agent' + titleColor='primary' + /> + { - + - this.showAgent(this.state.agentMostActive)}> + + + this.showAgent(this.state.agentMostActive) + } + > {this.state.agentMostActive?.name || '-'} } - titleSize="s" - description="Most active agent" - titleColor="primary" + titleSize='s' + description='Most active agent' + titleColor='primary' /> } @@ -277,41 +352,41 @@ export const AgentsPreview = compose( - )} - + - - - + +
- - - + + + +
+ {!evolutionIsReady && ( +
+
- {!evolutionIsReady && ( -
- -
- )} -
-
-
-
+ )} +
+
+ +
- + formatUIDate(date)} reload={() => this.fetchAgentStatusDetailsData()} /> @@ -328,7 +402,7 @@ export const AgentsPreview = compose(
); } - } + }, ); AgentsTable.propTypes = { diff --git a/public/controllers/agent/components/agents-table.js b/public/controllers/agent/components/agents-table.js index 55ce4d48d9..e517f99a7b 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,40 @@ export const AgentsTable = withErrorBoundary( actionButtonsRender(agent) { return (
- + { + onClick={ev => { ev.stopPropagation(); - this.props.clickAction(agent, 'default'); + AppNavigate.navigateToModule(ev, 'agents', { + tab: 'welcome', + agent: agent.id, + }); }} - 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'); + AppNavigate.navigateToModule(ev, 'agents', { + tab: 'configuration', + agent: agent.id, + }); }} color={'primary'} - iconType="wrench" - aria-label="Open configuration for this agent" + iconType='wrench' + aria-label='Open configuration for this agent' /> )} @@ -337,7 +384,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 +397,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 +423,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 +438,14 @@ export const AgentsTable = withErrorBoundary( return ( <> - + Export formatted - + - + @@ -423,11 +470,13 @@ export const AgentsTable = withErrorBoundary( } else if (selectedItems.length === pageSize) { return (
- + @@ -435,7 +484,7 @@ export const AgentsTable = withErrorBoundary( { this._isMount && - this.setState((prevState) => ({ + this.setState(prevState => ({ allSelected: !prevState.allSelected, })); }} @@ -447,18 +496,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 +542,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 +581,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 +601,7 @@ export const AgentsTable = withErrorBoundary( field: 'actions', name: 'Actions', show: true, - render: (agent) => this.actionButtonsRender(agent), + render: agent => this.actionButtonsRender(agent), }, ]; @@ -550,15 +610,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 +650,9 @@ export const AgentsTable = withErrorBoundary( this.props.addingNewAgent()} > Deploy new agent @@ -598,7 +660,7 @@ export const AgentsTable = withErrorBoundary( {formattedButton}
- +
); } @@ -611,12 +673,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 +695,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 +718,7 @@ export const AgentsTable = withErrorBoundary( @@ -661,12 +729,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 +743,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 +766,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 +783,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 +803,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 +833,6 @@ export const AgentsTable = withErrorBoundary( /> ); } - render() { const title = this.headRender(); const filter = this.filterBarRender(); @@ -772,8 +844,8 @@ export const AgentsTable = withErrorBoundary( return (
{filter} - - + + {title} {loadItems} {callOut} @@ -784,14 +856,13 @@ export const AgentsTable = withErrorBoundary(
); } - } + }, ); AgentsTable.propTypes = { wzReq: PropTypes.func, addingNewAgent: PropTypes.func, downloadCsv: PropTypes.func, - clickAction: PropTypes.func, timeService: PropTypes.func, reload: PropTypes.func, }; diff --git a/public/controllers/agent/components/register-agent.js b/public/controllers/agent/components/register-agent.js index 99b0a5b105..94a1b3db23 100644 --- a/public/controllers/agent/components/register-agent.js +++ b/public/controllers/agent/components/register-agent.js @@ -271,7 +271,7 @@ export const RegisterAgent = withErrorBoundary( this.state.selectedVersion === 'windowsserver2008' || this.state.selectedVersion === 'windows7' ) { - return 'NET START WazuhSvc'; + return 'NET START Wazuh'; } else { return ''; } @@ -1005,7 +1005,7 @@ export const RegisterAgent = withErrorBoundary( : ``; // Merge environment variables with installation script - const macOSInstallationScript = `curl -so wazuh-agent.pkg https://packages.wazuh.com/4.x/macos/wazuh-agent-${this.state.wazuhVersion}-1.pkg && ${macOSInstallationSetEnvVariablesScript}sudo installer -pkg ./wazuh-agent.pkg -target /`; + const macOSInstallationScript = `curl -so wazuh-agent.pkg https://packages.wazuh.com/4.x/macos/wazuh-agent-${this.state.wazuhVersion}-1.${this.state.selectedArchitecture}.pkg && ${macOSInstallationSetEnvVariablesScript}sudo installer -pkg ./wazuh-agent.pkg -target /`; /*** end macOS installation script customization ***/ diff --git a/public/controllers/agent/wazuh-config/index.ts b/public/controllers/agent/wazuh-config/index.ts index e555fb5517..f10c7994c1 100644 --- a/public/controllers/agent/wazuh-config/index.ts +++ b/public/controllers/agent/wazuh-config/index.ts @@ -103,8 +103,12 @@ const architectureButtonsSolaris = [ const architectureButtonsMacos = [ { - id: 'intel/applesilicon', - label: 'Intel/Apple Silicon', + id: 'intel64', + label: 'Intel', + }, + { + id: 'arm64', + label: 'Apple Silicon', }, ]; 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()), }; };