Skip to content

Commit 8483b9c

Browse files
liggittHirazawaUi
authored andcommitted
Prune explicit nulls from client-side apply create
1 parent b85a834 commit 8483b9c

File tree

1 file changed

+33
-4
lines changed
  • staging/src/k8s.io/kubectl/pkg/cmd/apply

1 file changed

+33
-4
lines changed

staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import (
4343
"k8s.io/client-go/util/csaupgrade"
4444
"k8s.io/component-base/version"
4545
"k8s.io/klog/v2"
46-
"k8s.io/kubectl/pkg/cmd/delete"
46+
cmddelete "k8s.io/kubectl/pkg/cmd/delete"
4747
cmdutil "k8s.io/kubectl/pkg/cmd/util"
4848
"k8s.io/kubectl/pkg/scheme"
4949
"k8s.io/kubectl/pkg/util"
@@ -61,7 +61,7 @@ type ApplyFlags struct {
6161
RecordFlags *genericclioptions.RecordFlags
6262
PrintFlags *genericclioptions.PrintFlags
6363

64-
DeleteFlags *delete.DeleteFlags
64+
DeleteFlags *cmddelete.DeleteFlags
6565

6666
FieldManager string
6767
Selector string
@@ -84,7 +84,7 @@ type ApplyOptions struct {
8484
PrintFlags *genericclioptions.PrintFlags
8585
ToPrinter func(string) (printers.ResourcePrinter, error)
8686

87-
DeleteOptions *delete.DeleteOptions
87+
DeleteOptions *cmddelete.DeleteOptions
8888

8989
ServerSideApply bool
9090
ForceConflicts bool
@@ -182,7 +182,7 @@ var ApplySetToolVersion = version.Get().GitVersion
182182
func NewApplyFlags(streams genericiooptions.IOStreams) *ApplyFlags {
183183
return &ApplyFlags{
184184
RecordFlags: genericclioptions.NewRecordFlags(),
185-
DeleteFlags: delete.NewDeleteFlags("The files that contain the configurations to apply."),
185+
DeleteFlags: cmddelete.NewDeleteFlags("The files that contain the configurations to apply."),
186186
PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme),
187187

188188
Overwrite: true,
@@ -681,6 +681,12 @@ See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts`
681681
return cmdutil.AddSourceToErr("creating", info.Source, err)
682682
}
683683

684+
// prune nulls when client-side apply does a create to match what will happen when client-side applying an update.
685+
// do this after CreateApplyAnnotation so the annotation matches what will be persisted on an update apply of the same manifest.
686+
if u, ok := info.Object.(runtime.Unstructured); ok {
687+
pruneNullsFromMap(u.UnstructuredContent())
688+
}
689+
684690
if o.DryRunStrategy != cmdutil.DryRunClient {
685691
// Then create the resource and skip the three-way merge
686692
obj, err := helper.Create(info.Namespace, true, info.Object)
@@ -759,6 +765,29 @@ See https://kubernetes.io/docs/reference/using-api/server-side-apply/#conflicts`
759765
return nil
760766
}
761767

768+
func pruneNullsFromMap(data map[string]interface{}) {
769+
for k, v := range data {
770+
if v == nil {
771+
delete(data, k)
772+
} else {
773+
pruneNulls(v)
774+
}
775+
}
776+
}
777+
func pruneNullsFromSlice(data []interface{}) {
778+
for _, v := range data {
779+
pruneNulls(v)
780+
}
781+
}
782+
func pruneNulls(v interface{}) {
783+
switch v := v.(type) {
784+
case map[string]interface{}:
785+
pruneNullsFromMap(v)
786+
case []interface{}:
787+
pruneNullsFromSlice(v)
788+
}
789+
}
790+
762791
// Saves the last-applied-configuration annotation in a separate SSA field manager
763792
// to prevent it from being dropped by users who have transitioned to SSA.
764793
//

0 commit comments

Comments
 (0)