diff --git a/tdp/core/deployment/executor.py b/tdp/core/deployment/executor.py index 1a49f171..1424e49c 100644 --- a/tdp/core/deployment/executor.py +++ b/tdp/core/deployment/executor.py @@ -3,12 +3,12 @@ import io import logging -import shutil import subprocess from collections.abc import Iterable from typing import Optional from tdp.core.models import OperationStateEnum +from tdp.utils import ExecutableNotFoundError, resolve_executable logger = logging.getLogger(__name__) @@ -78,11 +78,18 @@ def execute( Returns: A tuple with the state of the command and the output of the command in UTF-8. """ - # Check if ansible is available - ansible_path = shutil.which("ansible-playbook") - if ansible_path is None: - logger.error("'ansible-playbook' not found in PATH") - return OperationStateEnum.FAILURE, b"" + ansible_playbook_command = "ansible-playbook" + if self._dry: + # In dry mode, we don't want to execute the ansible-playbook command + ansible_path = ansible_playbook_command + else: + # Check if the ansible-playbook command is available in PATH + try: + ansible_path = resolve_executable(ansible_playbook_command) + except ExecutableNotFoundError: + logs = f"'{ansible_playbook_command}' not found in PATH" + logger.error(logs) + return OperationStateEnum.FAILURE, logs.encode("utf-8") # Build command command = [ansible_path] command += [str(playbook)] diff --git a/tdp/test_utils.py b/tdp/test_utils.py new file mode 100644 index 00000000..3fd81ea2 --- /dev/null +++ b/tdp/test_utils.py @@ -0,0 +1,19 @@ +# Copyright 2022 TOSIT.IO +# SPDX-License-Identifier: Apache-2.0 + +import shutil + +import pytest + +from tdp.utils import ExecutableNotFoundError, resolve_executable + + +class TestResolveExecutable: + def test_resolve_executable_as_path(self): + # Test when as_path is True + assert resolve_executable("python") == shutil.which("python") + + def test_resolve_executable_not_found(self): + # Test when executable is not found in PATH + with pytest.raises(ExecutableNotFoundError): + resolve_executable("nonexistent_executable") diff --git a/tdp/utils.py b/tdp/utils.py new file mode 100644 index 00000000..a60b0568 --- /dev/null +++ b/tdp/utils.py @@ -0,0 +1,29 @@ +# Copyright 2022 TOSIT.IO +# SPDX-License-Identifier: Apache-2.0 + +import shutil + + +class ExecutableNotFoundError(Exception): + """Raised when an executable is not found in PATH.""" + + pass + + +def resolve_executable(executable: str, /) -> str: + """Resolve an executable to its full path. + + Args: + executable: Name of the executable to resolve. + + Returns: + Path of the executable. + + Raises: + ExecutableNotFoundError: If the executable is not found in PATH and as_path + is True. + """ + executable_path = shutil.which(executable) + if executable_path is None: + raise ExecutableNotFoundError(f"'{executable}' not found in PATH") + return executable_path