Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,17 @@ export OPENSHIFT_PYTHON_WRAPPER_LOG_LEVEL=<LOG_LEVEL> # can be: "DEBUG", "INFO",
## Proxy Enablement

This configuration allows the client to route traffic through a specified proxy server.
It can be enabled via the environment variable `OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY`.

To enable proxy configuration for the client:

1. Set the environment variable `OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY=<any value>`
1. Define either `HTTPS_PROXY` or `HTTP_PROXY` environment variable with your proxy URL:

2. Define either `HTTPS_PROXY` or `HTTP_PROXY` environment variable with your proxy URL:
```bash
export HTTPS_PROXY="http://proxy.example.com:8080"
# or
export HTTP_PROXY="http://proxy.example.com:8080"
```

If neither variable is set when proxy is enabled, a `ValueError` will be raised.

## Code check
Expand Down
47 changes: 20 additions & 27 deletions ocp_resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,22 @@ def get_client(
Returns:
DynamicClient: a kubernetes client.
"""
client_configuration = kwargs.get("client_configuration", kubernetes.client.Configuration())

# If the proxy is not set, set it from the environment
if not client_configuration.proxy:
proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("HTTP_PROXY")
if proxy:
client_configuration.proxy = proxy

kwargs["client_configuration"] = client_configuration

# Ref: https://github.com/kubernetes-client/python/blob/v26.1.0/kubernetes/base/config/kube_config.py
if config_dict:
return kubernetes.dynamic.DynamicClient(
client=kubernetes.config.new_client_from_config_dict(
config_dict=config_dict, context=context or None, **kwargs
)
_client = kubernetes.config.new_client_from_config_dict(
config_dict=config_dict, context=context or None, **kwargs
)
client_configuration = kwargs.get("client_configuration", kubernetes.client.Configuration())
try:
else:
# Ref: https://github.com/kubernetes-client/python/blob/v26.1.0/kubernetes/base/config/__init__.py
LOGGER.info("Trying to get client via new_client_from_config")

Expand All @@ -118,28 +125,14 @@ def get_client(
# is populated during import which comes before setting the variable in code.
config_file = config_file or os.environ.get("KUBECONFIG", "~/.kube/config")

if os.environ.get("OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY"):
proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("HTTP_PROXY")
if not proxy:
raise ValueError(
"Proxy configuration is enabled but neither HTTPS_PROXY nor HTTP_PROXY environment variables are set."
)
if client_configuration.proxy and client_configuration.proxy != proxy:
raise ValueError(
f"Conflicting proxy settings: client_configuration.proxy={client_configuration.proxy}, "
f"but the environment variable 'HTTPS_PROXY/HTTP_PROXY' defines proxy as {proxy}."
)
client_configuration.proxy = proxy

kwargs["client_configuration"] = client_configuration

return kubernetes.dynamic.DynamicClient(
client=kubernetes.config.new_client_from_config(
config_file=config_file,
context=context or None,
**kwargs,
)
_client = kubernetes.config.new_client_from_config(
config_file=config_file,
context=context or None,
**kwargs,
)

try:
return kubernetes.dynamic.DynamicClient(client=_client)
except MaxRetryError:
# Ref: https://github.com/kubernetes-client/python/blob/v26.1.0/kubernetes/base/config/incluster_config.py
LOGGER.info("Trying to get client via incluster_config")
Expand Down
42 changes: 16 additions & 26 deletions tests/test_resources.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
import yaml
from docker.errors import DockerException
import kubernetes
from kubernetes.config.config_exception import ConfigException
from testcontainers.k3s import K3SContainer

from ocp_resources.exceptions import ResourceTeardownError
Expand All @@ -19,13 +19,18 @@ def clean_up(self, wait: bool = True, timeout: int | None = None) -> bool:
return False


@pytest.fixture(scope="session")
def client():
@pytest.fixture(scope="class")
def k3scontainer_config():
try:
with K3SContainer() as k3s:
yield get_client(config_dict=yaml.safe_load(k3s.config_yaml()))
except DockerException:
pytest.skip("K3S container not available")
yield yaml.safe_load(k3s.config_yaml())
except DockerException as ex:
pytest.skip(f"K3S container not available. {ex}")


@pytest.fixture(scope="class")
def client(k3scontainer_config):
yield get_client(config_dict=k3scontainer_config)


@pytest.fixture(scope="class")
Expand Down Expand Up @@ -109,25 +114,10 @@ def test_resource_context_manager_exit(self, client):
with SecretTestExit(name="test-context-manager-exit", namespace="default", client=client):
pass

def test_proxy_enabled_but_no_proxy_set(self, monkeypatch):
monkeypatch.setenv(name="OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY", value="1")

with pytest.raises(
ValueError,
match="Proxy configuration is enabled but neither HTTPS_PROXY nor HTTP_PROXY environment variables are set.",
):
get_client()

def test_proxy_conflict_raises_value_error(self, monkeypatch):
monkeypatch.setenv(name="OPENSHIFT_PYTHON_WRAPPER_CLIENT_USE_PROXY", value="1")
monkeypatch.setenv(name="HTTPS_PROXY", value="http://env-proxy.com")

client_configuration = kubernetes.client.Configuration()
client_configuration.proxy = "http://not-env-proxy.com"
def test_client_with_proxy(monkeypatch, k3scontainer_config):
proxy = "http://env-proxy.com"
monkeypatch.setenv(name="HTTPS_PROXY", value=proxy)

with pytest.raises(
ValueError,
match="Conflicting proxy settings: client_configuration.proxy=http://not-env-proxy.com, "
"but the environment variable 'HTTPS_PROXY/HTTP_PROXY' defines proxy as http://env-proxy.com.",
):
get_client(client_configuration=client_configuration)
with pytest.raises(ConfigException, match=r"Service host/port is not set."):
get_client(config_dict=k3scontainer_config)