From 62455b8a6fd843b90aab58ab02c5e620509d9068 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 12 May 2024 16:07:23 -0400 Subject: [PATCH] fix: use proper xpaths, convert types --- src/gvm_sync_targets/cli/__init__.py | 32 ++++++++++++++++++---------- src/gvm_sync_targets/util.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 src/gvm_sync_targets/util.py diff --git a/src/gvm_sync_targets/cli/__init__.py b/src/gvm_sync_targets/cli/__init__.py index 7ae0e80..b13a90f 100644 --- a/src/gvm_sync_targets/cli/__init__.py +++ b/src/gvm_sync_targets/cli/__init__.py @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2024-present linuxdaemon # # SPDX-License-Identifier: MIT -from typing import TYPE_CHECKING, Optional, TextIO +from typing import TYPE_CHECKING, TextIO, cast import click from gvm.connections import UnixSocketConnection @@ -9,6 +9,7 @@ from gvm.transforms import EtreeCheckCommandTransform from gvm_sync_targets import __version__ +from gvm_sync_targets.util import to_str if TYPE_CHECKING: from lxml.etree import ElementBase @@ -37,27 +38,36 @@ def gvm_sync_targets(username: str, password: str, hosts_file: TextIO) -> None: if target is None: # Create target new_target = gmp.create_target("All Hosts") - elif target.xpath("in_use/text()") == ["1"]: - new_target = gmp.clone_target(target.attrib["id"]) + elif target.xpath("sum(in_use/text()) > 0"): + new_target = gmp.clone_target(to_str(target.attrib["id"])) else: new_target = target + new_target_id: str = to_str(new_target.attrib["id"]) # Set hosts # gmp.modify_target(new_target.attrib['id'], hosts=hosts) # Replace old target in tasks if target is not None and target is not new_target: - tasks = gmp.get_tasks().findall("task") - if tasks is None: - tasks = [] + old_target_id = to_str(target.attrib["id"]) + tasks = cast("ElementBase", gmp.get_tasks()).findall( + f"task[target='{old_target_id}']" + ) for task in tasks: - print(task) - print(task.attrib) - for child in task: - print(child) - print(child.attrib) + gmp.modify_task( + to_str(task.attrib["id"]), target_id=new_target_id + ) # Ensure old target is unused + old_target: "ElementBase" = gmp.get_target(old_target_id) + old_name = old_target.xpath("name/text()[1]") + if old_target.xpath("sum(in_use/text()) > 0"): + msg = "target is still in use" + raise ValueError(msg) + # Delete old target + gmp.delete_target(old_target_id, ultimate=True) + # Rename new target + gmp.modify_target(new_target_id, name=old_name) diff --git a/src/gvm_sync_targets/util.py b/src/gvm_sync_targets/util.py new file mode 100644 index 0000000..6af41be --- /dev/null +++ b/src/gvm_sync_targets/util.py @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2024-present linuxdaemon +# +# SPDX-License-Identifier: MIT +from typing import Union + + +def to_str(text: Union[str, bytes, bytearray, memoryview]) -> str: + """Convert bytes, bytearray, memoryview, or str to str. + + Args: + text: Input value + + Returns: + decoded output + + Examples: + >>> to_str("aaa") + 'aaa' + >>> to_str(b'bb') + 'bb' + >>> to_str(memoryview(b'bb')) + 'bb' + >>> to_str(bytearray(b'cc')) + 'cc' + """ + if isinstance(text, (bytes, bytearray)): + return text.decode() + + if isinstance(text, memoryview): + return to_str(text.tobytes()) + + return text