SwiftkubeModel is a zero-dependency Swift package for Kubernetes API objects.
Model structs for all Kubernetes objects
Codable support
Hashable resources
Closure-based builders for convenient object composition
Type-erased wrappers for Kubernetes resources
UnstructuredResource type for handling any Kubernetes resource
Compatibility Matrix
<1.18.9
1.18.9 - 1.18.13
1.19.8
1.20.9
1.22.7
1.24.8
1.24.10
1.25.9
1.26.4
0.2.x
-
✓
-
-
-
-
-
-
-
0.3.x
-
-
✓
-
-
-
-
-
-
0.4.x
-
-
-
✓
-
-
-
-
-
0.5.x
-
-
-
-
✓
-
-
-
-
0.6.x
-
-
-
-
-
✓
-
-
-
0.7.x
-
-
-
-
-
✓
-
-
-
0.8.x
-
-
-
-
-
-
✓
-
-
0.9.x
-
-
-
-
-
-
-
✓
-
0.10.x
-
-
-
-
-
-
-
-
✓
0.11.x
-
-
-
-
-
-
-
-
✓
✓ Exact match of API objects in both model and the Kubernetes version.
- API objects mismatches either due to the removal of old API or the addition of new API. However, everything the
model and Kubernetes have in common will work.
Usage
To use the Kubernetes objects just import SwiftkubeModel:
import SwiftkubeModel
let metadata = meta.v1.ObjectMatadata(name: "swiftkube")
let pod = core.v1.Pod(metadata: metadata)
All the objects are namespaced according to their API group and version, e.g. apps.v1.Deployment or
networking.v1beta1.Ingress. Which means, that for example rbac.v1.Role and rbac.v1beta1.Role are completely
different objects.
Examples
Any Kubernetes object can be constructed directly using the model structs. Here is an example for a Deployment manifest:
From the above example it is clear, that a certain knowledge of all the subtypes and their API groups is required, in
order to comose a complete manifest. Furthermore, Swift doesn’t allow arbitrary arguments order.
For this purpose SwiftkubeModel provides simple closure-based builder functions for convenience. All these functions
reside under the sk namespace.
The syntax is not yet finalized and can break many times before v1.0.0 ships. This can also be replaced
with Function/Result Builders, which is currently a WIP.
SwiftkubeModel currently provides convenience builders only for the most common Kubernetes objects.
let container: core.v1.Container = ...
let volume: core.v1.Volume = ...
// mount a volume in a container
container.mount(volume: volume, on: "/data")
container.mount(volume: "dataVolume", on: "/data")
Populating a Secret: the values are Base64-encoded automatically
let secret: core.v1.Secret = sk.secret(name: "test")
// populate the secret
configMap.add(data: "stuff", forKey: "foo")
configMap.add(file: URL(fileURLWithPath: "/some/path"), forKey: "foo")
core.v1.Service
Server ports on a service
let service: core.v1.Service = ...
// add a service port entry
service.serve(port: 8080, targetPort: 80)
core.v1.ServiceAccount
Use secrets
let serviceAccount: core.v1.ServiceAccount = ...
// add an object reference for a secret
serviceAccount.use(imagePullSecret: "pullSecret")
serviceAccount.use(secret: "secret", namespace: "ns")
apps.v1.Deployment
Exposing a Deployment
let deployment: apps.v1.Deployment = ...
// expose a deployment instance to create a service
let service = deployment.expose(on: 8080, type: .clusterIP)
Type-erasure
Often when working with Kubernetes the concrete type of the resource is not known or not relevant, e.g. when creating
resources from a YAML manifest file. Other times the type or kind of the resource must be derived at runtime given its
string representation.
SwiftkubeModel provides a type-erased resource implementation UnstructuredResource and its corresponding
List-Type UnstructuredResourceList in order to tackle these use-cases.
UnstruturedResource allows objects that do not have registered KubernetesAPIResources to be manipulated generically.
This can be used to deal with the API objects from a plug-in or CRDs.
Here are some examples to clarify their purpose:
// Given a JSON string, e.g. at runtime, containing some Kubernetes resource
let json = """
{
"apiVersion": "stable.example.com/v1",
"kind": "CronTab",
"metadata": {
"name": "my-new-cron-object",
"namespace": "default"
},
"spec": {
"cronSpec": "* * * * */5",
"image": "my-awesome-cron-image"
}
}
"""
// We can still decode it without knowing the concrete type
let data = str.data(using: .utf8)!
let resource = try? JSONDecoder().decode(UnstructuredResource.self, from: data)
// When encoding the previous instance, it serializes the underlying resource
let encoded = try? JSONEncoder().encode(resource)
The UnstruturedResource exposes its internal dictionary representation and also provides a dynamic subscript support:
let json = """
{
"apiVersion": "stable.example.com/v1",
"kind": "CronTab",
"metadata": {
"name": "my-new-cron-object",
"namespace": "default"
},
"spec": {
"cronSpec": "* * * * */5",
"image": "my-awesome-cron-image"
}
}
"""
let data = str.data(using: .utf8)!
let cron = try? JSONDecoder().decode(UnstructuredResource.self, from: data)
// Shortcut vars
print(cron.apiVersion)
print(cron.kind)
print(cron.metadata)
// The internal Dictionary<String: Any> representation
print(cron.properties)
// Dynamic member lookup
let spec: [String: Any]? = cron.spec
print(spec?["cronSpec"])
Installation
To use the SwiftkubeModel in a SwiftPM project, add the following line to the dependencies in your Package.swift file:
Table of contents
Overview
SwiftkubeModel
is a zero-dependency Swift package for Kubernetes API objects.Codable
supportHashable
resourcesUnstructuredResource
type for handling any Kubernetes resourceCompatibility Matrix
0.2.x
0.3.x
0.4.x
0.5.x
0.6.x
0.7.x
0.8.x
0.9.x
0.10.x
0.11.x
✓
Exact match of API objects in both model and the Kubernetes version.-
API objects mismatches either due to the removal of old API or the addition of new API. However, everything theUsage
To use the Kubernetes objects just import
SwiftkubeModel
:All the objects are namespaced according to their API group and version, e.g.
apps.v1.Deployment
ornetworking.v1beta1.Ingress
. Which means, that for examplerbac.v1.Role
andrbac.v1beta1.Role
are completely different objects.Examples
Any Kubernetes object can be constructed directly using the model structs. Here is an example for a
Deployment
manifest:Here is a
ConfigMap
:A more complete example of a
Deployment
, that definesProbes
,ResourceRequirements
,Volumes
andVolumeMounts
would look something like this:Builders
From the above example it is clear, that a certain knowledge of all the subtypes and their API groups is required, in order to comose a complete manifest. Furthermore, Swift doesn’t allow arbitrary arguments order.
For this purpose
SwiftkubeModel
provides simple closure-based builder functions for convenience. All these functions reside under thesk
namespace.The above example would look like this:
Extensions
In addition to closure-based builders,
SwiftkubeModel
extends the Model objects with some convenience functions, inspired by cdk8score.v1.ConfigMap
ConfigMap
core.v1.Container
core.v1.Namespace
core.v1.Secret
Secret
: the values are Base64-encoded automaticallycore.v1.Service
core.v1.ServiceAccount
apps.v1.Deployment
Deployment
Type-erasure
Often when working with Kubernetes the concrete type of the resource is not known or not relevant, e.g. when creating resources from a YAML manifest file. Other times the type or kind of the resource must be derived at runtime given its string representation.
SwiftkubeModel
provides a type-erased resource implementationUnstructuredResource
and its corresponding List-TypeUnstructuredResourceList
in order to tackle these use-cases.UnstruturedResource
allows objects that do not have registeredKubernetesAPIResource
s to be manipulated generically. This can be used to deal with the API objects from a plug-in or CRDs.Here are some examples to clarify their purpose:
The
UnstruturedResource
exposes its internal dictionary representation and also provides a dynamic subscript support:Installation
To use the
SwiftkubeModel
in a SwiftPM project, add the following line to the dependencies in yourPackage.swift
file:then include it as a dependency in your target:
Then run
swift build
.License
Swiftkube project is licensed under version 2.0 of the Apache License. See LICENSE for more details.