From ad5fdfc7e2babb721d0504c36d94af945ab8229e Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 19 Jun 2026 08:28:17 +0200 Subject: [PATCH 1/2] add: support get_agent_support_bundle GMP command Add the `get_agent_support_bundle` request method, including support for the optional `days` parameter and related tests. --- gvm/protocols/gmp/_gmpnext.py | 23 +++++++ gvm/protocols/gmp/requests/next/_agents.py | 36 ++++++++++ .../agents/test_get_agent_support_bundle.py | 66 +++++++++++++++++++ .../protocols/gmpnext/entities/test_agents.py | 9 +++ uv.lock | 2 +- 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py index bd498816d..49322cdb5 100644 --- a/gvm/protocols/gmp/_gmpnext.py +++ b/gvm/protocols/gmp/_gmpnext.py @@ -306,6 +306,29 @@ def sync_agents(self) -> T: """Trigger agents synchronization from all agent controllers.""" return self._send_request_and_transform_response(Agents.sync_agents()) + def get_agent_support_bundle( + self, + agent_id: EntityID, + days: int | None = None, + ) -> T: + """Request a support bundle for an agent. + + Args: + agent_id: ID of the agent to get the support bundle for. + days: Number of days of logs to include. If None, zero is sent so the + Agent Controller uses its configured default. + + Raises: + RequiredArgument: If agent_id is missing. + ValueError: If days is negative. + """ + return self._send_request_and_transform_response( + Agents.get_agent_support_bundle( + agent_id, + days=days, + ) + ) + def create_credential_store_credential( self, name: str, diff --git a/gvm/protocols/gmp/requests/next/_agents.py b/gvm/protocols/gmp/requests/next/_agents.py index b9fdc4121..4a767bbf6 100644 --- a/gvm/protocols/gmp/requests/next/_agents.py +++ b/gvm/protocols/gmp/requests/next/_agents.py @@ -431,3 +431,39 @@ def modify_agent_control_scan_config( def sync_agents(cls) -> Request: """Trigger agents synchronization from all agent controllers.""" return XmlCommand("sync_agents") + + @classmethod + def get_agent_support_bundle( + cls, + agent_id: EntityID, + *, + days: int | None = None, + ) -> Request: + """Request a support bundle for an agent. + + Args: + agent_id: ID of the agent to get the support bundle for. + days: Number of days of logs to include. If None, zero is sent so the + Agent Controller uses its configured default. + + Raises: + RequiredArgument: If agent_id is missing. + ValueError: If days is negative. + """ + if not agent_id: + raise RequiredArgument( + function=cls.get_agent_support_bundle.__name__, + argument="agent_id", + ) + + if days is None: + days = 0 + + if days < 0: + raise ValueError("days must be greater than or equal to zero") + + cmd = XmlCommand("get_agent_support_bundle") + cmd.set_attribute("agent_uuid", str(agent_id)) + cmd.set_attribute("days", str(days)) + + return cmd diff --git a/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py b/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py new file mode 100644 index 000000000..faf70ef15 --- /dev/null +++ b/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py @@ -0,0 +1,66 @@ +# SPDX-FileCopyrightText: 2026 Greenbone AG +# +# SPDX-License-Identifier: GPL-3.0-or-later + +from gvm.errors import RequiredArgument + + +class GmpGetAgentSupportBundleTestMixin: + def test_get_agent_support_bundle(self): + self.gmp.get_agent_support_bundle( + agent_id="agent-123", + days=7, + ) + + self.connection.send.has_been_called_with( + b'' + ) + + def test_get_agent_support_bundle_without_days_uses_zero(self): + self.gmp.get_agent_support_bundle( + agent_id="agent-123", + ) + + self.connection.send.has_been_called_with( + b'' + ) + + def test_get_agent_support_bundle_with_none_days_uses_zero(self): + self.gmp.get_agent_support_bundle( + agent_id="agent-123", + days=None, + ) + + self.connection.send.has_been_called_with( + b'' + ) + + def test_get_agent_support_bundle_with_zero_days(self): + self.gmp.get_agent_support_bundle( + agent_id="agent-123", + days=0, + ) + + self.connection.send.has_been_called_with( + b'' + ) + + def test_get_agent_support_bundle_without_agent_id(self): + with self.assertRaises(RequiredArgument): + self.gmp.get_agent_support_bundle( + agent_id=None, + days=7, + ) + + with self.assertRaises(RequiredArgument): + self.gmp.get_agent_support_bundle( + agent_id="", + days=7, + ) + + def test_get_agent_support_bundle_with_negative_days(self): + with self.assertRaises(ValueError): + self.gmp.get_agent_support_bundle( + agent_id="agent-123", + days=-1, + ) diff --git a/tests/protocols/gmpnext/entities/test_agents.py b/tests/protocols/gmpnext/entities/test_agents.py index 16d983476..8299e5491 100644 --- a/tests/protocols/gmpnext/entities/test_agents.py +++ b/tests/protocols/gmpnext/entities/test_agents.py @@ -7,6 +7,9 @@ from .agents.test_delete_agents import ( GmpDeleteAgentsTestMixin, ) +from .agents.test_get_agent_support_bundle import ( + GmpGetAgentSupportBundleTestMixin, +) from .agents.test_get_agents import ( GmpGetAgentsTestMixin, ) @@ -39,3 +42,9 @@ class GMPModifyAgentControllerScanConfigTestCase( class GMPSyncAgentsTestCase(GmpSyncAgentsTestMixin, GMPTestCase): pass + + +class GmpGetAgentSupportBundleTestCase( + GmpGetAgentSupportBundleTestMixin, GMPTestCase +): + pass diff --git a/uv.lock b/uv.lock index 8edf42ff5..1589d94e8 100644 --- a/uv.lock +++ b/uv.lock @@ -1267,7 +1267,7 @@ wheels = [ [[package]] name = "python-gvm" -version = "27.3.2.dev1" +version = "27.4.1.dev1" source = { editable = "." } dependencies = [ { name = "httpx", extra = ["http2"] }, From 4376d90fe5edbde14a7ec297d0be22381fe7bf87 Mon Sep 17 00:00:00 2001 From: ozgen Date: Fri, 19 Jun 2026 08:51:31 +0200 Subject: [PATCH 2/2] change: use 0 instead of None for support bundle days Remove `None` support for the `days` parameter and use `0` as the default value. --- gvm/protocols/gmp/_gmpnext.py | 2 +- gvm/protocols/gmp/requests/next/_agents.py | 5 +---- .../entities/agents/test_get_agent_support_bundle.py | 10 ---------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/gvm/protocols/gmp/_gmpnext.py b/gvm/protocols/gmp/_gmpnext.py index 49322cdb5..dc271e12d 100644 --- a/gvm/protocols/gmp/_gmpnext.py +++ b/gvm/protocols/gmp/_gmpnext.py @@ -309,7 +309,7 @@ def sync_agents(self) -> T: def get_agent_support_bundle( self, agent_id: EntityID, - days: int | None = None, + days: int = 0, ) -> T: """Request a support bundle for an agent. diff --git a/gvm/protocols/gmp/requests/next/_agents.py b/gvm/protocols/gmp/requests/next/_agents.py index 4a767bbf6..361caef6e 100644 --- a/gvm/protocols/gmp/requests/next/_agents.py +++ b/gvm/protocols/gmp/requests/next/_agents.py @@ -437,7 +437,7 @@ def get_agent_support_bundle( cls, agent_id: EntityID, *, - days: int | None = None, + days: int = 0, ) -> Request: """Request a support bundle for an agent. @@ -456,9 +456,6 @@ def get_agent_support_bundle( argument="agent_id", ) - if days is None: - days = 0 - if days < 0: raise ValueError("days must be greater than or equal to zero") diff --git a/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py b/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py index faf70ef15..359a20fc1 100644 --- a/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py +++ b/tests/protocols/gmpnext/entities/agents/test_get_agent_support_bundle.py @@ -25,16 +25,6 @@ def test_get_agent_support_bundle_without_days_uses_zero(self): b'' ) - def test_get_agent_support_bundle_with_none_days_uses_zero(self): - self.gmp.get_agent_support_bundle( - agent_id="agent-123", - days=None, - ) - - self.connection.send.has_been_called_with( - b'' - ) - def test_get_agent_support_bundle_with_zero_days(self): self.gmp.get_agent_support_bundle( agent_id="agent-123",