Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gtsystem/lightkube
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.13.0
Choose a base ref
...
head repository: gtsystem/lightkube
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.14.0
Choose a head ref
  • 5 commits
  • 4 files changed
  • 3 contributors

Commits on Jul 16, 2023

  1. load_from_yaml supports loading *List kinds while from_dict raises wh…

    …en a non-dict is provided
    addyess authored and gtsystem committed Jul 16, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    63c7335 View commit details
  2. back compatability for python 3.7

    addyess authored and gtsystem committed Jul 16, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2f2bcde View commit details
  3. Update lightkube/codecs.py

    Co-authored-by: Giuseppe Tribulato <gtsystem@users.noreply.github.com>
    addyess and gtsystem committed Jul 16, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5152c5a View commit details
  4. address review comment

    addyess authored and gtsystem committed Jul 16, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a30ed35 View commit details
  5. 0.14.0: Version increase

    gtsystem committed Jul 16, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    acc7d8e View commit details
Showing with 112 additions and 12 deletions.
  1. +22 −11 lightkube/codecs.py
  2. +1 −1 setup.py
  3. +84 −0 tests/data/example-def-with-lists.yaml
  4. +5 −0 tests/test_codecs.py
33 changes: 22 additions & 11 deletions lightkube/codecs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import importlib
from typing import Union, TextIO, List
from typing import Union, TextIO, Iterator, List, Mapping

import yaml

@@ -52,6 +52,8 @@ def from_dict(d: dict) -> AnyResource:
* **d** - A dictionary representing a Kubernetes resource. Keys `apiVersion` and `kind` are
always required.
"""
if not isinstance(d, Mapping):
raise LoadResourceError(f"Invalid resource definition, not a dict.")
for attr in REQUIRED_ATTR:
if attr not in d:
raise LoadResourceError(f"Invalid resource definition, key '{attr}' missing.")
@@ -63,7 +65,7 @@ def from_dict(d: dict) -> AnyResource:
def load_all_yaml(stream: Union[str, TextIO], context: dict = None, template_env = None, create_resources_for_crds: bool = False) -> List[AnyResource]:
"""Load kubernetes resource objects defined as YAML. See `from_dict` regarding how resource types are detected.
Returns a list of resource objects or raise a `LoadResourceError`. Skips any empty YAML documents in the
stream, returning an empty list if all YAML documents are empty.
stream, returning an empty list if all YAML documents are empty. Deep parse any items from .*List resources.
**parameters**
@@ -83,15 +85,24 @@ def load_all_yaml(stream: Union[str, TextIO], context: dict = None, template_env
"""
if context is not None:
stream = _template(stream, context=context, template_env=template_env)
resources = []
for obj in yaml.safe_load_all(stream):
if obj is not None:
res = from_dict(obj)
resources.append(res)

if create_resources_for_crds is True and res.kind == "CustomResourceDefinition":
create_resources_from_crd(res)
return resources

def _flatten(objects: Iterator) -> List[AnyResource]:
"""Flatten resources which have a kind = *List."""
resources = []
for obj in objects:
if obj is None:
continue
if isinstance(obj, Mapping) and obj.get("kind", "").endswith("List"):
resources += _flatten(obj.get("items") or [])
else:
res = from_dict(obj)
resources.append(res)

if create_resources_for_crds is True and res.kind == "CustomResourceDefinition":
create_resources_from_crd(res)
return resources

return _flatten(yaml.safe_load_all(stream))


def dump_all_yaml(resources: List[AnyResource], stream: TextIO = None, indent=2):
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

setup(
name='lightkube',
version="0.13.0",
version="0.14.0",
description='Lightweight kubernetes client library',
long_description=Path("README.md").read_text(),
long_description_content_type="text/markdown",
84 changes: 84 additions & 0 deletions tests/data/example-def-with-lists.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: v1
kind: SecretList
items:
- apiVersion: v1
kind: Secret
metadata:
name: "nginxsecret"
namespace: "default"
type: kubernetes.io/tls
data:
tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdW...Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0t"
tls.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURB...TkJnVW1VbGc9Ci0tLS0tRU5EIFBSSVZB"
---
apiVersion: v1
kind: List
items:
- apiVersion: myapp.com/v1
kind: Mydb
metadata:
name: bla
a: xx
b: yy
---
apiVersion: v1
kind: ServiceList
items:
- apiVersion: v1
kind: ServiceList
metadata: {}
items:
- apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: DeploymentList
items:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
- name: configmap-volume
configMap:
name: nginxconfigmap
containers:
- name: nginxhttps
image: bprashanth/nginxhttps:1.0
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
- mountPath: /etc/nginx/conf.d
name: configmap-volume
5 changes: 5 additions & 0 deletions tests/test_codecs.py
Original file line number Diff line number Diff line change
@@ -59,6 +59,10 @@ def test_from_dict():


def test_from_dict_wrong_model():
# provided argument must actually be a dict
with pytest.raises(LoadResourceError, match='.*not a dict'):
codecs.from_dict([])

# apiVersion and kind are required
with pytest.raises(LoadResourceError, match=".*key 'apiVersion' missing"):
codecs.from_dict({
@@ -123,6 +127,7 @@ def test_from_dict_not_found():
(
"example-def.yaml",
"example-def-with-nulls.yaml",
"example-def-with-lists.yaml"
)
)
def test_load_all_yaml_static(yaml_file):