From b6a1b8430e9a055f1ddfa99c0950de38962f2a73 Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 4 Sep 2026 08:20:23 +0200 Subject: [PATCH 1/4] add: add get_report_exports request support --- gvm/protocols/gmp/_gmpnext.py | 23 +++++++++++++ gvm/protocols/gmp/requests/next/__init__.py | 4 +++ .../gmp/requests/next/_report_exports.py | 32 +++++++++++++++++++ .../entities/report_exports/__init__.py | 9 ++++++ .../report_exports/test_get_report_exports.py | 18 +++++++++++ .../gmpnext/entities/test_report_exports.py | 13 ++++++++ 6 files changed, 99 insertions(+) create mode 100644 gvm/protocols/gmp/requests/next/_report_exports.py create mode 100644 tests/protocols/gmpnext/entities/report_exports/__init__.py create mode 100644 tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py create mode 100644 tests/protocols/gmpnext/entities/test_report_exports.py diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py index 357c236e..7ce58f10 100644 --- a/gvm/protocols/gmp/_gmpnext.py +++ b/gvm/protocols/gmp/_gmpnext.py @@ -26,6 +26,7 @@ ReportClosedCVEs, ReportCVEs, ReportErrors, + ReportExports, ReportHosts, ReportOperatingSystems, ReportPorts, @@ -1808,3 +1809,25 @@ def export_scan_report( result_tags=result_tags, ) ) + + def get_report_exports( + self, + *, + report_export_id: EntityID | None = None, + ) -> T: + """Request report exports. + + If report_export_id is provided, only the matching report export is + requested. Otherwise, the command requests a list of report exports. + + Args: + report_export_id: UUID of an optional report export. + + Returns: + A request for the get_report_exports GMP command. + """ + return self._send_request_and_transform_response( + ReportExports.get_report_exports( + report_export_id=report_export_id, + ) + ) diff --git a/gvm/protocols/gmp/requests/next/__init__.py b/gvm/protocols/gmp/requests/next/__init__.py index a4b8f046..ff9cbcff 100644 --- a/gvm/protocols/gmp/requests/next/__init__.py +++ b/gvm/protocols/gmp/requests/next/__init__.py @@ -30,6 +30,9 @@ from gvm.protocols.gmp.requests.next._report_errors import ( ReportErrors, ) +from gvm.protocols.gmp.requests.next._report_exports import ( + ReportExports, +) from gvm.protocols.gmp.requests.next._report_hosts import ( ReportHosts, ) @@ -174,6 +177,7 @@ "ReportConfigParameter", "ReportConfigs", "ReportErrors", + "ReportExports", "ReportFormatType", "ReportFormats", "ReportHosts", diff --git a/gvm/protocols/gmp/requests/next/_report_exports.py b/gvm/protocols/gmp/requests/next/_report_exports.py new file mode 100644 index 00000000..57459c58 --- /dev/null +++ b/gvm/protocols/gmp/requests/next/_report_exports.py @@ -0,0 +1,32 @@ +from gvm.protocols.core import Request +from gvm.protocols.gmp.requests import EntityID +from gvm.xml import XmlCommand + + +class ReportExports: + @classmethod + def get_report_exports( + cls, + *, + report_export_id: EntityID | None = None, + ) -> Request: + """Request report exports. + + If report_export_id is provided, only the matching report export is + requested. Otherwise, the command requests a list of report exports. + + Args: + report_export_id: UUID of an optional report export. + + Returns: + A request for the get_report_exports GMP command. + """ + cmd = XmlCommand("get_report_exports") + + if report_export_id: + cmd.set_attribute( + "report_export_id", + str(report_export_id), + ) + + return cmd diff --git a/tests/protocols/gmpnext/entities/report_exports/__init__.py b/tests/protocols/gmpnext/entities/report_exports/__init__.py new file mode 100644 index 00000000..a378495a --- /dev/null +++ b/tests/protocols/gmpnext/entities/report_exports/__init__.py @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from .test_get_report_exports import GmpGetReportExportsTestMixin + +__all__ = [ + "GmpGetReportExportsTestMixin", +] diff --git a/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py b/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py new file mode 100644 index 00000000..204ca257 --- /dev/null +++ b/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + + +class GmpGetReportExportsTestMixin: + def test_get_report_exports(self): + self.gmp.get_report_exports() + + self.connection.send.has_been_called_with(b"") + + def test_get_report_exports_with_id(self): + self.gmp.get_report_exports(report_export_id="e1") + + self.connection.send.has_been_called_with( + b'' + ) diff --git a/tests/protocols/gmpnext/entities/test_report_exports.py b/tests/protocols/gmpnext/entities/test_report_exports.py new file mode 100644 index 00000000..7b2e4715 --- /dev/null +++ b/tests/protocols/gmpnext/entities/test_report_exports.py @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from ...gmpnext import GMPTestCase +from .report_exports import ( + GmpGetReportExportsTestMixin, +) + + +class GmpGmpGetReportExportsTestCase(GmpGetReportExportsTestMixin, GMPTestCase): + pass From be5a3f6a2edf565ebcce5cb0711b0ab7851e218f Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 4 Sep 2026 08:21:33 +0200 Subject: [PATCH 2/4] add: add missing license headers to Python files --- gvm/protocols/gmp/requests/next/_integration_configs.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_applications.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_closed_cves.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_cves.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_errors.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_hosts.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_operating_systems.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_ports.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_tls_certificates.py | 4 ++++ gvm/protocols/gmp/requests/next/_report_vulnerabilities.py | 4 ++++ gvm/protocols/gmp/requests/next/_scan_report.py | 4 ++++ 11 files changed, 44 insertions(+) diff --git a/gvm/protocols/gmp/requests/next/_integration_configs.py b/gvm/protocols/gmp/requests/next/_integration_configs.py index d0576852..fd2d3bcc 100644 --- a/gvm/protocols/gmp/requests/next/_integration_configs.py +++ b/gvm/protocols/gmp/requests/next/_integration_configs.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_applications.py b/gvm/protocols/gmp/requests/next/_report_applications.py index 6875709d..179fcc22 100644 --- a/gvm/protocols/gmp/requests/next/_report_applications.py +++ b/gvm/protocols/gmp/requests/next/_report_applications.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_closed_cves.py b/gvm/protocols/gmp/requests/next/_report_closed_cves.py index 2650101d..9c485977 100644 --- a/gvm/protocols/gmp/requests/next/_report_closed_cves.py +++ b/gvm/protocols/gmp/requests/next/_report_closed_cves.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_cves.py b/gvm/protocols/gmp/requests/next/_report_cves.py index ef1fc28b..8a0fc169 100644 --- a/gvm/protocols/gmp/requests/next/_report_cves.py +++ b/gvm/protocols/gmp/requests/next/_report_cves.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_errors.py b/gvm/protocols/gmp/requests/next/_report_errors.py index e36af893..6c61e99b 100644 --- a/gvm/protocols/gmp/requests/next/_report_errors.py +++ b/gvm/protocols/gmp/requests/next/_report_errors.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_hosts.py b/gvm/protocols/gmp/requests/next/_report_hosts.py index 7237163f..7e9fd798 100644 --- a/gvm/protocols/gmp/requests/next/_report_hosts.py +++ b/gvm/protocols/gmp/requests/next/_report_hosts.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_operating_systems.py b/gvm/protocols/gmp/requests/next/_report_operating_systems.py index 36fc1ca6..49d2c810 100644 --- a/gvm/protocols/gmp/requests/next/_report_operating_systems.py +++ b/gvm/protocols/gmp/requests/next/_report_operating_systems.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_ports.py b/gvm/protocols/gmp/requests/next/_report_ports.py index fe3ba7af..49a7e706 100644 --- a/gvm/protocols/gmp/requests/next/_report_ports.py +++ b/gvm/protocols/gmp/requests/next/_report_ports.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_tls_certificates.py b/gvm/protocols/gmp/requests/next/_report_tls_certificates.py index 13ff8168..058595cf 100644 --- a/gvm/protocols/gmp/requests/next/_report_tls_certificates.py +++ b/gvm/protocols/gmp/requests/next/_report_tls_certificates.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_report_vulnerabilities.py b/gvm/protocols/gmp/requests/next/_report_vulnerabilities.py index a5a9b18a..90a8eb30 100644 --- a/gvm/protocols/gmp/requests/next/_report_vulnerabilities.py +++ b/gvm/protocols/gmp/requests/next/_report_vulnerabilities.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID diff --git a/gvm/protocols/gmp/requests/next/_scan_report.py b/gvm/protocols/gmp/requests/next/_scan_report.py index b7c13589..50e4334f 100644 --- a/gvm/protocols/gmp/requests/next/_scan_report.py +++ b/gvm/protocols/gmp/requests/next/_scan_report.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID From 4749a4b1f9630557f86463cc75f31263cd659ac9 Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 4 Sep 2026 08:54:19 +0200 Subject: [PATCH 3/4] change: split report export list and single retrieval --- gvm/protocols/gmp/_gmpnext.py | 22 ++++++++++++++----- .../gmp/requests/next/_report_exports.py | 21 +++++++++++++----- .../entities/report_exports/__init__.py | 2 ++ .../report_exports/test_get_report_export.py | 18 +++++++++++++++ .../report_exports/test_get_report_exports.py | 7 ------ .../gmpnext/entities/test_report_exports.py | 5 +++++ 6 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py index 7ce58f10..2696f45f 100644 --- a/gvm/protocols/gmp/_gmpnext.py +++ b/gvm/protocols/gmp/_gmpnext.py @@ -1812,22 +1812,32 @@ def export_scan_report( def get_report_exports( self, - *, - report_export_id: EntityID | None = None, ) -> T: """Request report exports. - If report_export_id is provided, only the matching report export is - requested. Otherwise, the command requests a list of report exports. + The command requests a list of report exports. + + Returns: + A request for the get_report_exports GMP command. + """ + return self._send_request_and_transform_response( + ReportExports.get_report_exports() + ) + + def get_report_export( + self, + report_export_id: EntityID | None = None, + ) -> T: + """Request a single report export. Args: - report_export_id: UUID of an optional report export. + report_export_id: UUID of the report export. Returns: A request for the get_report_exports GMP command. """ return self._send_request_and_transform_response( - ReportExports.get_report_exports( + ReportExports.get_report_export( report_export_id=report_export_id, ) ) diff --git a/gvm/protocols/gmp/requests/next/_report_exports.py b/gvm/protocols/gmp/requests/next/_report_exports.py index 57459c58..0acf9010 100644 --- a/gvm/protocols/gmp/requests/next/_report_exports.py +++ b/gvm/protocols/gmp/requests/next/_report_exports.py @@ -7,16 +7,27 @@ class ReportExports: @classmethod def get_report_exports( cls, - *, - report_export_id: EntityID | None = None, ) -> Request: """Request report exports. - If report_export_id is provided, only the matching report export is - requested. Otherwise, the command requests a list of report exports. + The command requests a list of report exports. + + Returns: + A request for the get_report_exports GMP command. + """ + cmd = XmlCommand("get_report_exports") + + return cmd + + @classmethod + def get_report_export( + cls, + report_export_id: EntityID, + ) -> Request: + """Request a single report export. Args: - report_export_id: UUID of an optional report export. + report_export_id: UUID of the report export. Returns: A request for the get_report_exports GMP command. diff --git a/tests/protocols/gmpnext/entities/report_exports/__init__.py b/tests/protocols/gmpnext/entities/report_exports/__init__.py index a378495a..67091b86 100644 --- a/tests/protocols/gmpnext/entities/report_exports/__init__.py +++ b/tests/protocols/gmpnext/entities/report_exports/__init__.py @@ -2,8 +2,10 @@ # # SPDX-License-Identifier: GPL-3.0-or-later +from .test_get_report_export import GmpGetReportExportTestMixin from .test_get_report_exports import GmpGetReportExportsTestMixin __all__ = [ + "GmpGetReportExportTestMixin", "GmpGetReportExportsTestMixin", ] diff --git a/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py b/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py new file mode 100644 index 00000000..dd15762c --- /dev/null +++ b/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + + +class GmpGetReportExportTestMixin: + def test_get_report_export_without_id(self): + self.gmp.get_report_export() + + self.connection.send.has_been_called_with(b"") + + def test_get_report_export_with_id(self): + self.gmp.get_report_export(report_export_id="e1") + + self.connection.send.has_been_called_with( + b'' + ) diff --git a/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py b/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py index 204ca257..16691f85 100644 --- a/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py +++ b/tests/protocols/gmpnext/entities/report_exports/test_get_report_exports.py @@ -9,10 +9,3 @@ def test_get_report_exports(self): self.gmp.get_report_exports() self.connection.send.has_been_called_with(b"") - - def test_get_report_exports_with_id(self): - self.gmp.get_report_exports(report_export_id="e1") - - self.connection.send.has_been_called_with( - b'' - ) diff --git a/tests/protocols/gmpnext/entities/test_report_exports.py b/tests/protocols/gmpnext/entities/test_report_exports.py index 7b2e4715..c0d358a7 100644 --- a/tests/protocols/gmpnext/entities/test_report_exports.py +++ b/tests/protocols/gmpnext/entities/test_report_exports.py @@ -6,8 +6,13 @@ from ...gmpnext import GMPTestCase from .report_exports import ( GmpGetReportExportsTestMixin, + GmpGetReportExportTestMixin, ) class GmpGmpGetReportExportsTestCase(GmpGetReportExportsTestMixin, GMPTestCase): pass + + +class GmpGmpGetReportExportTestCase(GmpGetReportExportTestMixin, GMPTestCase): + pass From b71fb2a4d3560cf874aa412a906774f7542b9227 Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 4 Sep 2026 09:07:39 +0200 Subject: [PATCH 4/4] change: split report export list and single retrieval --- gvm/protocols/gmp/_gmpnext.py | 2 +- .../gmp/requests/next/_report_exports.py | 24 ++++++++++++++----- .../report_exports/test_get_report_export.py | 7 ++++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py index 2696f45f..c67f798f 100644 --- a/gvm/protocols/gmp/_gmpnext.py +++ b/gvm/protocols/gmp/_gmpnext.py @@ -1826,7 +1826,7 @@ def get_report_exports( def get_report_export( self, - report_export_id: EntityID | None = None, + report_export_id: EntityID, ) -> T: """Request a single report export. diff --git a/gvm/protocols/gmp/requests/next/_report_exports.py b/gvm/protocols/gmp/requests/next/_report_exports.py index 0acf9010..0c1147fd 100644 --- a/gvm/protocols/gmp/requests/next/_report_exports.py +++ b/gvm/protocols/gmp/requests/next/_report_exports.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from gvm.errors import RequiredArgument from gvm.protocols.core import Request from gvm.protocols.gmp.requests import EntityID from gvm.xml import XmlCommand @@ -31,13 +36,20 @@ def get_report_export( Returns: A request for the get_report_exports GMP command. - """ - cmd = XmlCommand("get_report_exports") - if report_export_id: - cmd.set_attribute( - "report_export_id", - str(report_export_id), + Raises: + RequiredArgument: If report_export_id is not provided. + """ + if not report_export_id: + raise RequiredArgument( + function=cls.get_report_export.__name__, + argument="report_export_id", ) + cmd = XmlCommand("get_report_exports") + cmd.set_attribute( + "report_export_id", + str(report_export_id), + ) + return cmd diff --git a/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py b/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py index dd15762c..f73663b8 100644 --- a/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py +++ b/tests/protocols/gmpnext/entities/report_exports/test_get_report_export.py @@ -2,13 +2,16 @@ # # SPDX-License-Identifier: GPL-3.0-or-later # +from gvm.errors import RequiredArgument class GmpGetReportExportTestMixin: def test_get_report_export_without_id(self): - self.gmp.get_report_export() + with self.assertRaises(RequiredArgument): + self.gmp.get_report_export(None) - self.connection.send.has_been_called_with(b"") + with self.assertRaises(RequiredArgument): + self.gmp.get_report_export("") def test_get_report_export_with_id(self): self.gmp.get_report_export(report_export_id="e1")