Frankkkkk / pykorm

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

Add object relationships #2

Open Frankkkkk opened 4 years ago

Frankkkkk commented 4 years ago

We should add a Relationship field whose role is to reference another resource.

However, how to deal with references to other namespaces ? We could support:

AnyISalIn commented 4 years ago

We need to deal with Relationship Resource CRUD operations.

I have two ideas.

  1. association based on ownerReferences of Kubernetes.
  2. association based on structured annotations

If we adopt the first, Kubernetes will help us deal with garbage collection. but cross-namespace owner references are disallowed.

Frankkkkk commented 4 years ago

Maybe we could have both ? Indeed, ownerReferences are useful, but sometimes soft dependencies (that don't imply parent-child, unlike ownerRef) are also useful. I'm imagining something like:

@pykorm.k8s_custom_object
class Server(pykorm.NamespacedModel):
  pass

@pykorm.k8s_custom_object
class User(pykorm.NamespacedModel):
  # Many-to-one or one-to-one
  server = pykorm.fields.Relationship(field=pykorm.fields.Spec('server'), relationship=Server, lookup_field='name')

In this case, behind the scenes, the user CRD would have their .spec.server field equal to the name of the corresponding CRD in the same namespace.

This is easy when having references in the same namespace (for a Namespaced resource) or for the whole cluster (cluster resource). However we could, at first, disallow inter-namespace references for the sake of clarity.

What do you think ?

Roni1993 commented 2 years ago

Hey @Frankkkkk, i'm currently looking into using pykorm as i've been writing way to much boilerplate for my liking with pykube. this feature would be something i'd be using a lot. My use-case is as following:

as of now i'm just requesting the k8s api & then filtering in my code but it would be nice to use the relationships estabilished in ownerReferences.

i'd like to help with this feature if you can give me some guidance on how to contribute

Frankkkkk commented 2 years ago

Maybe we should decide whether we want lazy loading or not. I'd think that its not a bad idea to load on the fly so we have less "circular" checking to do.

With lazy loading, we could handle the relationship loading on the model's __getattr__. It shouldn't be really hard as we'd have the class, so we can do some querying and return the found (or not) object

On https://github.com/Frankkkkk/pykorm/issues/2#issuecomment-715301548 I thought that sqlalchemy-like relationships sounded neat, but if you've got another idea I'm all for it !

Maybe we could start with many-to-one (or one-to-one as it's the same from the "father" object) relationships ?

Would you like to do a POC MR @Roni1993 and then we can improve on it ?

Cheers

Roni1993 commented 2 years ago

I think lazy loading sounds like a good idea. As in my use case I'm often requesting the CRDs but require the ownerReference relationships only in a few cases. I think i can try to create a MR for these relationships.

Regarding the custom relationships I'm thinking that it might be a good idea to build on a similar approach like the labels are used with service selectors

Labels allow more efficient requests as the k8s API already provides special filters & it would also align with the standard approach. What do you think about this?

danielloader commented 1 year ago

Maybe we could have both ? Indeed, ownerReferences are useful, but sometimes soft dependencies (that don't imply parent-child, unlike ownerRef) are also useful. I'm imagining something like:

@pykorm.k8s_custom_object
class Server(pykorm.NamespacedModel):
  pass

@pykorm.k8s_custom_object
class User(pykorm.NamespacedModel):
  # Many-to-one or one-to-one
  server = pykorm.fields.Relationship(field=pykorm.fields.Spec('server'), relationship=Server, lookup_field='name')

In this case, behind the scenes, the user CRD would have their .spec.server field equal to the name of the corresponding CRD in the same namespace.

This is easy when having references in the same namespace (for a Namespaced resource) or for the whole cluster (cluster resource). However we could, at first, disallow inter-namespace references for the sake of clarity.

What do you think ?

I know it's been a while but this soft dependency pattern has a lot of benefits though I appreciate it doesn't solve all the issues.