kubernator 1.0.20.dev20250519050248__py3-none-any.whl → 1.0.21__py3-none-any.whl

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.

Potentially problematic release.


This version of kubernator might be problematic. Click here for more details.

kubernator/__init__.py CHANGED
@@ -16,7 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- __version__ = "1.0.20.dev20250519050248"
19
+ __version__ = "1.0.21"
20
20
 
21
21
 
22
22
  def _main():
kubernator/api.py CHANGED
@@ -768,7 +768,8 @@ class KubernatorPlugin:
768
768
  pass
769
769
 
770
770
 
771
- def install_python_k8s_client(run, package_major, logger, logger_stdout, logger_stderr, disable_patching):
771
+ def install_python_k8s_client(run, package_major, logger, logger_stdout, logger_stderr, disable_patching,
772
+ fallback=False):
772
773
  cache_dir = get_cache_dir("python")
773
774
  package_major_dir = cache_dir / str(package_major)
774
775
  package_major_dir_str = str(package_major_dir)
@@ -780,14 +781,43 @@ def install_python_k8s_client(run, package_major, logger, logger_stdout, logger_
780
781
  str(package_major), package_major_dir)
781
782
  rmtree(package_major_dir)
782
783
 
783
- if not package_major_dir.exists():
784
+ if not package_major_dir.exists() or not len(os.listdir(package_major_dir)):
784
785
  package_major_dir.mkdir(parents=True, exist_ok=True)
785
- run([sys.executable, "-m", "pip", "install", "--no-deps", "--no-input",
786
- "--root-user-action=ignore", "--break-system-packages", "--disable-pip-version-check",
787
- "--target", package_major_dir_str, f"kubernetes>={package_major!s}dev0,<{int(package_major) + 1!s}"],
788
- logger_stdout, logger_stderr).wait()
786
+ try:
787
+ run([sys.executable, "-m", "pip", "install", "--no-deps", "--no-input",
788
+ "--root-user-action=ignore", "--break-system-packages", "--disable-pip-version-check",
789
+ "--target", package_major_dir_str, f"kubernetes>={package_major!s}dev0,<{int(package_major) + 1!s}"],
790
+ logger_stdout, logger_stderr)
791
+ except CalledProcessError as e:
792
+ if not fallback and "No matching distribution found for" in e.stderr:
793
+ logger.warning("Kubernetes Client %s (%s) failed to install because the version wasn't found. "
794
+ "Falling back to a client of the previous version - %s",
795
+ str(package_major), package_major_dir, int(package_major) - 1)
796
+ return install_python_k8s_client(run,
797
+ int(package_major) - 1,
798
+ logger,
799
+ logger_stdout,
800
+ logger_stderr,
801
+ disable_patching,
802
+ fallback=True)
803
+ else:
804
+ raise
789
805
 
790
806
  if not patch_indicator.exists() and not disable_patching:
807
+ if not fallback and not len(os.listdir(package_major_dir)):
808
+ # Directory is empty
809
+ logger.warning("Kubernetes Client %s (%s) directory is empty - the client was not installed. "
810
+ "Falling back to a client of the previous version - %s",
811
+ str(package_major), package_major_dir, int(package_major) - 1)
812
+
813
+ return install_python_k8s_client(run,
814
+ int(package_major) - 1,
815
+ logger,
816
+ logger_stdout,
817
+ logger_stderr,
818
+ disable_patching,
819
+ fallback=True)
820
+
791
821
  for patch_text, target_file, skip_if_found, min_version, max_version, name in (
792
822
  URLLIB_HEADERS_PATCH, CUSTOM_OBJECT_PATCH_23, CUSTOM_OBJECT_PATCH_25):
793
823
  patch_target = package_major_dir / target_file
kubernator/app.py CHANGED
@@ -35,7 +35,7 @@ import kubernator
35
35
  from kubernator.api import (KubernatorPlugin, Globs, scan_dir, PropertyDict, config_as_dict, config_parent,
36
36
  download_remote_file, load_remote_file, Repository, StripNL, jp, get_app_cache_dir,
37
37
  get_cache_dir, install_python_k8s_client)
38
- from kubernator.proc import run, run_capturing_out
38
+ from kubernator.proc import run, run_capturing_out, run_pass_through_capturing
39
39
 
40
40
  TRACE = 5
41
41
 
@@ -215,7 +215,7 @@ class App(KubernatorPlugin):
215
215
  self.context = self._top_dir_context
216
216
  context = self.context
217
217
  self._run_handlers(KubernatorPlugin.handle_shutdown, True, context, None)
218
- except: # noqa E722
218
+ except: # noqa E722
219
219
  raise
220
220
  else:
221
221
  self.context = self._top_dir_context
@@ -348,6 +348,7 @@ class App(KubernatorPlugin):
348
348
  jp=jp,
349
349
  run=self._run,
350
350
  run_capturing_out=self._run_capturing_out,
351
+ run_passthrough_capturing=self._run_passthrough_capturing,
351
352
  repository=self.repository,
352
353
  StripNL=StripNL,
353
354
  default_includes=Globs(["*"], True),
@@ -465,6 +466,9 @@ class App(KubernatorPlugin):
465
466
  def _run_capturing_out(self, *args, **kwargs):
466
467
  return run_capturing_out(*args, **kwargs)
467
468
 
469
+ def _run_passthrough_capturing(self, *args, **kwargs):
470
+ return run_pass_through_capturing(*args, **kwargs)
471
+
468
472
  def __repr__(self):
469
473
  return "Kubernator"
470
474
 
@@ -493,7 +497,7 @@ def pre_cache_k8s_clients(*versions, disable_patching=False):
493
497
  for v in versions:
494
498
  logger.info("Caching K8S client library ~=v%s.0%s...", v,
495
499
  " (no patches)" if disable_patching else "")
496
- install_python_k8s_client(run, v, logger, stdout_logger, stderr_logger, disable_patching)
500
+ install_python_k8s_client(run_pass_through_capturing, v, logger, stdout_logger, stderr_logger, disable_patching)
497
501
 
498
502
 
499
503
  def main():
kubernator/plugins/k8s.py CHANGED
@@ -164,7 +164,7 @@ class KubernetesPlugin(KubernatorPlugin, K8SResourcePluginMixin):
164
164
 
165
165
  logger.info("Using Kubernetes client version =~%s.0 for server version %s",
166
166
  server_minor, ".".join(k8s.server_version))
167
- pkg_dir = install_python_k8s_client(self.context.app.run, server_minor, logger,
167
+ pkg_dir = install_python_k8s_client(self.context.app.run_passthrough_capturing, server_minor, logger,
168
168
  stdout_logger, stderr_logger, k8s.disable_client_patches)
169
169
 
170
170
  modules_to_delete = []
@@ -31,7 +31,7 @@ import yaml
31
31
  from jsonschema._format import FormatChecker
32
32
  from jsonschema._keywords import required
33
33
  from jsonschema.exceptions import ValidationError
34
- from jsonschema.validators import extend, Draft7Validator, RefResolver
34
+ from jsonschema.validators import extend, Draft7Validator
35
35
  from openapi_schema_validator import OAS31Validator
36
36
 
37
37
  from kubernator.api import load_file, FileType, load_remote_file, calling_frame_source
@@ -147,10 +147,6 @@ def check_int_or_string(value):
147
147
  return check_int32(value) if is_integer(value) else is_string(value)
148
148
 
149
149
 
150
- # def make_api_version(group, version):
151
- # return f"{group}/{version}" if group else version
152
-
153
-
154
150
  def to_group_and_version(api_version):
155
151
  group, _, version = api_version.partition("/")
156
152
  if not version:
@@ -662,10 +658,8 @@ class K8SResourcePluginMixin:
662
658
  yield error
663
659
  else:
664
660
  rdef = error
665
- # schema = ChainMap(manifest, self.resource_definitions_schema)
666
661
  k8s_validator = K8SValidator(rdef.schema,
667
- format_checker=k8s_format_checker,
668
- resolver=RefResolver.from_schema(self.resource_definitions_schema))
662
+ format_checker=k8s_format_checker)
669
663
  yield from k8s_validator.iter_errors(manifest)
670
664
 
671
665
  def _get_manifest_rdef(self, manifest):
@@ -743,6 +737,8 @@ class K8SResourcePluginMixin:
743
737
  rdef_paths[path] = actions
744
738
 
745
739
  for k, schema in k8s_def["definitions"].items():
740
+ # This short-circuits the resolution of the references to the top of the document
741
+ schema["definitions"] = k8s_def["definitions"]
746
742
  for key in k8s_resource_def_key(schema):
747
743
  for rdef in K8SResourceDef.from_manifest(key, schema, self.resource_paths):
748
744
  self.resource_definitions[key] = rdef
@@ -35,6 +35,8 @@ proc_logger = logger.getChild("proc")
35
35
  stdout_logger = StripNL(proc_logger.info)
36
36
  stderr_logger = StripNL(proc_logger.warning)
37
37
 
38
+ MINIKUBE_MAX_VERSION_LEGACY = "1.36.0"
39
+
38
40
 
39
41
  class MinikubePlugin(KubernatorPlugin):
40
42
  logger = logger
@@ -99,9 +101,17 @@ class MinikubePlugin(KubernatorPlugin):
99
101
  logger.critical(msg)
100
102
  raise RuntimeError(msg)
101
103
 
104
+ k8s_version_tuple = tuple(map(int, k8s_version.split(".")))
105
+
102
106
  if not minikube_version:
103
107
  minikube_version = self.get_latest_minikube_version()
104
108
  logger.info("No minikube version is specified, latest is %s", minikube_version)
109
+ if k8s_version_tuple < (1, 28, 0):
110
+ logger.info("While latest minikube version is %s, "
111
+ "the requested K8S version %s requires %s or earlier - choosing %s",
112
+ minikube_version, k8s_version, MINIKUBE_MAX_VERSION_LEGACY,
113
+ MINIKUBE_MAX_VERSION_LEGACY)
114
+ minikube_version = MINIKUBE_MAX_VERSION_LEGACY
105
115
 
106
116
  minikube_dl_file, _ = context.app.download_remote_file(logger,
107
117
  f"https://github.com/kubernetes/minikube/releases"
kubernator/proc.py CHANGED
@@ -108,7 +108,7 @@ class ProcessRunner:
108
108
  raise RuntimeError("not available")
109
109
  return self._proc.stdin
110
110
 
111
- def wait(self, fail=True, timeout=None, _out_func=None):
111
+ def wait(self, fail=True, timeout=None, _out_func=None, _stderr_func=None):
112
112
  with Timeout(timeout, TimeoutExpired):
113
113
  retcode = self._proc.wait()
114
114
  if self._stdin_writer:
@@ -119,9 +119,12 @@ class ProcessRunner:
119
119
  self._stderr_reader.join()
120
120
  if fail and retcode:
121
121
  output = None
122
+ stderr = None
122
123
  if _out_func:
123
124
  output = _out_func()
124
- raise CalledProcessError(retcode, self._safe_args, output=output)
125
+ if _stderr_func:
126
+ stderr = _stderr_func()
127
+ raise CalledProcessError(retcode, self._safe_args, output=output, stderr=stderr)
125
128
  return retcode
126
129
 
127
130
  def terminate(self):
@@ -134,6 +137,25 @@ class ProcessRunner:
134
137
  run = ProcessRunner
135
138
 
136
139
 
140
+ def run_pass_through_capturing(args, stdout_logger, stderr_logger, stdin=DEVNULL, *, safe_args=None,
141
+ universal_newlines=True, **kwargs):
142
+ out = StringIO(trimmed=False) if universal_newlines else BytesIO()
143
+ err = StringIO(trimmed=False) if universal_newlines else BytesIO()
144
+
145
+ def write_out(data):
146
+ out.write(data)
147
+ stdout_logger(data)
148
+
149
+ def write_err(data):
150
+ err.write(data)
151
+ stderr_logger(data)
152
+
153
+ proc = run(args, write_out, write_err, stdin, safe_args=safe_args, universal_newlines=universal_newlines,
154
+ **kwargs)
155
+ proc.wait(_out_func=lambda: out.getvalue(), _stderr_func=lambda: err.getvalue())
156
+ return out.getvalue(), err.getvalue()
157
+
158
+
137
159
  def run_capturing_out(args, stderr_logger, stdin=DEVNULL, *, safe_args=None, universal_newlines=True, **kwargs):
138
160
  out = StringIO(trimmed=False) if universal_newlines else BytesIO()
139
161
  proc = run(args, out.write, stderr_logger, stdin, safe_args=safe_args, universal_newlines=universal_newlines,
@@ -1,23 +1,23 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kubernator
3
- Version: 1.0.20.dev20250519050248
3
+ Version: 1.0.21
4
4
  Summary: Kubernator is the a pluggable framework for K8S provisioning
5
5
  Home-page: https://github.com/karellen/kubernator
6
6
  Author: Express Systems USA, Inc.
7
7
  Author-email:
8
8
  Maintainer: Karellen, Inc., Arcadiy Ivanov
9
9
  Maintainer-email: supervisor@karellen.co,arcadiy@karellen.co
10
- License: Apache License, Version 2.0
10
+ License: Apache-2.0
11
11
  Project-URL: Bug Tracker, https://github.com/karellen/kubernator/issues
12
12
  Project-URL: Documentation, https://github.com/karellen/kubernator/
13
13
  Project-URL: Source Code, https://github.com/karellen/kubernator/
14
14
  Keywords: kubernetes k8s kube top provisioning kOps terraform tf AWS
15
- Classifier: License :: OSI Approved :: Apache Software License
16
15
  Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
20
19
  Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
21
  Classifier: Operating System :: MacOS :: MacOS X
22
22
  Classifier: Operating System :: POSIX
23
23
  Classifier: Operating System :: POSIX :: Linux
@@ -45,8 +45,7 @@ Requires-Dist: kubernetes~=32.0
45
45
  Requires-Dist: openapi-schema-validator~=0.1
46
46
  Requires-Dist: openapi-spec-validator~=0.3
47
47
  Requires-Dist: platformdirs~=4.2
48
- Requires-Dist: referencing~=0.36.2
49
- Requires-Dist: requests<=2.31.0
48
+ Requires-Dist: requests>=2.31.0
50
49
  Dynamic: author
51
50
  Dynamic: classifier
52
51
  Dynamic: description
@@ -1,30 +1,30 @@
1
1
  kubernator/LICENSE,sha256=wKKdOCMTCPQRV5gDkVLAsXX8qSnRJ5owk7yWPO1KZNo,11387
2
- kubernator/__init__.py,sha256=e-LUMORChME-9EOp_4V4a5K3yCdpAbzcDwJ1A2CFwQc,933
2
+ kubernator/__init__.py,sha256=_sCRkr5V79fanpMCglRIMGs0rrRkSIuKW8H58GnJ4NY,915
3
3
  kubernator/__main__.py,sha256=f0S60wgpLu--1UlOhzfWail-xt8zyIuODodX98_yPN0,707
4
4
  kubernator/_json_path.py,sha256=pjQKXxgbpQWETYBIrIuJZHgugF92IbEAM19AC7JUmAQ,3162
5
5
  kubernator/_k8s_client_patches.py,sha256=PEeWPInnW38NDyK7G24_Dmw-x7xHpN3vJWZeckdqgK0,76892
6
- kubernator/api.py,sha256=cU_dsS4PcTkRUcQqnRxsaqzeoApjhwRd2-l4CfwFZpU,27201
7
- kubernator/app.py,sha256=ZtQm60Cb1z2SkD338B6nue3wLOo_auRqZRW5ou_-d84,20949
6
+ kubernator/api.py,sha256=R_a22G5bcrm-xl1gP4frIbhnt7i5ksqCS6xiOOA0E0s,29009
7
+ kubernator/app.py,sha256=ETgysPcIKEDsMTbdIw00-enSLip7Z2cECJrRxjf9ciw,21214
8
8
  kubernator/merge.py,sha256=eW5fajnDdI2n8aUqRfTmdG6GWDvDtcVKPKsp3fiB5Nk,5882
9
- kubernator/proc.py,sha256=8YlgbppyHic_51fVTPD7OP8x5yuRuL8j1kThR8MJjNI,5119
9
+ kubernator/proc.py,sha256=43jrpTe1FCdhDIK0b6hnB6XqU_m7iYu3wbzJyzO3pl0,5979
10
10
  kubernator/plugins/__init__.py,sha256=h9TLYK8UFEi53ipZSZsTBjp0ljKhisWsgPpt_PkWrO8,670
11
11
  kubernator/plugins/awscli.py,sha256=S6X7-qFiaZ7NDVDl2Jg0t-ih9KAJ45cUjjzd5Qe93ZM,4252
12
12
  kubernator/plugins/eks.py,sha256=xe7vyPHNwuP8gEYDSzPyBkm-RkAtP64wCOqs9U5I7xI,2273
13
13
  kubernator/plugins/helm.py,sha256=R5hrDDhQ8b5BYYswvxJaM9-KsHKWPBKqHVtTRa1eSuA,11122
14
14
  kubernator/plugins/istio.py,sha256=oERwbVtIk9vMJp_miBXK3-XJKF6SDbh6PPe0p3QIekY,14924
15
- kubernator/plugins/k8s.py,sha256=Zj3q_bUmbOADfjSHy2X0BhgrbXuH-fM8Vq75sYFy0nE,24496
16
- kubernator/plugins/k8s_api.py,sha256=dp4dFHm_ieBTQoRlnEZgiJ6sYGw0CheUt7wEmp-T060,27529
15
+ kubernator/plugins/k8s.py,sha256=g9PwEBE3vEZ-EPi24Bz52K-ZMv0CbEmzD29Wj1WfCLs,24518
16
+ kubernator/plugins/k8s_api.py,sha256=PDa7MB9q3WMm_9tr8T6LY_ojrHpyGYiNTlvBZinbgFY,27379
17
17
  kubernator/plugins/kops.py,sha256=QsrQJUF6wGJo2QRVqP92pG5vmOTYQIc25PD_DWCzrAA,9635
18
18
  kubernator/plugins/kubeconfig.py,sha256=uwtHmF2I6LiTPrC3M88G5SfYxDWtuh0MqcMfrHHoNRA,2178
19
19
  kubernator/plugins/kubectl.py,sha256=IgNghW1Q6s8V2o08eNY2NWfkkdV9Z6X2A3YFQinFr4g,4028
20
- kubernator/plugins/minikube.py,sha256=FFGW8Rkap4CPEydEgxXhIuK3A263khjli0adC5j09MA,10393
20
+ kubernator/plugins/minikube.py,sha256=V7nf6YRi-NRIGMTuf4JvrIUFCQXyjBs3kTBjAk5NDDw,10922
21
21
  kubernator/plugins/template.py,sha256=542nyS4ZNgdwJHEoIA5aLP1d4C312ydd7sPM9ZFbHuI,8357
22
22
  kubernator/plugins/terraform.py,sha256=a1MPl9G8Rznjd28uMRdYWrjpFDLlFAVmLFH4hFEsMsQ,5285
23
23
  kubernator/plugins/terragrunt.py,sha256=-qN8tTqPUXJ9O7CEiJVUB0GSUQU3DUTkv-aWdIIsm7Q,5051
24
- kubernator-1.0.20.dev20250519050248.dist-info/METADATA,sha256=b5etb-yveUpdFoyEevyUYE2w5SHYBlHPp_kQ7XvpueE,10904
25
- kubernator-1.0.20.dev20250519050248.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
26
- kubernator-1.0.20.dev20250519050248.dist-info/entry_points.txt,sha256=IWDtHzyTleRqDSuVRXEr5GImrI7z_kh21t5DWZ8ldcQ,47
27
- kubernator-1.0.20.dev20250519050248.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
28
- kubernator-1.0.20.dev20250519050248.dist-info/top_level.txt,sha256=_z1CxWeKMI55ckf2vC8HqjbCn_E2Y_P5RdrhE_QWcIs,11
29
- kubernator-1.0.20.dev20250519050248.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
30
- kubernator-1.0.20.dev20250519050248.dist-info/RECORD,,
24
+ kubernator-1.0.21.dist-info/METADATA,sha256=Fsv2QRkXZUjlE7oqQWVf5R-Iq_OrJ2vz9xiGrqzrQpg,10822
25
+ kubernator-1.0.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ kubernator-1.0.21.dist-info/entry_points.txt,sha256=IWDtHzyTleRqDSuVRXEr5GImrI7z_kh21t5DWZ8ldcQ,47
27
+ kubernator-1.0.21.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
28
+ kubernator-1.0.21.dist-info/top_level.txt,sha256=_z1CxWeKMI55ckf2vC8HqjbCn_E2Y_P5RdrhE_QWcIs,11
29
+ kubernator-1.0.21.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
30
+ kubernator-1.0.21.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5