Skip to content

Commit ad5fdfc

Browse files
committed
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.
1 parent 7b693da commit ad5fdfc

5 files changed

Lines changed: 135 additions & 1 deletion

File tree

gvm/protocols/gmp/_gmpnext.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,29 @@ def sync_agents(self) -> T:
306306
"""Trigger agents synchronization from all agent controllers."""
307307
return self._send_request_and_transform_response(Agents.sync_agents())
308308

309+
def get_agent_support_bundle(
310+
self,
311+
agent_id: EntityID,
312+
days: int | None = None,
313+
) -> T:
314+
"""Request a support bundle for an agent.
315+
316+
Args:
317+
agent_id: ID of the agent to get the support bundle for.
318+
days: Number of days of logs to include. If None, zero is sent so the
319+
Agent Controller uses its configured default.
320+
321+
Raises:
322+
RequiredArgument: If agent_id is missing.
323+
ValueError: If days is negative.
324+
"""
325+
return self._send_request_and_transform_response(
326+
Agents.get_agent_support_bundle(
327+
agent_id,
328+
days=days,
329+
)
330+
)
331+
309332
def create_credential_store_credential(
310333
self,
311334
name: str,

gvm/protocols/gmp/requests/next/_agents.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,39 @@ def modify_agent_control_scan_config(
431431
def sync_agents(cls) -> Request:
432432
"""Trigger agents synchronization from all agent controllers."""
433433
return XmlCommand("sync_agents")
434+
435+
@classmethod
436+
def get_agent_support_bundle(
437+
cls,
438+
agent_id: EntityID,
439+
*,
440+
days: int | None = None,
441+
) -> Request:
442+
"""Request a support bundle for an agent.
443+
444+
Args:
445+
agent_id: ID of the agent to get the support bundle for.
446+
days: Number of days of logs to include. If None, zero is sent so the
447+
Agent Controller uses its configured default.
448+
449+
Raises:
450+
RequiredArgument: If agent_id is missing.
451+
ValueError: If days is negative.
452+
"""
453+
if not agent_id:
454+
raise RequiredArgument(
455+
function=cls.get_agent_support_bundle.__name__,
456+
argument="agent_id",
457+
)
458+
459+
if days is None:
460+
days = 0
461+
462+
if days < 0:
463+
raise ValueError("days must be greater than or equal to zero")
464+
465+
cmd = XmlCommand("get_agent_support_bundle")
466+
cmd.set_attribute("agent_uuid", str(agent_id))
467+
cmd.set_attribute("days", str(days))
468+
469+
return cmd
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SPDX-FileCopyrightText: 2026 Greenbone AG
2+
#
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
from gvm.errors import RequiredArgument
6+
7+
8+
class GmpGetAgentSupportBundleTestMixin:
9+
def test_get_agent_support_bundle(self):
10+
self.gmp.get_agent_support_bundle(
11+
agent_id="agent-123",
12+
days=7,
13+
)
14+
15+
self.connection.send.has_been_called_with(
16+
b'<get_agent_support_bundle agent_uuid="agent-123" days="7"/>'
17+
)
18+
19+
def test_get_agent_support_bundle_without_days_uses_zero(self):
20+
self.gmp.get_agent_support_bundle(
21+
agent_id="agent-123",
22+
)
23+
24+
self.connection.send.has_been_called_with(
25+
b'<get_agent_support_bundle agent_uuid="agent-123" days="0"/>'
26+
)
27+
28+
def test_get_agent_support_bundle_with_none_days_uses_zero(self):
29+
self.gmp.get_agent_support_bundle(
30+
agent_id="agent-123",
31+
days=None,
32+
)
33+
34+
self.connection.send.has_been_called_with(
35+
b'<get_agent_support_bundle agent_uuid="agent-123" days="0"/>'
36+
)
37+
38+
def test_get_agent_support_bundle_with_zero_days(self):
39+
self.gmp.get_agent_support_bundle(
40+
agent_id="agent-123",
41+
days=0,
42+
)
43+
44+
self.connection.send.has_been_called_with(
45+
b'<get_agent_support_bundle agent_uuid="agent-123" days="0"/>'
46+
)
47+
48+
def test_get_agent_support_bundle_without_agent_id(self):
49+
with self.assertRaises(RequiredArgument):
50+
self.gmp.get_agent_support_bundle(
51+
agent_id=None,
52+
days=7,
53+
)
54+
55+
with self.assertRaises(RequiredArgument):
56+
self.gmp.get_agent_support_bundle(
57+
agent_id="",
58+
days=7,
59+
)
60+
61+
def test_get_agent_support_bundle_with_negative_days(self):
62+
with self.assertRaises(ValueError):
63+
self.gmp.get_agent_support_bundle(
64+
agent_id="agent-123",
65+
days=-1,
66+
)

tests/protocols/gmpnext/entities/test_agents.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
from .agents.test_delete_agents import (
88
GmpDeleteAgentsTestMixin,
99
)
10+
from .agents.test_get_agent_support_bundle import (
11+
GmpGetAgentSupportBundleTestMixin,
12+
)
1013
from .agents.test_get_agents import (
1114
GmpGetAgentsTestMixin,
1215
)
@@ -39,3 +42,9 @@ class GMPModifyAgentControllerScanConfigTestCase(
3942

4043
class GMPSyncAgentsTestCase(GmpSyncAgentsTestMixin, GMPTestCase):
4144
pass
45+
46+
47+
class GmpGetAgentSupportBundleTestCase(
48+
GmpGetAgentSupportBundleTestMixin, GMPTestCase
49+
):
50+
pass

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)