Skip to content

Commit

Permalink
OK, found where we were properly handling the case in the Probe class…
Browse files Browse the repository at this point in the history
… where K8s passes us a field named _exec and we map it to exec. This is now in and tests have been added. Also, it seems that pytest has left nose behind, so we're maxing pytest at 7.3.1 for now as otherwise there will be a huge number of edits of tests required to make them all fully pytest compliant.
  • Loading branch information
haxsaw committed Apr 15, 2024
1 parent a6f743a commit bb89e0d
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README-core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
|logo|


Version 1.1.1
Version 1.1.2

|travis| |license| |versions| |coverage|

Expand Down
7 changes: 5 additions & 2 deletions hikaru/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class provides all of the machinery for working with the both Python and YAML:
from dataclasses import fields, dataclass, is_dataclass, InitVar
from inspect import signature, Parameter
from collections import defaultdict, namedtuple
from hikaru.tweaks import h2kc_translate

import hikaru
from hikaru.tweaks import h2kc_translate, h2kc_get_translator
from hikaru.utils import get_origin, get_args, field_metadata_domain


Expand Down Expand Up @@ -984,9 +986,10 @@ class instances that mirror the structure and contents of the YAML,
f"value = {yaml}") # pragma: no cover
yaml = new
hints = self._get_hints()
translator = h2kc_get_translator(self.__class__)
for f in fields(self.__class__):
k8s_name = f.name.strip("_")
k8s_name = (h2kc_translate(self.__class__, k8s_name)
k8s_name = (translator(k8s_name)
if translate
else k8s_name)
is_required = True
Expand Down
23 changes: 21 additions & 2 deletions hikaru/tweaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ def h2kc_translate(cls, fieldname: str) -> str:
return super(_DaemonEndpointTranslator, cls).h2kc_translate(fieldname)


@_register_translator("Probe")
class _ProbeTranslator(_BaseTranslator):
@classmethod
def h2kc_translate(cls, fieldname:str) -> str:
# OK, in this case the openapi spec file has 'exec' as the field
# name in the definition JSON, but when this is read from the cluster
# it is supplied to us as "_exec". So in this case, we have to detect
# when we want Probe's 'exec' as defined in the API spec we actually
# want _exec as it comes from the cluster.
if fieldname == 'exec':
return "_exec"
else:
return super(_ProbeTranslator, cls).h2kc_translate(fieldname)


def h2kc_get_translator(target_cls: type):
return _translation_register.get(target_cls.__name__, _BaseTranslator).h2kc_translate


def h2kc_translate(target_cls: type, fieldname: str) -> str:
xlator = _translation_register.get(target_cls.__name__, _BaseTranslator)
return xlator.h2kc_translate(fieldname)
xlator = h2kc_get_translator(target_cls)
return xlator(fieldname)
2 changes: 1 addition & 1 deletion maintainers_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Pygments>=2.8.1
Sphinx>=3.5.2
pytest>=6.2.2
pytest<=7.3.1
pytest-cov>=2.11.1
13 changes: 13 additions & 0 deletions release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
Release Notes
*************

hikaru-core v1.1.2
------------------

This patch fixes a problem with Probe, which are refereced by PodSpecs among other objects.
A field in the Probe object as it is provided from the cluster to Hikaru via the K8s libraries
doesn't match how it is specified in the OpenAPI schema. In the schema, Probe has a field called
'exec', however when it comes up from the K8s libraries it is '_exec'. It isn't clear if this
reflects how it comes out of the cluster or is a name mapping done in the Python K8s libraries
to avoid colliding with the Python 2 reserved work 'exec', but regardless this value didn't match
what Hikaru was expected. There are a couple of fields like this and Hikaru has a mapping facility
to catch these when they come from K8s, so this field in Probe has been added. Probes should now be
properly read from the cluster.

hikaru-core v1.1.1
------------------

Expand Down
2 changes: 1 addition & 1 deletion setup-core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import setup

__version__ = "1.1.1"
__version__ = "1.1.2"


def get_long_desc():
Expand Down
12 changes: 11 additions & 1 deletion tests/basic_tests_rel_1_25.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from hikaru.meta import DiffDetail, DiffType
from hikaru.naming import make_swagger_name, process_swagger_name
from hikaru.version_kind import get_version_kind_class
from hikaru.tweaks import h2kc_get_translator, h2kc_translate


set_default_release('rel_1_25')
Expand All @@ -52,7 +53,7 @@ def test001():
"""
get the basic machinery creaking to life
"""
assert isinstance(p, Pod)
assert isinstance(p, Pod), f"p is a {p}"
assert p.metadata.name == "hello-kiamol-3", p.metadata.name


Expand Down Expand Up @@ -1657,6 +1658,15 @@ def test143():
assert 'key_2' in m2.labels


def test_issue_39():
"""
Issue 39: Ensure that the key '_exec' from K8s gets turned into 'exec'
"""
xlator = h2kc_get_translator(Probe)
assert '_exec' == xlator('exec')
assert '_exec' == h2kc_translate(Probe, 'exec')


if __name__ == "__main__":
setup()
the_tests = {k: v for k, v in globals().items()
Expand Down
10 changes: 10 additions & 0 deletions tests/basic_tests_rel_1_26.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from hikaru.meta import DiffDetail, DiffType
from hikaru.naming import make_swagger_name, process_swagger_name
from hikaru.version_kind import get_version_kind_class
from hikaru.tweaks import h2kc_translate, h2kc_get_translator


set_default_release('rel_1_26')
Expand Down Expand Up @@ -1657,6 +1658,15 @@ def test143():
assert 'key_2' in m2.labels


def test_issue_39():
"""
Issue 39: Ensure that the key '_exec' from K8s gets turned into 'exec'
"""
xlator = h2kc_get_translator(Probe)
assert '_exec' == xlator('exec')
assert '_exec' == h2kc_translate(Probe, 'exec')


if __name__ == "__main__":
setup()
the_tests = {k: v for k, v in globals().items()
Expand Down
10 changes: 10 additions & 0 deletions tests/basic_tests_rel_1_27.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from hikaru.meta import DiffDetail, DiffType
from hikaru.naming import make_swagger_name, process_swagger_name
from hikaru.version_kind import get_version_kind_class
from hikaru.tweaks import h2kc_get_translator, h2kc_translate


set_default_release('rel_1_27')
Expand Down Expand Up @@ -1657,6 +1658,15 @@ def test143():
assert 'key_2' in m2.labels


def test_issue_39():
"""
Issue 39: Ensure that the key '_exec' from K8s gets turned into 'exec'
"""
xlator = h2kc_get_translator(Probe)
assert '_exec' == xlator('exec')
assert '_exec' == h2kc_translate(Probe, 'exec')


if __name__ == "__main__":
setup()
the_tests = {k: v for k, v in globals().items()
Expand Down
10 changes: 10 additions & 0 deletions tests/basic_tests_rel_1_28.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from hikaru.meta import DiffDetail, DiffType
from hikaru.naming import make_swagger_name, process_swagger_name
from hikaru.version_kind import get_version_kind_class
from hikaru.tweaks import h2kc_translate,h2kc_get_translator


set_default_release('rel_1_28')
Expand Down Expand Up @@ -1657,6 +1658,15 @@ def test143():
assert 'key_2' in m2.labels


def test_issue_39():
"""
Issue 39: Ensure that the key '_exec' from K8s gets turned into 'exec'
"""
xlator = h2kc_get_translator(Probe)
assert '_exec' == xlator('exec')
assert '_exec' == h2kc_translate(Probe, 'exec')


if __name__ == "__main__":
setup()
the_tests = {k: v for k, v in globals().items()
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e/integration_rel_1_25.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ def test02a():
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test_issue_39():
"""
Github issue #39: ensure that a livenessProbe is read back after creation
"""
path = base_path / "core-pod.yaml"
p: Pod = cast(Pod, load_full_yaml(path=str(path))[0])
p.metadata.name += '-issue39'
probe = Probe(exec=ExecAction(command=["/bin/sleep", '1']), periodSeconds=60)
p.spec.containers[0].livenessProbe = probe
res = p.createNamespacedPod(e2e_namespace)
try:
res = Pod.readNamespacedPod(p.metadata.name, e2e_namespace)
assert res.obj and isinstance(res.obj, Pod)
p1: Pod = res.obj
assert isinstance(p1.spec.containers[0].livenessProbe, Probe)
assert p1.spec.containers[0].livenessProbe.exec.command[0] == "/bin/sleep"
finally:
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test03():
"""
Create, read, and delete a Service
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e/integration_rel_1_26.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ def test02a():
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test_issue_39():
"""
Github issue #39: ensure that a livenessProbe is read back after creation
"""
path = base_path / "core-pod.yaml"
p: Pod = cast(Pod, load_full_yaml(path=str(path))[0])
p.metadata.name += '-issue39'
probe = Probe(exec=ExecAction(command=["/bin/sleep", '1']), periodSeconds=60)
p.spec.containers[0].livenessProbe = probe
res = p.createNamespacedPod(e2e_namespace)
try:
res = Pod.readNamespacedPod(p.metadata.name, e2e_namespace)
assert res.obj and isinstance(res.obj, Pod)
p1: Pod = res.obj
assert isinstance(p1.spec.containers[0].livenessProbe, Probe)
assert p1.spec.containers[0].livenessProbe.exec.command[0] == "/bin/sleep"
finally:
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test03():
"""
Create, read, and delete a Service
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e/integration_rel_1_27.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ def test02a():
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test_issue_39():
"""
Github issue #39: ensure that a livenessProbe is read back after creation
"""
path = base_path / "core-pod.yaml"
p: Pod = cast(Pod, load_full_yaml(path=str(path))[0])
p.metadata.name += '-issue39'
probe = Probe(exec=ExecAction(command=["/bin/sleep", '1']), periodSeconds=60)
p.spec.containers[0].livenessProbe = probe
res = p.createNamespacedPod(e2e_namespace)
try:
res = Pod.readNamespacedPod(p.metadata.name, e2e_namespace)
assert res.obj and isinstance(res.obj, Pod)
p1: Pod = res.obj
assert isinstance(p1.spec.containers[0].livenessProbe, Probe)
assert p1.spec.containers[0].livenessProbe.exec.command[0] == "/bin/sleep"
finally:
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test03():
"""
Create, read, and delete a Service
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e/integration_rel_1_28.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ def test02a():
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test_issue_39():
"""
Github issue #39: ensure that a livenessProbe is read back after creation
"""
path = base_path / "core-pod.yaml"
p: Pod = cast(Pod, load_full_yaml(path=str(path))[0])
p.metadata.name += '-issue39'
probe = Probe(exec=ExecAction(command=["/bin/sleep", '1']), periodSeconds=60)
p.spec.containers[0].livenessProbe = probe
res = p.createNamespacedPod(e2e_namespace)
try:
res = Pod.readNamespacedPod(p.metadata.name, e2e_namespace)
assert res.obj and isinstance(res.obj, Pod)
p1: Pod = res.obj
assert isinstance(p1.spec.containers[0].livenessProbe, Probe)
assert p1.spec.containers[0].livenessProbe.exec.command[0] == "/bin/sleep"
finally:
_ = Pod.deleteNamespacedPod(p.metadata.name, e2e_namespace)


def test03():
"""
Create, read, and delete a Service
Expand Down

0 comments on commit bb89e0d

Please sign in to comment.