Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions kubecrd/schemabase.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import json

import re
import kubernetes
import yaml
from apischema import serialize
from apischema.json_schema import deserialization_schema
from kubernetes import utils
from kubernetes.client.models.v1_object_meta import V1ObjectMeta
from uuid import uuid4 as uuid

# ObjectMeta_attribute_map is simply the reverse of the
# V1ObjectMeta.attribute_map , which is a mapping from python attribute to json
Expand All @@ -16,6 +17,10 @@
}


def convert_to_1123(input):
return re.sub(r'[^a-zA-Z0-9]+', '-', input).lower()


class KubeResourceBase:
"""KubeResourceBase is base class that provides methods to converts dataclass
into Kubernetes CR. It provides ability to create a Kubernetes CRD from the
Expand Down Expand Up @@ -199,22 +204,31 @@ async def async_watch(cls, k8s_client):
obj = cls.from_json(event['object'])
yield (event['type'], obj)

def spec_json(self):
return serialize(self)

def serialize(self, name_prefix=None):
"""Serialize the CR as a JSON suitable for POST'ing to K8s API."""
if name_prefix is None:
name_prefix = self.__class__.__name__.lower()
# use class property name as metadata.name
# if not exist, use class name with uuid
if hasattr(self, "name"):
metadata_name = convert_to_1123(self.name)
else:
if name_prefix is None:
name_prefix = self.__class__.__name__.lower()
metadata_name = convert_to_1123(name_prefix + "-" + str(uuid()))

return {
'kind': self.__class__.__name__,
'apiVersion': f'{self.__group__}/{self.__version__}',
'spec': serialize(self),
'spec': self.spec_json(),
'metadata': {
'name': (name_prefix + str(id(self))).lower(),
'name': metadata_name,
},
}

def save(self, k8s_client, namespace='default'):
"""Save the instance of this class as a K8s custom resource."""
def create(self, k8s_client, namespace='default'):
"""Use the instance create a K8s custom resource."""
api_instance = kubernetes.client.CustomObjectsApi(k8s_client)
resp = api_instance.create_namespaced_custom_object(
group=self.__group__,
Expand All @@ -225,6 +239,19 @@ def save(self, k8s_client, namespace='default'):
)
return resp

def patch(self, k8s_client, namespace='default'):
"""Use the instance patch a exists K8s custom resource."""
api_instance = kubernetes.client.CustomObjectsApi(k8s_client)
resp = api_instance.patch_namespaced_custom_object(
group=self.__group__,
namespace=namespace,
version=self.__version__,
plural=self.plural(),
name=self.metadata.name,
body={"spec": self.spec_json()},
)
return resp

async def async_save(self, k8s_client, namespace='default'):
"""Save the instance of this class as a K8s custom resource."""
from kubernetes_asyncio import client
Expand Down