PATCH API
This is to open a discussion on how to support PATCH API. Are there already some thoughts / ideas how this could work? The k8s API supports both JSON Patch and JSON Merge Patch requests.
@t089 Hey there, take a look at this, any feedback is much appreciated!!
I have a draft implementation for (Strategic) Merge Patch, which I tried to make type-safe.
It would look like this:
// Construct an instance of some resource, e.g. a Deployment
// Populate only fields that should be patched
let deployment = apps.v1.Deployment(
spec: apps.v1.DeploymentSpec(
replicas: 2,
selector: meta.v1.LabelSelector(),
template: core.v1.PodTemplateSpec(
spec: core.v1.PodSpec(
containers: [
core.v1.Container(
image: "nginx",
name: "patch-demo"
)
]
)
)
)
)
// Create an instance of MergePatch
let patch: MergePatch = deployment.mergePatch()!
// OR
// Create an instance of Strategic MergePatch
let patch: MergePatch = deployment.strategicMergePatch()!
// Patch the resource
let patched = try! await client.appsV1.deployments.patch(in: .default, resource: "some-deployment", patch)
The MergePatch instance above would contain only non-nil and non-empty fields of the resource and would be serialised to the following JSON:
{
"apiVersion": "apps/v1"
"kind": "Deployment"
"spec": {
"replicas": 2,
"template": {
"spec": {
"containers": [
{
"name": "patch-demo",
"image": "nginx"
}
]
}
}
}
}
PS: apiVersion and kind are ignored by the API Server.
A MergePatch instance can also be loaded from a YAML file:
let patch = try MergePatch.load(contentsOf: "/some/path/to/manifest.yaml")
Sounds interesting. Of course, this only works if the structs have only optional fields. Is this currently the case?
How would you "nil-out" a value? Is this even a thing?
Eg, if you want to remove only the annotation with name "xyz" what would you do? The patch should look like this, shouldn't it?
{
"meta": {
"annotations": {
"xyz": null
}
}
}