diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py
index b2a702e9..0487354e 100644
--- a/gvm/protocols/gmp/_gmpnext.py
+++ b/gvm/protocols/gmp/_gmpnext.py
@@ -1916,6 +1916,59 @@ def export_audit_report(
)
)
+ def export_delta_audit_report(
+ self,
+ report_id: EntityID,
+ delta_report_id: EntityID,
+ format_id: EntityID,
+ *,
+ config_id: EntityID | None = None,
+ filter_string: str | None = None,
+ ignore_pagination: bool = False,
+ lean: bool = False,
+ notes_details: bool = False,
+ overrides_details: bool = False,
+ result_tags: bool = False,
+ ) -> T:
+ """Request an asynchronous export of a delta audit report.
+
+ If an identical export is already pending or running, the existing
+ report export is returned instead of creating a duplicate.
+
+ Args:
+ report_id: UUID of the audit report to export.
+ delta_report_id: UUID of the report used for delta comparison.
+ format_id: UUID of the report format to apply.
+ config_id: UUID of an optional report configuration.
+ filter_string: Filter term to apply while generating the report.
+ ignore_pagination: Whether pagination settings in the filter
+ should be ignored.
+ lean: Whether lean report data should be generated.
+ notes_details: Whether note details should be included.
+ overrides_details: Whether override details should be included.
+ result_tags: Whether result tags should be included.
+
+ Returns:
+ A request for the export_delta_audit_report GMP command.
+
+ Raises:
+ RequiredArgument: If report_id or delta_report_id is not provided.
+ """
+ return self._send_request_and_transform_response(
+ AuditReport.export_delta_audit_report(
+ report_id=report_id,
+ delta_report_id=delta_report_id,
+ format_id=format_id,
+ config_id=config_id,
+ filter_string=filter_string,
+ ignore_pagination=ignore_pagination,
+ lean=lean,
+ notes_details=notes_details,
+ overrides_details=overrides_details,
+ result_tags=result_tags,
+ )
+ )
+
def get_report_exports(
self,
) -> T:
diff --git a/gvm/protocols/gmp/requests/next/_audit_report.py b/gvm/protocols/gmp/requests/next/_audit_report.py
index 46ee7902..144c5957 100644
--- a/gvm/protocols/gmp/requests/next/_audit_report.py
+++ b/gvm/protocols/gmp/requests/next/_audit_report.py
@@ -111,3 +111,85 @@ def export_audit_report(
)
return cmd
+
+ @classmethod
+ def export_delta_audit_report(
+ cls,
+ report_id: EntityID,
+ delta_report_id: EntityID,
+ format_id: EntityID,
+ *,
+ config_id: EntityID | None = None,
+ filter_string: str | None = None,
+ ignore_pagination: bool = False,
+ lean: bool = False,
+ notes_details: bool = False,
+ overrides_details: bool = False,
+ result_tags: bool = False,
+ ) -> Request:
+ """Request an asynchronous export of a delta audit report.
+
+ If an identical export is already pending or running, the existing
+ report export is returned instead of creating a duplicate.
+
+ Args:
+ report_id: UUID of the audit report to export.
+ delta_report_id: UUID of the report used for delta comparison.
+ format_id: UUID of the report format to apply.
+ config_id: UUID of an optional report configuration.
+ filter_string: Filter term to apply while generating the report.
+ ignore_pagination: Whether pagination settings in the filter
+ should be ignored.
+ lean: Whether lean report data should be generated.
+ notes_details: Whether note details should be included.
+ overrides_details: Whether override details should be included.
+ result_tags: Whether result tags should be included.
+
+ Returns:
+ A request for the export_delta_audit_report GMP command.
+
+ Raises:
+ RequiredArgument: If report_id or delta_report_id is not provided.
+ """
+ if not report_id:
+ raise RequiredArgument(
+ function=cls.export_delta_audit_report.__name__,
+ argument="report_id",
+ )
+
+ if not delta_report_id:
+ raise RequiredArgument(
+ function=cls.export_delta_audit_report.__name__,
+ argument="delta_report_id",
+ )
+
+ cmd = XmlCommand("export_delta_audit_report")
+ cmd.set_attribute("report_id", str(report_id))
+ cmd.set_attribute("delta_report_id", str(delta_report_id))
+ cmd.set_attribute("format_id", str(format_id))
+
+ if config_id:
+ cmd.set_attribute("config_id", str(config_id))
+
+ if filter_string is not None:
+ cmd.set_attribute("filter", filter_string)
+
+ cmd.set_attribute(
+ "ignore_pagination",
+ to_bool(ignore_pagination),
+ )
+ cmd.set_attribute("lean", to_bool(lean))
+ cmd.set_attribute(
+ "notes_details",
+ to_bool(notes_details),
+ )
+ cmd.set_attribute(
+ "overrides_details",
+ to_bool(overrides_details),
+ )
+ cmd.set_attribute(
+ "result_tags",
+ to_bool(result_tags),
+ )
+
+ return cmd
diff --git a/tests/protocols/gmpnext/entities/audit_report/__init__.py b/tests/protocols/gmpnext/entities/audit_report/__init__.py
index f7e2ed9a..3ab14f40 100644
--- a/tests/protocols/gmpnext/entities/audit_report/__init__.py
+++ b/tests/protocols/gmpnext/entities/audit_report/__init__.py
@@ -6,6 +6,9 @@
from .test_export_audit_report import (
GmpExportAuditReportTestMixin,
)
+from .test_export_delta_audit_report import (
+ GmpExportDeltaAuditReportTestMixin,
+)
from .test_get_audit_report import (
GmpGetAuditReportTestMixin,
)
@@ -15,6 +18,7 @@
__all__ = (
"GmpExportAuditReportTestMixin",
+ "GmpExportDeltaAuditReportTestMixin",
"GmpGetAuditReportLegacyTestMixin",
"GmpGetAuditReportTestMixin",
)
diff --git a/tests/protocols/gmpnext/entities/audit_report/test_export_delta_audit_report.py b/tests/protocols/gmpnext/entities/audit_report/test_export_delta_audit_report.py
new file mode 100644
index 00000000..38d6d25b
--- /dev/null
+++ b/tests/protocols/gmpnext/entities/audit_report/test_export_delta_audit_report.py
@@ -0,0 +1,179 @@
+# SPDX-FileCopyrightText: 2026 Greenbone AG
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from gvm.errors import RequiredArgument
+
+
+class GmpExportDeltaAuditReportTestMixin:
+ def test_export_delta_audit_report_without_report_id(self):
+ with self.assertRaises(RequiredArgument):
+ self.gmp.export_delta_audit_report(
+ None,
+ delta_report_id="d1",
+ format_id="f1",
+ )
+
+ with self.assertRaises(RequiredArgument):
+ self.gmp.export_delta_audit_report(
+ "",
+ delta_report_id="d1",
+ format_id="f1",
+ )
+
+ def test_export_delta_audit_report_without_delta_report_id(self):
+ with self.assertRaises(RequiredArgument):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id=None,
+ format_id="f1",
+ )
+
+ with self.assertRaises(RequiredArgument):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="",
+ format_id="f1",
+ )
+
+ def test_export_delta_audit_report(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_config_id(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ config_id="c1",
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_filter_string(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ filter_string="compliance_levels=yniu",
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_ignore_pagination(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ ignore_pagination=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_lean(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ lean=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_notes_details(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ notes_details=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_overrides_details(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ overrides_details=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_result_tags(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ result_tags=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
+
+ def test_export_delta_audit_report_with_all_arguments(self):
+ self.gmp.export_delta_audit_report(
+ report_id="r1",
+ delta_report_id="d1",
+ format_id="f1",
+ config_id="c1",
+ filter_string="compliance_levels=yniu",
+ ignore_pagination=True,
+ lean=True,
+ notes_details=True,
+ overrides_details=True,
+ result_tags=True,
+ )
+
+ self.connection.send.has_been_called_with(
+ b''
+ )
diff --git a/tests/protocols/gmpnext/entities/test_audit_report.py b/tests/protocols/gmpnext/entities/test_audit_report.py
index 35dd4730..31fc02cb 100644
--- a/tests/protocols/gmpnext/entities/test_audit_report.py
+++ b/tests/protocols/gmpnext/entities/test_audit_report.py
@@ -6,6 +6,7 @@
from ...gmpnext import GMPTestCase
from ...gmpnext.entities.audit_report import (
GmpExportAuditReportTestMixin,
+ GmpExportDeltaAuditReportTestMixin,
GmpGetAuditReportLegacyTestMixin,
GmpGetAuditReportTestMixin,
)
@@ -23,3 +24,9 @@ class GmpGetAuditReportLegacyTestCase(
class GmpExportAuditReportTestCase(GmpExportAuditReportTestMixin, GMPTestCase):
pass
+
+
+class GmpExportDeltaAuditReportTestCase(
+ GmpExportDeltaAuditReportTestMixin, GMPTestCase
+):
+ pass