@@ -36,17 +36,33 @@ type CustomDefaulter interface {
3636 Default (ctx context.Context , obj runtime.Object ) error
3737}
3838
39+ type defaulterOptions struct {
40+ preserveUnknownFields bool
41+ }
42+
43+ type defaulterOption func (* defaulterOptions )
44+
45+ // DefaulterPreserveUnknownFields stops the defaulter from pruning the fields that are not recognized in the local scheme.
46+ func DefaulterPreserveUnknownFields (o * defaulterOptions ) {
47+ o .preserveUnknownFields = true
48+ }
49+
3950// WithCustomDefaulter creates a new Webhook for a CustomDefaulter interface.
40- func WithCustomDefaulter (scheme * runtime.Scheme , obj runtime.Object , defaulter CustomDefaulter ) * Webhook {
51+ func WithCustomDefaulter (scheme * runtime.Scheme , obj runtime.Object , defaulter CustomDefaulter , opts ... defaulterOption ) * Webhook {
52+ options := & defaulterOptions {}
53+ for _ , o := range opts {
54+ o (options )
55+ }
4156 return & Webhook {
42- Handler : & defaulterForType {object : obj , defaulter : defaulter , decoder : NewDecoder (scheme )},
57+ Handler : & defaulterForType {object : obj , defaulter : defaulter , decoder : NewDecoder (scheme ), preserveUnknownFields : options . preserveUnknownFields },
4358 }
4459}
4560
4661type defaulterForType struct {
47- defaulter CustomDefaulter
48- object runtime.Object
49- decoder Decoder
62+ defaulter CustomDefaulter
63+ object runtime.Object
64+ decoder Decoder
65+ preserveUnknownFields bool
5066}
5167
5268// Handle handles admission requests.
@@ -79,8 +95,11 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
7995 return Errored (http .StatusBadRequest , err )
8096 }
8197
82- // Keep a copy of the object
83- originalObj := obj .DeepCopyObject ()
98+ // Keep a copy of the object if needed
99+ var originalObj runtime.Object
100+ if h .preserveUnknownFields {
101+ originalObj = obj .DeepCopyObject ()
102+ }
84103
85104 // Default the object
86105 if err := h .defaulter .Default (ctx , obj ); err != nil {
@@ -96,9 +115,12 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
96115 if err != nil {
97116 return Errored (http .StatusInternalServerError , err )
98117 }
99- handlerResponse := PatchResponseFromRaw (req .Object .Raw , marshalled )
100118
101- return h .dropSchemeRemovals (handlerResponse , originalObj , req .Object .Raw )
119+ handlerResponse := PatchResponseFromRaw (req .Object .Raw , marshalled )
120+ if h .preserveUnknownFields {
121+ handlerResponse = h .dropSchemeRemovals (handlerResponse , originalObj , req .Object .Raw )
122+ }
123+ return handlerResponse
102124}
103125
104126func (h * defaulterForType ) dropSchemeRemovals (r Response , original runtime.Object , raw []byte ) Response {
0 commit comments