Open tgermain opened 3 months ago
Nice one. I think JsonPatch
is an ok API for this, assuming it works of course :)
The thing is, it does work in typescript:
cdk8s.ApiObject.of(cm).addJsonPatch(cdk8s.JsonPatch.replace('/metadata/labels/set-to-null', null));
In golang, the offending code is the auto generated validations jsii produces:
func validateJsonPatch_AddParameters(path *string, value interface{}) error {
if path == nil {
return fmt.Errorf("parameter path is required, but nil was provided")
}
if value == nil {
return fmt.Errorf("parameter value is required, but nil was provided")
}
return nil
}
This sounds like a generic jsii issue, i'll check and update here.
Thanks for reporting this!
I've tried to make my own version of JsonPatch_Replace
in order to bypass the validation that prevent me from passing nil
as the value of the patch:
package main
import (
"fmt"
"example.com/cdk8s-demo/imports/k8s"
"github.com/aws/jsii-runtime-go"
"github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2"
_jsii_ "github.com/aws/jsii-runtime-go/runtime"
_init_ "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2/jsii"
)
func main() {
app := cdk8s.NewApp(&cdk8s.AppProps{})
chart := cdk8s.NewChart(app, jsii.String("my-chart"), &cdk8s.ChartProps{})
labels := map[string]*string{
"foo": jsii.String("bar"),
"set-to-null": jsii.String(""),
}
cm := k8s.NewKubeConfigMap(chart, jsii.String("my-cm"), &k8s.KubeConfigMapProps{
Metadata: &k8s.ObjectMeta{
Labels: &labels,
}})
var i interface{}
// cm.AddJsonPatch(cdk8s.JsonPatch_Replace(jsii.String("/metadata/labels/set-to-null"), &i))
cm.AddJsonPatch(no_validation_JsonPatch_Replace(jsii.String("/metadata/labels/set-to-null"), &i))
fmt.Println(*app.SynthYaml())
}
func no_validation_JsonPatch_Replace(path *string, value interface{}) cdk8s.JsonPatch {
_init_.Initialize()
var returns cdk8s.JsonPatch
_jsii_.StaticInvoke(
"cdk8s.JsonPatch",
"replace",
[]interface{}{path, value},
&returns,
)
return returns
}
It doesn't break while going through jsii but it produces:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
foo: bar
name: my-chart-my-cm-c841940f
@tgermain I've opened a jsii issue. not much we can do on cdk8s side.
Description of the bug:
I'm using cdk8s with go and I'm having trouble setting some fields to
null
literal.Why do I need to set fields to
null
in the first place?When creating/updating resource using
kubectl apply
, it does a 3 way merge between the existing k8s resource on the cluster and what you want to apply.For instance, if you already have a k8s resource with a
foo: bar
label like:and you want to remove the
foo
label, applying a resource like:is not enough because of the 3 way merge. It will work if you try to apply the same manifest to a brand new k8s cluster but not on one where the
my-cm
configmap already have thefoo
label.A common trick I've used in the past and that was implemented in https://github.com/kubernetes/kubernetes/pull/40630 is to set the field you want to remove to
null
literal:This yaml manifest will remove the
foo
label if it's already present in the existing resource.Reproduction Steps:
This is my test cdk8s app:
It a go module named
example.com/cdk8s-demo/imports/k8s
. Underexample.com/cdk8s-demo/imports/k8s
I've imported k8s api objects usingcdk8s import k8s -l go
.When run using
go run main.go
it produce:Environment:
github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.68.71
Other:
What I have already tried:
Using
"set-to-null": jsii.String(""),
-> it renders an empty string in the yaml (expected).Using
"set-to-null": jsii.String("null"),
-> it renders a"null"
string in the yaml (expected).Using json-patch:
cm.AddJsonPatch(cdk8s.JsonPatch_Replace(jsii.String("/metadata/labels/set-to-null"),"null"))
-> render a"null"
string in yamlcm.AddJsonPatch(cdk8s.JsonPatch_Replace(jsii.String("/metadata/labels/set-to-null"),""))
-> render a""
string in yamlUsing pointer to empty interface:
-> it removes the field completely.
I think a json path like
{"op": "replace","path": "/metadata/labels/set-to-null","value": null}
should work but I think thenull
literal in the json patch is lost at some point when go ---call---> jsii ---call---> typescript.This is :bug: Bug Report