Skip to content

Commit dfa9792

Browse files
Add proxy support to Kubernetes client configuration in get_client (#2291)
* Add proxy support to Kubernetes client configuration in get_client This update modifies the get_client function to support setting a proxy for the Kubernetes client configuration. The client_configuration argument is introduced to allow passing a client.Configuration object directly, and if not provided, it defaults to creating a new configuration instance. Additionally, if the HTTPS_PROXY or HTTP_PROXY environment variables are set, the proxy is applied to the Kubernetes client configuration. This enhancement enables easier integration of Kubernetes client setup when working behind a proxy. Signed-off-by: Shahaf Bahar <[email protected]> * Simplify docstring by removing redundant default value explanation * Update proxy configuration logic and README documentation * Simplify use_proxy docstring in get_client method * Add support for enabling proxy with use_proxy flag * Remove client_configuration from get_client and initialize only for proxy usage Signed-off-by: Shahaf Bahar <[email protected]> * Refactor proxy handling in get_client function * Refactor docstring to clarify proxy behavior * Simplify proxy configuration logic in get_client * Improve error message for missing proxy configuration in get_client * Remove redundant dot in README * Remove unnecessary check for client_configuration in get_client * Update README to clarify proxy enablement instructions * Clarify proxy enablement in README * Clarify use_proxy argument type in README * Retrieve client_configuration from kwargs if provided * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Ensure environment variable overrides use_proxy * Remove redundant proxy configuration log * Preserve client_configuration from kwargs when setting proxy * Update docstring to clarify proxy conf behavior with env var * Refactor proxy configuration logic for clarity * Update README with proxy enablement details * Refactor client_configuration retrieval in get_client * Refactor proxy configuration in get_client for improved clarity * Refactor use_proxy argument in get_client to support None as default value * Remove use_proxy argument from get_client and update README * Ensure proxy settings are always applied when enabled * Check for proxy conflicts in client_configuration and environment variable * Add test to verify proxy conflict raises ValueError for mismatched proxy settings * Refactor test for proxy conflict in get_client method Signed-off-by: Shahaf Bahar <[email protected]> * Refactor test for proxy conflict to use pytest.raises match exp * Add test for proxy enabled without proxy env variables set --------- Signed-off-by: Shahaf Bahar <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent e88e0ff commit dfa9792

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL=<LOG_LEVEL> # can be: "DEBUG", "INFO",
9393
export OPENSHIFT_PYTHON_WRAPPER_HASH_LOG_DATA="false"
9494
```
9595

96+
## Proxy Enablement
97+
98+
This configuration allows the client to route traffic through a specified proxy server.
99+
It can be enabled via the environment variable `OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY`.
100+
101+
To enable proxy configuration for the client:
102+
103+
1. Set the environment variable `OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY=<any value>`
104+
105+
2. Define either `HTTPS_PROXY` or `HTTP_PROXY` environment variable with your proxy URL:
106+
```bash
107+
export HTTPS_PROXY="http://proxy.example.com:8080"
108+
# or
109+
export HTTP_PROXY="http://proxy.example.com:8080"
110+
```
111+
If neither variable is set when proxy is enabled, a `ValueError` will be raised.
112+
96113
## Code check
97114

98115
We use pre-commit for code check.

ocp_resources/resource.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ def _get_api_version(dyn_client: DynamicClient, api_group: str, kind: str) -> st
7676

7777

7878
def get_client(
79-
config_file: str = "", config_dict: dict[str, Any] | None = None, context: str = "", **kwargs: Any
79+
config_file: str = "",
80+
config_dict: dict[str, Any] | None = None,
81+
context: str = "",
82+
**kwargs: Any,
8083
) -> DynamicClient:
8184
"""
8285
Get a kubernetes client.
@@ -104,6 +107,7 @@ def get_client(
104107
config_dict=config_dict, context=context or None, **kwargs
105108
)
106109
)
110+
client_configuration = kwargs.get("client_configuration", kubernetes.client.Configuration())
107111
try:
108112
# Ref: https://github.com/kubernetes-client/python/blob/v26.1.0/kubernetes/base/config/__init__.py
109113
LOGGER.info("Trying to get client via new_client_from_config")
@@ -112,15 +116,34 @@ def get_client(
112116
# If `KUBECONFIG` environment variable is set via code, the `KUBE_CONFIG_DEFAULT_LOCATION` will be None since
113117
# is populated during import which comes before setting the variable in code.
114118
config_file = config_file or os.environ.get("KUBECONFIG", "~/.kube/config")
119+
120+
if os.environ.get("OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY"):
121+
proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("HTTP_PROXY")
122+
if not proxy:
123+
raise ValueError(
124+
"Proxy configuration is enabled but neither HTTPS_PROXY nor HTTP_PROXY environment variables are set."
125+
)
126+
if client_configuration.proxy and client_configuration.proxy != proxy:
127+
raise ValueError(
128+
f"Conflicting proxy settings: client_configuration.proxy={client_configuration.proxy}, "
129+
f"but the environment variable 'OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY' defines proxy as {proxy}."
130+
)
131+
client_configuration.proxy = proxy
132+
115133
return kubernetes.dynamic.DynamicClient(
116-
client=kubernetes.config.new_client_from_config(config_file=config_file, context=context or None, **kwargs)
134+
client=kubernetes.config.new_client_from_config(
135+
config_file=config_file,
136+
client_configuration=client_configuration,
137+
context=context or None,
138+
**kwargs,
139+
)
117140
)
118141
except MaxRetryError:
119142
# Ref: https://github.com/kubernetes-client/python/blob/v26.1.0/kubernetes/base/config/incluster_config.py
120143
LOGGER.info("Trying to get client via incluster_config")
121144
return kubernetes.dynamic.DynamicClient(
122145
client=kubernetes.config.incluster_config.load_incluster_config(
123-
client_configuration=kwargs.get("client_configuration"),
146+
client_configuration=client_configuration,
124147
try_refresh_token=kwargs.get("try_refresh_token", True),
125148
)
126149
)

tests/test_resources.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
import yaml
3+
import kubernetes
34
from testcontainers.k3s import K3SContainer
45

56
from ocp_resources.exceptions import ResourceTeardownError
@@ -103,3 +104,26 @@ def test_resource_context_manager_exit(self, client):
103104
with pytest.raises(ResourceTeardownError):
104105
with TestSecretExit(name="test-context-manager-exit", namespace="default", client=client):
105106
pass
107+
108+
def test_proxy_enabled_but_no_proxy_set(self, monkeypatch):
109+
monkeypatch.setenv(name="OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY", value="1")
110+
111+
with pytest.raises(
112+
ValueError,
113+
match="Proxy configuration is enabled but neither HTTPS_PROXY nor HTTP_PROXY environment variables are set.",
114+
):
115+
get_client()
116+
117+
def test_proxy_conflict_raises_value_error(self, monkeypatch):
118+
monkeypatch.setenv(name="OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY", value="1")
119+
monkeypatch.setenv(name="HTTPS_PROXY", value="http://env-proxy.com")
120+
121+
client_configuration = kubernetes.client.Configuration()
122+
client_configuration.proxy = "http://not-env-proxy.com"
123+
124+
with pytest.raises(
125+
ValueError,
126+
match="Conflicting proxy settings: client_configuration.proxy=http://not-env-proxy.com, "
127+
"but the environment variable 'OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY' defines proxy as http://env-proxy.com.",
128+
):
129+
get_client(client_configuration=client_configuration)

0 commit comments

Comments
 (0)