Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions gvm/protocols/gmp/_gmpnext.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
AgentInstallerInstructions,
Agents,
AliveTest,
AuditReport,
Credentials,
CredentialStoreCredentialType,
CredentialStores,
Expand All @@ -37,6 +38,7 @@
)
from .requests.v224 import AliveTest as AliveTestV224
from .requests.v224 import HostsOrdering
from .requests.v226 import ReportFormatType


class GMPNext(GMPv227[T]):
Expand Down Expand Up @@ -1671,3 +1673,58 @@ def get_scan_report(
filter_id=filter_id,
)
)

def get_audit_report( # type: ignore[override]
self,
audit_report_id: EntityID,
*,
filter_string: str | None = None,
filter_id: str | None = None,
) -> T:
"""Request a structured summary of a single audit report.

Args:
audit_report_id: UUID of an existing audit report.
filter_string: Filter term to apply to the report results.
filter_id: UUID of a saved filter to apply to the report results.

Returns:
A request for the get_audit_report GMP command.

Raises:
RequiredArgument: If audit_report_id is not provided.
"""
return self._send_request_and_transform_response(
AuditReport.get_audit_report(
audit_report_id=audit_report_id,
filter_string=filter_string,
filter_id=filter_id,
)
)

def get_audit_report_legacy(
self,
report_id: EntityID,
*,
filter_string: str | None = None,
filter_id: str | None = None,
delta_report_id: EntityID | None = None,
report_format_id: str | ReportFormatType | None = None,
ignore_pagination: bool | None = None,
details: bool | None = True,
) -> T:
"""Request an audit report using the legacy command.

Deprecated:
Use ``get_audit_report`` instead. This method will be removed
in the next major release.
"""
return super().get_audit_report(
report_id,
filter_string=filter_string,
filter_id=filter_id,
delta_report_id=delta_report_id,
report_format_id=report_format_id,
ignore_pagination=ignore_pagination,
details=details,
)
2 changes: 2 additions & 0 deletions gvm/protocols/gmp/requests/next/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
AgentInstallerInstructions,
)
from gvm.protocols.gmp.requests.next._agents import Agents
from gvm.protocols.gmp.requests.next._audit_report import AuditReport
from gvm.protocols.gmp.requests.next._credential_stores import CredentialStores
from gvm.protocols.gmp.requests.next._credentials import (
Credentials,
Expand Down Expand Up @@ -131,6 +132,7 @@
"AlertMethod",
"Alerts",
"AliveTest",
"AuditReport",
"AuditReports",
"Audits",
"Authentication",
Expand Down
39 changes: 39 additions & 0 deletions gvm/protocols/gmp/requests/next/_audit_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from gvm.errors import RequiredArgument
from gvm.protocols.core import Request
from gvm.protocols.gmp.requests import EntityID
from gvm.xml import XmlCommand


class AuditReport:
@classmethod
def get_audit_report(
cls,
audit_report_id: EntityID,
*,
filter_string: str | None = None,
filter_id: str | None = None,
) -> Request:
"""Request a structured summary of a single audit report.

Args:
audit_report_id: UUID of an existing audit report.
filter_string: Filter term to apply to the report results.
filter_id: UUID of a saved filter to apply to the report results.

Returns:
A request for the get_audit_report GMP command.

Raises:
RequiredArgument: If audit_report_id is not provided.
"""
if not audit_report_id:
raise RequiredArgument(
function=cls.get_audit_report.__name__,
argument="audit_report_id",
)

cmd = XmlCommand("get_audit_report")
cmd.set_attribute("audit_report_id", str(audit_report_id))
cmd.add_filter(filter_string, filter_id)

return cmd
16 changes: 16 additions & 0 deletions tests/protocols/gmpnext/entities/audit_report/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from .test_get_audit_report import (
GmpGetAuditReportTestMixin,
)
from .test_get_audit_report_legacy import (
GmpGetAuditReportLegacyTestMixin,
)

__all__ = (
"GmpGetAuditReportLegacyTestMixin",
"GmpGetAuditReportTestMixin",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from gvm.errors import RequiredArgument


class GmpGetAuditReportTestMixin:
def test_get_audit_report_without_id(self):
with self.assertRaises(RequiredArgument):
self.gmp.get_audit_report(None)

with self.assertRaises(RequiredArgument):
self.gmp.get_audit_report("")

def test_get_audit_report_with_id(self):
self.gmp.get_audit_report(audit_report_id="r1")

self.connection.send.has_been_called_with(
b'<get_audit_report audit_report_id="r1"/>'
)

def test_get_audit_report_with_filter_string(self):
self.gmp.get_audit_report(
audit_report_id="r1",
filter_string="name=foo",
)

self.connection.send.has_been_called_with(
b'<get_audit_report audit_report_id="r1" filter="name=foo"/>'
)

def test_get_audit_report_with_filter_id(self):
self.gmp.get_audit_report(
audit_report_id="r1",
filter_id="f1",
)

self.connection.send.has_been_called_with(
b'<get_audit_report audit_report_id="r1" filt_id="f1"/>'
)

def test_get_audit_report_with_filter_string_and_filter_id(self):
self.gmp.get_audit_report(
audit_report_id="r1",
filter_string="name=foo",
filter_id="f1",
)

self.connection.send.has_been_called_with(
b'<get_audit_report audit_report_id="r1" '
b'filter="name=foo" filt_id="f1"/>'
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from gvm.errors import RequiredArgument
from gvm.protocols.gmp.requests.v226 import ReportFormatType


class GmpGetAuditReportLegacyTestMixin:
def test_get_audit_report_legacy_without_id(self):
with self.assertRaises(RequiredArgument):
self.gmp.get_audit_report_legacy(None)

with self.assertRaises(RequiredArgument):
self.gmp.get_audit_report_legacy("")

def test_get_audit_report_legacy_with_filter_string(self):
self.gmp.get_audit_report_legacy(
report_id="r1", filter_string="name=foo"
)

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" filter="name=foo" details="1"/>'
)

def test_get_audit_report_legacy_with_filter_id(self):
self.gmp.get_audit_report_legacy(report_id="r1", filter_id="f1")

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" filt_id="f1" details="1"/>'
)

def test_get_audit_report_legacy_with_report_format_id(self):
self.gmp.get_audit_report_legacy(report_id="r1", report_format_id="bar")

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" format_id="bar" details="1"/>'
)

def test_get_audit_report_legacy_with_report_format_type(self):
self.gmp.get_audit_report_legacy(
report_id="r1", report_format_id=ReportFormatType.TXT
)
report_format_id = ReportFormatType.from_string("txt").value

self.connection.send.has_been_called_with(
'<get_reports report_id="r1" usage_type="audit" format_id='
f'"{report_format_id}" details="1"/>'.encode()
)

def test_get_audit_report_legacy_with_delta_report_id(self):
self.gmp.get_audit_report_legacy(report_id="r1", delta_report_id="r2")

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" delta_report_id="r2" details="1"/>'
)

def test_get_audit_report_legacy_with_ignore_pagination(self):
self.gmp.get_audit_report_legacy(report_id="r1", ignore_pagination=True)

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" ignore_pagination="1" details="1"/>'
)

self.gmp.get_audit_report_legacy(
report_id="r1", ignore_pagination=False
)

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" ignore_pagination="0" details="1"/>'
)

def test_get_audit_report_legacy_with_details(self):
self.gmp.get_audit_report_legacy(report_id="r1", details=True)

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" details="1"/>'
)

self.gmp.get_audit_report_legacy(report_id="r1", details=False)

self.connection.send.has_been_called_with(
b'<get_reports report_id="r1" usage_type="audit" details="0"/>'
)
20 changes: 20 additions & 0 deletions tests/protocols/gmpnext/entities/test_audit_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from ...gmpnext import GMPTestCase
from ...gmpnext.entities.audit_report import (
GmpGetAuditReportLegacyTestMixin,
GmpGetAuditReportTestMixin,
)


class GmpGetAuditReportTestCase(GmpGetAuditReportTestMixin, GMPTestCase):
pass


class GmpGetAuditReportLegacyTestCase(
GmpGetAuditReportLegacyTestMixin, GMPTestCase
):
pass
Loading