Generic code
While having a specific ZIO module and strictly typed interface for each available Kubernetes resource, sometimes we want to write more generic functions:
- that work on any given resource (maybe regardless of being namespaced or cluster level)
- that work on a given capability for example on any resource having a scale subresource
This section shows the available tools for implementing such functions.
Generic layers
Every resource client module defines an alternative type alias called Generic
.
For example the default Pods
type is defined as the following:
type Pods = Pods.Service
and it's generic version, Pods.Generic
defined in the companion object of Pods
as:
type Generic =
NamespacedResource[Pod]
with NamespacedResourceStatus[PodStatus, Pod]
with NamespacedLogSubresource[Pod]
with NamespacedEvictionSubresource[Pod]
with NamespacedBindingSubresource[Pod]
The pods
layer can be converted to its Generic
representation with .asGeneric
:
import com.coralogix.zio.k8s.client.v1.pods.Pods
import com.coralogix.zio.k8s.client.K8sFailure
val pods: ZLayer[System, Throwable, Pods] = k8sDefault >>> Pods.live
val generic: ZLayer[System, Throwable, Pods.Generic] = pods.map(_.get.asGeneric)
This generic
layer can be provided to generic functions that work with any kind of resource:
import com.coralogix.zio.k8s.client._
import com.coralogix.zio.k8s.client.model.K8sNamespace
import com.coralogix.zio.k8s.client.impl.ResourceClient
import zio._
import zio.Console
def getAndPrint[T : Tag](name: String, namespace: K8sNamespace): ZIO[Console with NamespacedResource[T], K8sFailure, Unit] =
for {
obj <- ResourceClient.namespaced.get(name, namespace)
_ <- Console.printLine(obj.toString).ignore
} yield ()
K8sObject
Not knowing anything about the resource type in these generic functions is very limiting. There are a couple of type classes available implemented by the Kubernetes model classes that can be used in these scenarios.
K8sObject
The K8sObject
type class provides access to the object's metadata, that always have the type ObjectMeta
, and some other
helper functions to get parts of this metadata and to manipulate ownership.
For example the above example can be extended to print the object's UID instead:
import com.coralogix.zio.k8s.client.model.K8sObject
import com.coralogix.zio.k8s.client.model.K8sObject._
def getAndPrintUid[T : Tag : K8sObject](name: String, namespace: K8sNamespace): ZIO[Console with NamespacedResource[T], K8sFailure, Unit] =
for {
obj <- ResourceClient.namespaced.get(name, namespace)
uid <- obj.getUid
_ <- Console.printLine(uid).ignore
} yield ()
K8sObjectStatus
Similarily to K8sObject
, the K8sObjectStatus
type class provides access to the resouce's status subresource. It is parametrized by both the resouce type and the status type:
trait K8sObjectStatus[ResourceT, StatusT]
Resource metadata
Finally each resource model class has an implicit ResourceMetadata
value as well. This can be used to get information about
the underlying resource's group/version/kind.