Frankkkkk / pykorm

A python 🐍 kubernetes ☸️ ORM 🚀. Very useful when writing operators for your CRDs with Kopf.
MIT License
73 stars 4 forks source link

ListField : allow undefined value if not required #44

Closed hedinasr closed 1 year ago

hedinasr commented 1 year ago

If a ListField attribute is not defined while making a query, you'll get a KeyError exception. As an attribute can be not required, this shouldn't happen.

For example:

class Subject(pykorm.models.Nested):
    kind: str = pykorm.fields.DataField('kind')
    name: str = pykorm.fields.DataField('name')
    namespace: str = pykorm.fields.DataField('namespace')
    apiGroup: str = pykorm.fields.DataField('apiGroup')

class RoleRef(pykorm.models.Nested):
    kind: str = pykorm.fields.DataField('kind')
    name: str = pykorm.fields.DataField('name')
    apiGroup: str = pykorm.fields.DataField('apiGroup')

@pykorm.pykorm.k8s_custom_object('rbac.authorization.k8s.io', 'v1', 'clusterrolebindings')
class ClusterRoleBinding(pykorm.models.ClusterModel):
    roleRef: RoleRef = pykorm.fields.DictNestedField(RoleRef, path=['roleRef'])
    subjects: List[Subject] = pykorm.fields.ListField(Subject, path=['subjects'])

Let's say that in your cluster there is the following ClusterRoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:node
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node

Then when you'll make the following query:

>>> ClusterRoleBinding.query.filter_by(name="system:node").all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/query.py", line 153, in all
    last_ret = self._query(data=last_ret, **_filter.kwargs)
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/query.py", line 143, in _query
    for el in data:
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/query.py", line 296, in _iter
    yield self.baseobject._instantiate_with_dict(obj, queryset=self)
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/models.py", line 46, in _instantiate_with_dict
    obj._set_attributes_with_dict(k8s_dict)
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/models.py", line 55, in _set_attributes_with_dict
    value = attr.get_data(k8s_dict)
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/pykorm/fields.py", line 97, in get_data
    full_items = dpath.util.get(k8s_dict, self.fullpath) or []
  File "/Users/hedinasr/src/operator-project/.direnv/python-3.10.9/lib/python3.10/site-packages/dpath/util.py", line 177, in get
    raise KeyError(glob)
KeyError: ['subjects']

I added a test case that should fail with the exact same error without the patch in the ListField.get_data function.

hedinasr commented 1 year ago

@Frankkkkk ;)

Frankkkkk commented 1 year ago

Woops, sorry Hedi. Merging that tonight :-)

On January 12, 2023 10:27:35 AM GMT+01:00, Hedi Nasr @.***> wrote:

@Frankkkkk ;)

-- Reply to this email directly or view it on GitHub: https://github.com/Frankkkkk/pykorm/pull/44#issuecomment-1380037703 You are receiving this because you were mentioned.

Message ID: @.***>

Frankkkkk commented 1 year ago

Thanks Hedi. 0.60.0 is on pypi. Cheers !