squarepeg 0.4.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {squarepeg-0.4.0 → squarepeg-0.4.1}/PKG-INFO +4 -1
- {squarepeg-0.4.0 → squarepeg-0.4.1}/README.md +3 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/pyproject.toml +1 -1
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/cli.py +5 -3
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/config.py +1 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/session.py +23 -3
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/PKG-INFO +4 -1
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_cli.py +35 -12
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_session.py +24 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/setup.cfg +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/__init__.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/__main__.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/dockerargs.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/env_interpolation.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/errors.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/__init__.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/apierrors.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/dryrun.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/events.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/logs.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/orphans.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/podstate.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/k8s/runner.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/labels.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/log.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/manifest.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/merge.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/naming.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/quantities.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/runspec.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/ui.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg/volumes.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/SOURCES.txt +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/dependency_links.txt +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/entry_points.txt +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/requires.txt +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/squarepeg.egg-info/top_level.txt +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_apierrors.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_config.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_dockerargs.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_dryrun.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_env_interpolation.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_events.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_integration.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_logs.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_manifest.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_merge.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_naming.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_orphans.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_podstate.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_quantities.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_runner.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_ui.py +0 -0
- {squarepeg-0.4.0 → squarepeg-0.4.1}/tests/test_volumes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: squarepeg
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Run a docker-run-style command as a Kubernetes Pod or Job, streaming its output like a local process
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -49,6 +49,9 @@ Full documentation lives in the [wiki](https://github.com/BioWilko/squarepeg/wik
|
|
|
49
49
|
- [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting)
|
|
50
50
|
- [Development](https://github.com/BioWilko/squarepeg/wiki/Development)
|
|
51
51
|
|
|
52
|
+
> **MicroK8s on Python 3.13+:** if connecting fails with `CA cert does not include key usage extension`,
|
|
53
|
+
> set `lenient_tls: true` in your config — see [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting#runner-errors-exit-code-125).
|
|
54
|
+
|
|
52
55
|
See also [`examples/config.yaml`](examples/config.yaml) for a fully worked
|
|
53
56
|
config file.
|
|
54
57
|
|
|
@@ -35,6 +35,9 @@ Full documentation lives in the [wiki](https://github.com/BioWilko/squarepeg/wik
|
|
|
35
35
|
- [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting)
|
|
36
36
|
- [Development](https://github.com/BioWilko/squarepeg/wiki/Development)
|
|
37
37
|
|
|
38
|
+
> **MicroK8s on Python 3.13+:** if connecting fails with `CA cert does not include key usage extension`,
|
|
39
|
+
> set `lenient_tls: true` in your config — see [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting#runner-errors-exit-code-125).
|
|
40
|
+
|
|
38
41
|
See also [`examples/config.yaml`](examples/config.yaml) for a fully worked
|
|
39
42
|
config file.
|
|
40
43
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "squarepeg"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.1"
|
|
8
8
|
description = "Run a docker-run-style command as a Kubernetes Pod or Job, streaming its output like a local process"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -354,6 +354,7 @@ def run(
|
|
|
354
354
|
else coerce_int(resolved_config.get("timeout", 300), "timeout")
|
|
355
355
|
)
|
|
356
356
|
quiet = quiet or coerce_bool(resolved_config.get("quiet", False), "quiet")
|
|
357
|
+
lenient_tls = coerce_bool(resolved_config.get("lenient_tls", False), "lenient_tls")
|
|
357
358
|
cleanup = (
|
|
358
359
|
False if keep else coerce_bool(resolved_config.get("cleanup", True), "cleanup")
|
|
359
360
|
)
|
|
@@ -435,7 +436,7 @@ def run(
|
|
|
435
436
|
ui.set_run_tag(effective_run_id)
|
|
436
437
|
|
|
437
438
|
if dry_run_server:
|
|
438
|
-
session = Session(namespace=spec.namespace, context=context, quiet=spec.quiet)
|
|
439
|
+
session = Session(namespace=spec.namespace, context=context, quiet=spec.quiet, lenient_tls=lenient_tls)
|
|
439
440
|
spec.namespace = session.namespace
|
|
440
441
|
validated = server_dry_run(session, spec, manifest)
|
|
441
442
|
click.echo(yaml.safe_dump(validated, sort_keys=False), nl=False)
|
|
@@ -444,7 +445,7 @@ def run(
|
|
|
444
445
|
click.echo(yaml.safe_dump(manifest, sort_keys=False), nl=False)
|
|
445
446
|
return
|
|
446
447
|
|
|
447
|
-
session = Session(namespace=spec.namespace, context=context, quiet=spec.quiet)
|
|
448
|
+
session = Session(namespace=spec.namespace, context=context, quiet=spec.quiet, lenient_tls=lenient_tls)
|
|
448
449
|
spec.namespace = session.namespace
|
|
449
450
|
exit_code = run_manifest(session, spec, manifest)
|
|
450
451
|
raise SystemExit(exit_code)
|
|
@@ -510,6 +511,7 @@ def clean(dry_run, min_age, namespace, context, quiet, no_color, config_paths, n
|
|
|
510
511
|
if namespace is None:
|
|
511
512
|
namespace = resolved_config.get("namespace")
|
|
512
513
|
quiet = quiet or coerce_bool(resolved_config.get("quiet", False), "quiet")
|
|
514
|
+
lenient_tls = coerce_bool(resolved_config.get("lenient_tls", False), "lenient_tls")
|
|
513
515
|
|
|
514
516
|
if min_age is None:
|
|
515
517
|
min_age = coerce_int(
|
|
@@ -520,7 +522,7 @@ def clean(dry_run, min_age, namespace, context, quiet, no_color, config_paths, n
|
|
|
520
522
|
elif min_age < 0:
|
|
521
523
|
raise UsageError(f"--min-age must not be negative, got {min_age}")
|
|
522
524
|
|
|
523
|
-
session = Session(namespace=namespace, context=context, quiet=quiet)
|
|
525
|
+
session = Session(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
524
526
|
|
|
525
527
|
with ui.Status("scanning for orphaned resources", quiet=quiet):
|
|
526
528
|
result = clean_orphans(session, min_age, quiet=quiet, dry_run=dry_run)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import ssl
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
from kubernetes import client
|
|
4
5
|
from kubernetes import config as kube_config
|
|
5
6
|
from kubernetes.config.config_exception import ConfigException
|
|
7
|
+
from urllib3.util.ssl_ import create_urllib3_context
|
|
6
8
|
|
|
7
9
|
from squarepeg.errors import RunnerError
|
|
8
10
|
from squarepeg.log import chatter
|
|
@@ -47,7 +49,13 @@ class Session:
|
|
|
47
49
|
surface that failure, not be silently masked by an in-cluster fallback.
|
|
48
50
|
"""
|
|
49
51
|
|
|
50
|
-
def __init__(
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
namespace: str | None = None,
|
|
55
|
+
context: str | None = None,
|
|
56
|
+
quiet: bool = False,
|
|
57
|
+
lenient_tls: bool = False,
|
|
58
|
+
):
|
|
51
59
|
in_cluster = False
|
|
52
60
|
try:
|
|
53
61
|
kube_config.load_kube_config(context=context)
|
|
@@ -73,7 +81,19 @@ class Session:
|
|
|
73
81
|
|
|
74
82
|
self.namespace = namespace or context_namespace or "default"
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
api_client = None
|
|
85
|
+
if lenient_tls:
|
|
86
|
+
# short-term workaround for https://github.com/canonical/microk8s/issues/4864: microk8s's CA
|
|
87
|
+
# lacks the keyUsage extension, which Python 3.13+/urllib3 2.3+ reject via VERIFY_X509_STRICT.
|
|
88
|
+
# Only that flag is cleared -- CERT_REQUIRED, CA chain and hostname checks are all still
|
|
89
|
+
# enforced. The kubernetes client exposes no ssl_context option, so it's injected into the
|
|
90
|
+
# (lazily created) urllib3 connection pools' kwargs instead.
|
|
91
|
+
ssl_context = create_urllib3_context()
|
|
92
|
+
ssl_context.verify_flags &= ~ssl.VERIFY_X509_STRICT
|
|
93
|
+
api_client = client.ApiClient()
|
|
94
|
+
api_client.rest_client.pool_manager.connection_pool_kw["ssl_context"] = ssl_context
|
|
95
|
+
|
|
96
|
+
self.core = client.CoreV1Api(api_client)
|
|
97
|
+
self.batch = client.BatchV1Api(api_client)
|
|
78
98
|
|
|
79
99
|
chatter(f"using context {self.context_name!r}, namespace {self.namespace!r}", quiet=quiet)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: squarepeg
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Run a docker-run-style command as a Kubernetes Pod or Job, streaming its output like a local process
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -49,6 +49,9 @@ Full documentation lives in the [wiki](https://github.com/BioWilko/squarepeg/wik
|
|
|
49
49
|
- [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting)
|
|
50
50
|
- [Development](https://github.com/BioWilko/squarepeg/wiki/Development)
|
|
51
51
|
|
|
52
|
+
> **MicroK8s on Python 3.13+:** if connecting fails with `CA cert does not include key usage extension`,
|
|
53
|
+
> set `lenient_tls: true` in your config — see [Troubleshooting](https://github.com/BioWilko/squarepeg/wiki/Troubleshooting#runner-errors-exit-code-125).
|
|
54
|
+
|
|
52
55
|
See also [`examples/config.yaml`](examples/config.yaml) for a fully worked
|
|
53
56
|
config file.
|
|
54
57
|
|
|
@@ -26,10 +26,11 @@ class FakeSession:
|
|
|
26
26
|
.core/.batch are plain MagicMocks returning empty lists by default, for 'clean' tests
|
|
27
27
|
that need a listable (but otherwise inert) session."""
|
|
28
28
|
|
|
29
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
29
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
30
30
|
self.namespace = namespace or "default"
|
|
31
31
|
self.context = context
|
|
32
32
|
self.quiet = quiet
|
|
33
|
+
self.lenient_tls = lenient_tls
|
|
33
34
|
self.context_name = context or "fake-context"
|
|
34
35
|
self.core = MagicMock()
|
|
35
36
|
self.batch = MagicMock()
|
|
@@ -318,11 +319,12 @@ def test_dry_run_server_constructs_session_with_context_and_quiet(monkeypatch):
|
|
|
318
319
|
constructed = {}
|
|
319
320
|
|
|
320
321
|
class RecordingFakeSession(FakeSession):
|
|
321
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
322
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
322
323
|
constructed["namespace"] = namespace
|
|
323
324
|
constructed["context"] = context
|
|
324
325
|
constructed["quiet"] = quiet
|
|
325
|
-
|
|
326
|
+
constructed["lenient_tls"] = lenient_tls
|
|
327
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
326
328
|
|
|
327
329
|
monkeypatch.setattr(cli_module, "Session", RecordingFakeSession)
|
|
328
330
|
monkeypatch.setattr(cli_module, "server_dry_run", lambda session, spec, manifest: manifest)
|
|
@@ -333,6 +335,27 @@ def test_dry_run_server_constructs_session_with_context_and_quiet(monkeypatch):
|
|
|
333
335
|
assert result.exit_code == 0, result.output
|
|
334
336
|
assert constructed["context"] == "my-context"
|
|
335
337
|
assert constructed["quiet"] is True
|
|
338
|
+
assert constructed["lenient_tls"] is False
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def test_dry_run_server_lenient_tls_from_config(monkeypatch, tmp_path):
|
|
342
|
+
constructed = {}
|
|
343
|
+
|
|
344
|
+
class RecordingFakeSession(FakeSession):
|
|
345
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
346
|
+
constructed["lenient_tls"] = lenient_tls
|
|
347
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
348
|
+
|
|
349
|
+
monkeypatch.setattr(cli_module, "Session", RecordingFakeSession)
|
|
350
|
+
monkeypatch.setattr(cli_module, "server_dry_run", lambda session, spec, manifest: manifest)
|
|
351
|
+
config_file = tmp_path / "config.yaml"
|
|
352
|
+
config_file.write_text("lenient_tls: true\n")
|
|
353
|
+
|
|
354
|
+
result = CliRunner().invoke(
|
|
355
|
+
cli, ["run", "--no-default-config", "--config", str(config_file), "--dry-run-server", "alpine"]
|
|
356
|
+
)
|
|
357
|
+
assert result.exit_code == 0, result.output
|
|
358
|
+
assert constructed["lenient_tls"] is True
|
|
336
359
|
|
|
337
360
|
|
|
338
361
|
def test_dry_run_server_apiserver_rejection_exits_125(monkeypatch):
|
|
@@ -354,7 +377,7 @@ def test_dry_run_server_apiserver_rejection_exits_125(monkeypatch):
|
|
|
354
377
|
|
|
355
378
|
|
|
356
379
|
def test_dry_run_server_no_cluster_connection_exits_125(monkeypatch):
|
|
357
|
-
def raising_session(namespace=None, context=None, quiet=False):
|
|
380
|
+
def raising_session(namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
358
381
|
raise RunnerError("could not load a kubeconfig (...) and doesn't look like it's running in-cluster (...)")
|
|
359
382
|
|
|
360
383
|
monkeypatch.setattr(cli_module, "Session", raising_session)
|
|
@@ -554,8 +577,8 @@ def _mock_clean_session(monkeypatch, pods=(), jobs=()):
|
|
|
554
577
|
monkeypatch.setattr("squarepeg.k8s.orphans.current_created_by", lambda: CLEAN_CREATED_BY)
|
|
555
578
|
|
|
556
579
|
class RecordingFakeSession(FakeSession):
|
|
557
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
558
|
-
super().__init__(namespace=namespace, context=context, quiet=quiet)
|
|
580
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
581
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
559
582
|
self.core.list_namespaced_pod.return_value = SimpleNamespace(items=list(pods))
|
|
560
583
|
self.batch.list_namespaced_job.return_value = SimpleNamespace(items=list(jobs))
|
|
561
584
|
|
|
@@ -597,8 +620,8 @@ def test_clean_partial_failure_exit_code(monkeypatch):
|
|
|
597
620
|
monkeypatch.setattr("squarepeg.k8s.orphans.current_created_by", lambda: CLEAN_CREATED_BY)
|
|
598
621
|
|
|
599
622
|
class FailingFakeSession(FakeSession):
|
|
600
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
601
|
-
super().__init__(namespace=namespace, context=context, quiet=quiet)
|
|
623
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
624
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
602
625
|
self.core.list_namespaced_pod.return_value = SimpleNamespace(items=[_clean_pod("p1"), _clean_pod("p2")])
|
|
603
626
|
self.core.delete_namespaced_pod.side_effect = [ApiException(status=500, reason="err"), None]
|
|
604
627
|
|
|
@@ -613,8 +636,8 @@ def test_clean_listing_failure_exits_125(monkeypatch):
|
|
|
613
636
|
monkeypatch.setattr("squarepeg.k8s.orphans.current_created_by", lambda: CLEAN_CREATED_BY)
|
|
614
637
|
|
|
615
638
|
class RaisingFakeSession(FakeSession):
|
|
616
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
617
|
-
super().__init__(namespace=namespace, context=context, quiet=quiet)
|
|
639
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
640
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
618
641
|
self.core.list_namespaced_pod.side_effect = ApiException(status=403, reason="Forbidden")
|
|
619
642
|
|
|
620
643
|
monkeypatch.setattr(cli_module, "Session", RaisingFakeSession)
|
|
@@ -628,10 +651,10 @@ def test_clean_namespace_and_context_forwarded_to_session(monkeypatch):
|
|
|
628
651
|
monkeypatch.setattr("squarepeg.k8s.orphans.current_created_by", lambda: CLEAN_CREATED_BY)
|
|
629
652
|
|
|
630
653
|
class RecordingFakeSession(FakeSession):
|
|
631
|
-
def __init__(self, namespace=None, context=None, quiet=False):
|
|
654
|
+
def __init__(self, namespace=None, context=None, quiet=False, lenient_tls=False):
|
|
632
655
|
constructed["namespace"] = namespace
|
|
633
656
|
constructed["context"] = context
|
|
634
|
-
super().__init__(namespace=namespace, context=context, quiet=quiet)
|
|
657
|
+
super().__init__(namespace=namespace, context=context, quiet=quiet, lenient_tls=lenient_tls)
|
|
635
658
|
|
|
636
659
|
monkeypatch.setattr(cli_module, "Session", RecordingFakeSession)
|
|
637
660
|
result = _separated_runner().invoke(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ssl
|
|
1
2
|
from unittest.mock import MagicMock
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
@@ -119,3 +120,26 @@ def test_explicit_context_failure_does_not_fall_back_to_incluster(monkeypatch):
|
|
|
119
120
|
session_module.Session(context="myctx", quiet=True)
|
|
120
121
|
|
|
121
122
|
incluster.assert_not_called()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _pool_kw(api):
|
|
126
|
+
return api.api_client.rest_client.pool_manager.connection_pool_kw
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_default_session_injects_no_ssl_context(monkeypatch):
|
|
130
|
+
monkeypatch.setattr(session_module.kube_config, "load_kube_config", MagicMock())
|
|
131
|
+
monkeypatch.setattr(session_module.kube_config, "list_kube_config_contexts", MagicMock(return_value=_ctx()))
|
|
132
|
+
s = session_module.Session(quiet=True)
|
|
133
|
+
assert "ssl_context" not in _pool_kw(s.core)
|
|
134
|
+
assert "ssl_context" not in _pool_kw(s.batch)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_lenient_tls_clears_only_x509_strict(monkeypatch):
|
|
138
|
+
monkeypatch.setattr(session_module.kube_config, "load_kube_config", MagicMock())
|
|
139
|
+
monkeypatch.setattr(session_module.kube_config, "list_kube_config_contexts", MagicMock(return_value=_ctx()))
|
|
140
|
+
s = session_module.Session(quiet=True, lenient_tls=True)
|
|
141
|
+
assert s.core.api_client is s.batch.api_client
|
|
142
|
+
ctx = _pool_kw(s.core)["ssl_context"]
|
|
143
|
+
assert not ctx.verify_flags & ssl.VERIFY_X509_STRICT
|
|
144
|
+
assert ctx.verify_mode == ssl.CERT_REQUIRED
|
|
145
|
+
assert ctx.check_hostname is True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|