From b5fd1a16dd0b776c941713fa8ef6055f91f66187 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Wed, 27 May 2026 14:12:45 -0300 Subject: [PATCH 1/3] fix: bypass HTTP proxy for Patroni REST API calls Set trust_env=False on httpx.AsyncClient in parallel_patroni_get_request so proxy environment variables are ignored for intra-cluster Patroni communication. Signed-off-by: Marcelo Henrique Neppel --- single_kernel_postgresql/utils/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/single_kernel_postgresql/utils/__init__.py b/single_kernel_postgresql/utils/__init__.py index f1e1f1e..d9eae4c 100644 --- a/single_kernel_postgresql/utils/__init__.py +++ b/single_kernel_postgresql/utils/__init__.py @@ -164,7 +164,9 @@ async def _httpx_get_request( else: ssl_ctx.check_hostname = False ssl_ctx.verify_mode = CERT_NONE - async with AsyncClient(auth=auth, timeout=API_REQUEST_TIMEOUT, verify=ssl_ctx) as client: + async with AsyncClient( + auth=auth, timeout=API_REQUEST_TIMEOUT, verify=ssl_ctx, trust_env=False + ) as client: try: return (await client.get(url)).raise_for_status().json() except (HTTPError, ValueError): From 9bd6493883504747c8954c82ec4b23b4d5acfa21 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Wed, 27 May 2026 14:28:07 -0300 Subject: [PATCH 2/3] test: add unit tests for parallel_patroni_get_request proxy bypass Verify that AsyncClient is created with trust_env=False to prevent proxy environment variables from intercepting intra-cluster Patroni API calls. Signed-off-by: Marcelo Henrique Neppel --- tests/unit/test_utils.py | 51 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 46a5f4f..8bec1cd 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -2,15 +2,18 @@ # See LICENSE file for licensing details. import re -from unittest.mock import mock_open, patch +from asyncio import run as arun +from unittest.mock import Mock, mock_open, patch from single_kernel_postgresql.config.literals import Substrates from single_kernel_postgresql.utils import ( + _httpx_get_request, any_cpu_to_cores, any_memory_to_bytes, create_directory, label2name, new_password, + parallel_patroni_get_request, render_file, ) @@ -105,3 +108,49 @@ def test_create_directory(): _chmod.assert_called_once_with("test", 0o640) _chown.assert_called_once_with("test", uid=35, gid=35) _pwnam.assert_called_with("postgres") + + +def test_httpx_get_request(): + with patch("single_kernel_postgresql.utils.AsyncClient") as _async_client: + mock_response = Mock() + mock_response.raise_for_status.return_value = mock_response + mock_response.json.return_value = {"members": []} + + mock_client = _async_client.return_value.__aenter__.return_value + mock_client.get.return_value = mock_response + + result = arun(_httpx_get_request("https://1.1.1.1:8008/cluster", "/ca.pem")) + assert result == {"members": []} + + _async_client.assert_called_once() + call_kwargs = _async_client.call_args.kwargs + assert call_kwargs["trust_env"] is False + assert call_kwargs["timeout"] == 5 + + +def test_httpx_get_request_returns_none_on_error(): + with patch("single_kernel_postgresql.utils.AsyncClient") as _async_client: + from httpx import HTTPError + + mock_client = _async_client.return_value.__aenter__.return_value + mock_client.get.side_effect = HTTPError("connection failed") + + result = arun(_httpx_get_request("https://1.1.1.1:8008/cluster", "/ca.pem")) + assert result is None + + +def test_parallel_patroni_get_request(): + with patch("single_kernel_postgresql.utils.AsyncClient") as _async_client: + mock_response = Mock() + mock_response.raise_for_status.return_value = mock_response + mock_response.json.return_value = {"members": [{"name": "unit-0", "role": "leader"}]} + + mock_client = _async_client.return_value.__aenter__.return_value + mock_client.get.return_value = mock_response + + result = parallel_patroni_get_request("/cluster", ["1.1.1.1"], "/ca.pem") + assert result == {"members": [{"name": "unit-0", "role": "leader"}]} + + _async_client.assert_called() + call_kwargs = _async_client.call_args.kwargs + assert call_kwargs["trust_env"] is False From e763386979329d313cf303d03d504848e0066ff6 Mon Sep 17 00:00:00 2001 From: Marcelo Henrique Neppel Date: Wed, 27 May 2026 15:14:51 -0300 Subject: [PATCH 3/3] chore: bump version to 16.2.3 Signed-off-by: Marcelo Henrique Neppel --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d8d7b35..a3e4999 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "postgresql-charms-single-kernel" description = "Shared and reusable code for PostgreSQL-related charms" -version = "16.2.2" +version = "16.2.3" readme = "README.md" license = {file = "LICENSE"} authors = [