diff --git a/Dockerfile b/Dockerfile index c6e2fa64..cdc2d65f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,8 +34,9 @@ RUN mkdir -p $BIN_DIR \ && mkdir -p $DATA_DIR \ && mkdir -p $DATA_DIR/logs -COPY gunicorn.conf.py pyproject.toml uv.lock README.md $APP_DIR/ +COPY entrypoint.sh entrypoint.py pyproject.toml uv.lock README.md $APP_DIR/ COPY webhook_server $APP_DIR/webhook_server/ +RUN chmod +x $APP_DIR/entrypoint.sh RUN usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USERNAME \ && chown -R $USERNAME:$USERNAME $HOME_DIR @@ -66,4 +67,4 @@ RUN uv sync HEALTHCHECK CMD curl --fail http://127.0.0.1:5000/webhook_server/healthcheck || exit 1 -ENTRYPOINT ["uv", "run", "gunicorn", "webhook_server.app:FASTAPI_APP", "-c", "./gunicorn.conf.py"] +ENTRYPOINT ["./entrypoint.sh"] diff --git a/entrypoint.py b/entrypoint.py new file mode 100644 index 00000000..8e080206 --- /dev/null +++ b/entrypoint.py @@ -0,0 +1,13 @@ +from webhook_server.libs.config import Config +from webhook_server.utils.github_repository_and_webhook_settings import repository_and_webhook_settings + +_config = Config() +_root_config = _config.root_data +_ip_bind = _root_config.get("ip-bind", "0.0.0.0") +_port = _root_config.get("port", 5000) +_max_workers = _root_config.get("max-workers", 10) +_webhook_secret = _root_config.get("webhook-secret") + +if __name__ == "__main__": + repository_and_webhook_settings(webhook_secret=_webhook_secret) + print(f"uv run uvicorn webhook_server.app:FASTAPI_APP --host {_ip_bind} --port {_port} --workers {_max_workers}") diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..76081a23 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Generate the uvicorn command from Python +cmd=$(uv run ./entrypoint.py) +echo "${cmd}" + +# Replace the shell with the server process (PID 1 inside container) +exec ${cmd} diff --git a/gunicorn.conf.py b/gunicorn.conf.py deleted file mode 100644 index b5ebc88e..00000000 --- a/gunicorn.conf.py +++ /dev/null @@ -1,14 +0,0 @@ -from webhook_server.libs.config import Config - -_config = Config() -_root_config = _config.root_data -_ip_bind = _root_config.get("ip-bind", "0.0.0.0") -_port = _root_config.get("port", 5000) -_max_workers = _root_config.get("max-workers", 10) - -bind = f"{_ip_bind}:{_port}" -worker_class = "uvicorn.workers.UvicornWorker" -workers = int(_max_workers) -on_starting = "webhook_server.app.on_starting" -accesslog = "-" -timeout = 60 * 30 # some operation can take long time. diff --git a/pyproject.toml b/pyproject.toml index 398e3d29..a4e07c7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,9 +65,7 @@ dependencies = [ "string-color>=1.2.3", "timeout-sampler>=0.0.46", "uvicorn>=0.31.0", - "uvicorn-worker>=0.3.0", - "gunicorn>=23.0.0", - "httpx>=0.28.1" + "httpx>=0.28.1", ] [[project.authors]] diff --git a/uv.lock b/uv.lock index 280f9707..dc8abfef 100644 --- a/uv.lock +++ b/uv.lock @@ -348,7 +348,6 @@ dependencies = [ { name = "colorama" }, { name = "colorlog" }, { name = "fastapi" }, - { name = "gunicorn" }, { name = "httpx" }, { name = "pygithub" }, { name = "pyhelper-utils" }, @@ -363,7 +362,6 @@ dependencies = [ { name = "string-color" }, { name = "timeout-sampler" }, { name = "uvicorn" }, - { name = "uvicorn-worker" }, ] [package.dev-dependencies] @@ -378,7 +376,6 @@ requires-dist = [ { name = "colorama", specifier = ">=0.4.6" }, { name = "colorlog", specifier = ">=6.8.2" }, { name = "fastapi", specifier = ">=0.115.0" }, - { name = "gunicorn", specifier = ">=23.0.0" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "pygithub", specifier = ">=2.4.0" }, { name = "pyhelper-utils", specifier = ">=0.0.42" }, @@ -393,7 +390,6 @@ requires-dist = [ { name = "string-color", specifier = ">=1.2.3" }, { name = "timeout-sampler", specifier = ">=0.0.46" }, { name = "uvicorn", specifier = ">=0.31.0" }, - { name = "uvicorn-worker", specifier = ">=0.3.0" }, ] [package.metadata.requires-dev] @@ -402,18 +398,6 @@ dev = [ { name = "ipython", specifier = ">=8.12.3" }, ] -[[package]] -name = "gunicorn" -version = "23.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/34/72/9614c465dc206155d93eff0ca20d42e1e35afc533971379482de953521a4/gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec", size = 375031, upload-time = "2024-08-10T20:25:27.378Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029, upload-time = "2024-08-10T20:25:24.996Z" }, -] - [[package]] name = "h11" version = "0.16.0" @@ -1089,19 +1073,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, ] -[[package]] -name = "uvicorn-worker" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gunicorn" }, - { name = "uvicorn" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/37/c0/b5df8c9a31b0516a47703a669902b362ca1e569fed4f3daa1d4299b28be0/uvicorn_worker-0.3.0.tar.gz", hash = "sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b", size = 9181, upload-time = "2024-12-26T12:13:07.591Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl", hash = "sha256:ef0fe8aad27b0290a9e602a256b03f5a5da3a9e5f942414ca587b645ec77dd52", size = 5346, upload-time = "2024-12-26T12:13:06.026Z" }, -] - [[package]] name = "wcwidth" version = "0.2.13" diff --git a/webhook_server/app.py b/webhook_server/app.py index d01ed1bc..70a876ec 100644 --- a/webhook_server/app.py +++ b/webhook_server/app.py @@ -1,9 +1,11 @@ import hashlib import hmac import ipaddress +import logging import os import sys -from typing import Any +from contextlib import asynccontextmanager +from typing import Any, AsyncGenerator import requests import urllib3 @@ -20,11 +22,10 @@ from webhook_server.libs.config import Config from webhook_server.libs.exceptions import NoPullRequestError, RepositoryNotFoundError from webhook_server.libs.github_api import GithubWebhook -from webhook_server.utils.github_repository_and_webhook_settings import repository_and_webhook_settings from webhook_server.utils.helpers import get_logger_with_params ALLOWED_IPS: tuple[ipaddress._BaseNetwork, ...] = () -FASTAPI_APP: FastAPI = FastAPI(title="webhook-server") + APP_URL_ROOT_PATH: str = "/webhook_server" urllib3.disable_warnings() @@ -82,17 +83,16 @@ async def gate_by_allowlist_ips(request: Request) -> None: ) -def on_starting(server: Any) -> None: +@asynccontextmanager +async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: logger = get_logger_with_params(name="startup") - logger.info("Application starting up...") + try: + logger.info("Application starting up...") config = Config(logger=logger) root_config = config.root_data - webhook_secret = root_config.get("webhook-secret") verify_github_ips = root_config.get("verify-github-ips") verify_cloudflare_ips = root_config.get("verify-cloudflare-ips") - - repository_and_webhook_settings(webhook_secret=webhook_secret) logger.info("Repository and webhook settings initialized successfully.") global ALLOWED_IPS @@ -110,11 +110,15 @@ def on_starting(server: Any) -> None: logger.info(f"IP allowlist initialized successfully. {ALLOWED_IPS}") + yield except Exception as ex: - logger.exception(f"FATAL: Error during startup initialization: {ex}") + logger.error(f"Application failed to start up: {ex}") raise +FASTAPI_APP: FastAPI = FastAPI(title="webhook-server", lifespan=lifespan) + + @FASTAPI_APP.get(f"{APP_URL_ROOT_PATH}/healthcheck") def healthcheck() -> dict[str, Any]: return {"status": requests.codes.ok, "message": "Alive"} @@ -148,28 +152,28 @@ async def process_webhook(request: Request, background_tasks: BackgroundTasks) - logger = get_logger_with_params(name=logger_name, repository_name=hook_data["repository"]["name"]) - try: - api: GithubWebhook = GithubWebhook(hook_data=hook_data, headers=request.headers, logger=logger) + async def process_with_error_handling(_api: GithubWebhook, _logger: logging.Logger) -> None: + try: + await _api.process() - async def process_with_error_handling() -> None: - try: - await api.process() + except NoPullRequestError: + return - except NoPullRequestError: - return + except Exception as e: + _logger.exception(f"{log_context} Error in background task: {e}") - except Exception as e: - logger.exception(f"{log_context} Error in background task: {e}") + try: + api: GithubWebhook = GithubWebhook(hook_data=hook_data, headers=request.headers, logger=logger) - background_tasks.add_task(process_with_error_handling) - return {"status": requests.codes.ok, "message": "process success", "log_prefix": delivery_headers} + background_tasks.add_task(process_with_error_handling, _api=api, _logger=logger) + return {"status": requests.codes.ok, "message": "ok", "delivery headers": delivery_headers} except RepositoryNotFoundError as e: - logger.error(f"{log_context} Configuration/Repository error: {e}") + logger.exception(f"{log_context} Configuration/Repository error: {e}") raise HTTPException(status_code=404, detail=str(e)) except ConnectionError as e: - logger.error(f"{log_context} API connection error: {e}") + logger.exception(f"{log_context} API connection error: {e}") raise HTTPException(status_code=503, detail=f"API Connection Error: {e}") except NoPullRequestError as e: diff --git a/webhook_server/utils/github_repository_and_webhook_settings.py b/webhook_server/utils/github_repository_and_webhook_settings.py index e05d4a17..5f1d0086 100644 --- a/webhook_server/utils/github_repository_and_webhook_settings.py +++ b/webhook_server/utils/github_repository_and_webhook_settings.py @@ -11,22 +11,22 @@ from webhook_server.utils.helpers import get_api_with_highest_rate_limit, get_logger_with_params from webhook_server.utils.webhook import create_webhook +LOGGER = get_logger_with_params(name="repository-and-webhook-settings") + def get_repository_api(repository: str) -> tuple[str, github.Github | None, str]: - config = Config(repository=repository) + config = Config(repository=repository, logger=LOGGER) github_api, _, api_user = get_api_with_highest_rate_limit(config=config, repository_name=repository) return repository, github_api, api_user def repository_and_webhook_settings(webhook_secret: str | None = None) -> None: - logger = get_logger_with_params(name="github-repository-and-webhook-settings") - - config = Config(logger=logger) + config = Config(logger=LOGGER) apis_dict: dict[str, dict[str, Any]] = {} apis: list = [] with ThreadPoolExecutor() as executor: - for repo, data in config.root_data["repositories"].items(): + for repo, _ in config.root_data["repositories"].items(): apis.append( executor.submit( get_repository_api, @@ -38,7 +38,7 @@ def repository_and_webhook_settings(webhook_secret: str | None = None) -> None: repository, github_api, api_user = result.result() apis_dict[repository] = {"api": github_api, "user": api_user} - logger.debug(f"Repositories APIs: {apis_dict}") + LOGGER.debug(f"Repositories APIs: {apis_dict}") set_repositories_settings(config=config, apis_dict=apis_dict) set_all_in_progress_check_runs_to_queued(repo_config=config, apis_dict=apis_dict) diff --git a/webhook_server/utils/github_repository_settings.py b/webhook_server/utils/github_repository_settings.py index 5a0a9359..df72694c 100644 --- a/webhook_server/utils/github_repository_settings.py +++ b/webhook_server/utils/github_repository_settings.py @@ -29,6 +29,7 @@ from webhook_server.utils.helpers import ( get_future_results, get_logger_with_params, + run_command, ) DEFAULT_BRANCH_PROTECTION = { @@ -40,13 +41,14 @@ "required_conversation_resolution": True, } +LOGGER = get_logger_with_params(name="github-repository-settings") + def _get_github_repo_api(github_api: github.Github, repository: int | str) -> Repository | None: - logger = get_logger_with_params(name="github-repository-settings") try: return github_api.get_repo(repository) except UnknownObjectException: - logger.error(f"Failed to get GitHub API for repository {repository}") + LOGGER.error(f"Failed to get GitHub API for repository {repository}") return None @@ -67,9 +69,7 @@ def set_branch_protection( required_conversation_resolution: bool, api_user: str, ) -> bool: - logger = get_logger_with_params(name="github-repository-settings") - - logger.info( + LOGGER.info( f"[API user {api_user}] - Set branch {branch} setting for {repository.name}. enabled checks: {required_status_checks}" ) branch.edit_protection( @@ -89,16 +89,14 @@ def set_branch_protection( def set_repository_settings(repository: Repository, api_user: str) -> None: - logger = get_logger_with_params(name="github-repository-settings") - - logger.info(f"[API user {api_user}] - Set repository {repository.name} settings") + LOGGER.info(f"[API user {api_user}] - Set repository {repository.name} settings") repository.edit(delete_branch_on_merge=True, allow_auto_merge=True, allow_update_branch=True) if repository.private: - logger.warning(f"{repository.name}: Repository is private, skipping setting security settings") + LOGGER.warning(f"{repository.name}: Repository is private, skipping setting security settings") return - logger.info(f"[API user {api_user}] - Set repository {repository.name} security settings") + LOGGER.info(f"[API user {api_user}] - Set repository {repository.name} security settings") repository._requester.requestJsonAndCheck( "PATCH", f"{repository.url}/code-scanning/default-setup", @@ -163,9 +161,7 @@ def get_user_configures_status_checks(status_checks: dict[str, Any]) -> tuple[li def set_repository_labels(repository: Repository, api_user: str) -> str: - logger = get_logger_with_params(name="github-repository-settings") - - logger.info(f"[API user {api_user}] - Set repository {repository.name} labels") + LOGGER.info(f"[API user {api_user}] - Set repository {repository.name} labels") repository_labels: dict[str, dict[str, Any]] = {} for label in repository.get_labels(): repository_labels[label.name.lower()] = { @@ -180,10 +176,10 @@ def set_repository_labels(repository: Repository, api_user: str) -> str: if repository_labels[label_lower]["color"] == color: continue else: - logger.debug(f"{repository.name}: Edit repository label {label} with color {color}") + LOGGER.debug(f"{repository.name}: Edit repository label {label} with color {color}") repo_label.edit(name=repo_label.name, color=color) else: - logger.debug(f"{repository.name}: Add repository label {label} with color {color}") + LOGGER.debug(f"{repository.name}: Add repository label {label} with color {color}") repository.create_label(name=label, color=color) return f"[API user {api_user}] - {repository}: Setting repository labels is done" @@ -197,22 +193,22 @@ def get_repo_branch_protection_rules(config: Config) -> dict[str, Any]: def set_repositories_settings(config: Config, apis_dict: dict[str, dict[str, Any]]) -> None: - logger = get_logger_with_params(name="github-repository-settings") - - logger.info("Processing repositories") + LOGGER.info("Processing repositories") config_data = config.root_data docker: dict[str, str] | None = config_data.get("docker") if docker: - logger.info("Login in to docker.io") + LOGGER.info("Login in to docker.io") docker_username: str = docker["username"] docker_password: str = docker["password"] - os.system(f"podman login -u {docker_username} -p {docker_password} docker.io") + run_command( + log_prefix="", command=f"podman login -u {docker_username} -p {docker_password} docker.io", check=True + ) futures = [] with ThreadPoolExecutor() as executor: for repo, data in config_data["repositories"].items(): - config = Config(repository=repo, logger=logger) + config = Config(repository=repo, logger=LOGGER) branch_protection = get_repo_branch_protection_rules(config=config) futures.append( executor.submit( @@ -237,20 +233,18 @@ def set_repository( branch_protection: dict[str, Any], config: Config, ) -> tuple[bool, str, Callable]: - logger = get_logger_with_params(name="github-repository-settings") - full_repository_name: str = data["name"] - logger.info(f"Processing repository {full_repository_name}") + LOGGER.info(f"Processing repository {full_repository_name}") protected_branches: dict[str, Any] = config.get_value(value="protected-branches", return_on_none={}) github_api = apis_dict[repository_name].get("api") api_user = apis_dict[repository_name].get("user", "") if not github_api: - return False, f"{full_repository_name}: Failed to get github api", logger.error + return False, f"{full_repository_name}: Failed to get github api", LOGGER.error repo = _get_github_repo_api(github_api=github_api, repository=full_repository_name) if not repo: - return False, f"[API user {api_user}] - {full_repository_name}: Failed to get repository", logger.error + return False, f"[API user {api_user}] - {full_repository_name}: Failed to get repository", LOGGER.error try: set_repository_labels(repository=repo, api_user=api_user) @@ -260,18 +254,18 @@ def set_repository( return ( False, f"{full_repository_name}: Repository is private, skipping setting branch settings", - logger.warning, + LOGGER.warning, ) futures: list["Future"] = [] with ThreadPoolExecutor() as executor: for branch_name, status_checks in protected_branches.items(): - logger.debug(f"[API user {api_user}] - {full_repository_name}: Getting branch {branch_name}") + LOGGER.debug(f"[API user {api_user}] - {full_repository_name}: Getting branch {branch_name}") branch = get_branch_sampler(repo=repo, branch_name=branch_name) if not branch: - logger.error(f"[API user {api_user}] - {full_repository_name}: Failed to get branch {branch_name}") + LOGGER.error(f"[API user {api_user}] - {full_repository_name}: Failed to get branch {branch_name}") continue default_status_checks: list[str] = config.get_value( @@ -307,16 +301,16 @@ def set_repository( for result in as_completed(futures): if result.exception(): - logger.error(result.exception()) + LOGGER.error(result.exception()) except UnknownObjectException as ex: return ( False, f"[API user {api_user}] - {full_repository_name}: Failed to get repository settings, ex: {ex}", - logger.error, + LOGGER.error, ) - return True, f"[API user {api_user}] - {full_repository_name}: Setting repository settings is done", logger.info + return True, f"[API user {api_user}] - {full_repository_name}: Setting repository settings is done", LOGGER.info def set_all_in_progress_check_runs_to_queued(repo_config: Config, apis_dict: dict[str, dict[str, Any]]) -> None: @@ -331,7 +325,7 @@ def set_all_in_progress_check_runs_to_queued(repo_config: Config, apis_dict: dic with ThreadPoolExecutor() as executor: for repo, data in repo_config.root_data["repositories"].items(): - repo_config = Config(repository=repo) + repo_config = Config(repository=repo, logger=LOGGER) futures.append( executor.submit( set_repository_check_runs_to_queued, @@ -355,41 +349,37 @@ def set_repository_check_runs_to_queued( check_runs: tuple[str], api_user: str, ) -> tuple[bool, str, Callable]: - logger = get_logger_with_params(name="github-repository-settings") - repository: str = data["name"] repository_app_api = get_repository_github_app_api(config_=config_, repository_name=repository) if not repository_app_api: - return False, f"[API user {api_user}] - {repository}: Failed to get repositories GitHub app API", logger.error + return False, f"[API user {api_user}] - {repository}: Failed to get repositories GitHub app API", LOGGER.error app_api = _get_github_repo_api(github_api=repository_app_api, repository=repository) if not app_api: - logger.error(f"[API user {api_user}] - Failed to get GitHub app API for repository {repository}") - return False, f"[API user {api_user}] - Failed to get GitHub app API for repository {repository}", logger.error + LOGGER.error(f"[API user {api_user}] - Failed to get GitHub app API for repository {repository}") + return False, f"[API user {api_user}] - Failed to get GitHub app API for repository {repository}", LOGGER.error repo = _get_github_repo_api(github_api=github_api, repository=repository) if not repo: - logger.error(f"[API user {api_user}] - Failed to get GitHub API for repository {repository}") - return False, f"[API user {api_user}] - Failed to get GitHub API for repository {repository}", logger.error + LOGGER.error(f"[API user {api_user}] - Failed to get GitHub API for repository {repository}") + return False, f"[API user {api_user}] - Failed to get GitHub API for repository {repository}", LOGGER.error - logger.info(f"{repository}: Set all {IN_PROGRESS_STR} check runs to {QUEUED_STR}") + LOGGER.info(f"{repository}: Set all {IN_PROGRESS_STR} check runs to {QUEUED_STR}") for pull_request in repo.get_pulls(state="open"): last_commit: Commit = list(pull_request.get_commits())[-1] for check_run in last_commit.get_check_runs(): if check_run.name in check_runs and check_run.status == IN_PROGRESS_STR: - logger.warning( + LOGGER.warning( f"[API user {api_user}] - {repository}: [PR:{pull_request.number}] {check_run.name} status is {IN_PROGRESS_STR}, " f"Setting check run {check_run.name} to {QUEUED_STR}" ) app_api.create_check_run(name=check_run.name, head_sha=last_commit.sha, status=QUEUED_STR) - return True, f"[API user {api_user}] - {repository}: Set check run status to {QUEUED_STR} is done", logger.debug + return True, f"[API user {api_user}] - {repository}: Set check run status to {QUEUED_STR} is done", LOGGER.debug def get_repository_github_app_api(config_: Config, repository_name: str) -> Github | None: - logger = get_logger_with_params(name="github-repository-settings") - - logger.debug("Getting repositories GitHub app API") + LOGGER.debug("Getting repositories GitHub app API") with open(os.path.join(config_.data_dir, "webhook-server.private-key.pem")) as fd: private_key = fd.read() @@ -402,7 +392,7 @@ def get_repository_github_app_api(config_: Config, repository_name: str) -> Gith try: return app_instance.get_repo_installation(owner=owner, repo=repo).get_github_for_installation() except UnknownObjectException: - logger.error( + LOGGER.error( f"Repository {repository_name} not found by manage-repositories-app, " f"make sure the app installed (https://github.com/apps/manage-repositories-app)" ) diff --git a/webhook_server/utils/helpers.py b/webhook_server/utils/helpers.py index ebdfe137..b325b9cd 100644 --- a/webhook_server/utils/helpers.py +++ b/webhook_server/utils/helpers.py @@ -17,7 +17,9 @@ from webhook_server.libs.config import Config -def get_logger_with_params(name: str, repository_name: str = "") -> Logger: +def get_logger_with_params( + name: str, repository_name: str = "", mask_sensitive: bool = False, mask_sensitive_patterns: list[str] | None = None +) -> Logger: _config = Config(repository=repository_name) log_level: str = _config.get_value(value="log-level", return_on_none="INFO") @@ -26,7 +28,14 @@ def get_logger_with_params(name: str, repository_name: str = "") -> Logger: if log_file and not log_file.startswith("/"): log_file = os.path.join(_config.data_dir, "logs", log_file) - return get_logger(name=name, filename=log_file, level=log_level, file_max_bytes=1048576 * 50) # 50MB + return get_logger( + name=name, + filename=log_file, + level=log_level, + file_max_bytes=1048576 * 50, + mask_sensitive=mask_sensitive, + mask_sensitive_patterns=mask_sensitive_patterns, + ) # 50MB def extract_key_from_dict(key: Any, _dict: dict[Any, Any]) -> Any: @@ -77,7 +86,10 @@ def run_command( Returns: tuple: True, out if command succeeded, False, err otherwise. """ - logger = get_logger_with_params(name="helpers") + mask_sensitive_patterns: list[str] = ["-p", "password", "token", "apikey", "secret"] + logger = get_logger_with_params( + name="helpers", mask_sensitive=True, mask_sensitive_patterns=mask_sensitive_patterns + ) text = True out_decoded: str = "" err_decoded: str = ""