@@ -67,18 +67,19 @@ type Manager interface {
67
67
// FieldManager updates the managed fields and merge applied
68
68
// configurations.
69
69
type FieldManager struct {
70
- fieldManager Manager
70
+ fieldManager Manager
71
+ ignoreManagedFieldsFromRequestObject bool
71
72
}
72
73
73
74
// NewFieldManager creates a new FieldManager that decodes, manages, then re-encodes managedFields
74
75
// on update and apply requests.
75
- func NewFieldManager (f Manager ) * FieldManager {
76
- return & FieldManager {f }
76
+ func NewFieldManager (f Manager , ignoreManagedFieldsFromRequestObject bool ) * FieldManager {
77
+ return & FieldManager {fieldManager : f , ignoreManagedFieldsFromRequestObject : ignoreManagedFieldsFromRequestObject }
77
78
}
78
79
79
80
// NewDefaultFieldManager creates a new FieldManager that merges apply requests
80
81
// and update managed fields for other types of requests.
81
- func NewDefaultFieldManager (models openapiproto.Models , objectConverter runtime.ObjectConvertor , objectDefaulter runtime.ObjectDefaulter , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind , hub schema.GroupVersion ) (* FieldManager , error ) {
82
+ func NewDefaultFieldManager (models openapiproto.Models , objectConverter runtime.ObjectConvertor , objectDefaulter runtime.ObjectDefaulter , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind , hub schema.GroupVersion , ignoreManagedFieldsFromRequestObject bool ) (* FieldManager , error ) {
82
83
typeConverter , err := internal .NewTypeConverter (models , false )
83
84
if err != nil {
84
85
return nil , err
@@ -88,13 +89,13 @@ func NewDefaultFieldManager(models openapiproto.Models, objectConverter runtime.
88
89
if err != nil {
89
90
return nil , fmt .Errorf ("failed to create field manager: %v" , err )
90
91
}
91
- return newDefaultFieldManager (f , typeConverter , objectConverter , objectCreater , kind ), nil
92
+ return newDefaultFieldManager (f , typeConverter , objectConverter , objectCreater , kind , ignoreManagedFieldsFromRequestObject ), nil
92
93
}
93
94
94
95
// NewDefaultCRDFieldManager creates a new FieldManager specifically for
95
96
// CRDs. This allows for the possibility of fields which are not defined
96
97
// in models, as well as having no models defined at all.
97
- func NewDefaultCRDFieldManager (models openapiproto.Models , objectConverter runtime.ObjectConvertor , objectDefaulter runtime.ObjectDefaulter , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind , hub schema.GroupVersion , preserveUnknownFields bool ) (_ * FieldManager , err error ) {
98
+ func NewDefaultCRDFieldManager (models openapiproto.Models , objectConverter runtime.ObjectConvertor , objectDefaulter runtime.ObjectDefaulter , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind , hub schema.GroupVersion , preserveUnknownFields , ignoreManagedFieldsFromRequestObject bool ) (_ * FieldManager , err error ) {
98
99
var typeConverter internal.TypeConverter = internal.DeducedTypeConverter {}
99
100
if models != nil {
100
101
typeConverter , err = internal .NewTypeConverter (models , preserveUnknownFields )
@@ -106,11 +107,11 @@ func NewDefaultCRDFieldManager(models openapiproto.Models, objectConverter runti
106
107
if err != nil {
107
108
return nil , fmt .Errorf ("failed to create field manager: %v" , err )
108
109
}
109
- return newDefaultFieldManager (f , typeConverter , objectConverter , objectCreater , kind ), nil
110
+ return newDefaultFieldManager (f , typeConverter , objectConverter , objectCreater , kind , ignoreManagedFieldsFromRequestObject ), nil
110
111
}
111
112
112
113
// newDefaultFieldManager is a helper function which wraps a Manager with certain default logic.
113
- func newDefaultFieldManager (f Manager , typeConverter internal.TypeConverter , objectConverter runtime.ObjectConvertor , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind ) * FieldManager {
114
+ func newDefaultFieldManager (f Manager , typeConverter internal.TypeConverter , objectConverter runtime.ObjectConvertor , objectCreater runtime.ObjectCreater , kind schema.GroupVersionKind , ignoreManagedFieldsFromRequestObject bool ) * FieldManager {
114
115
f = NewStripMetaManager (f )
115
116
f = NewManagedFieldsUpdater (f )
116
117
f = NewBuildManagerInfoManager (f , kind .GroupVersion ())
@@ -119,36 +120,59 @@ func newDefaultFieldManager(f Manager, typeConverter internal.TypeConverter, obj
119
120
f = NewLastAppliedManager (f , typeConverter , objectConverter , kind .GroupVersion ())
120
121
f = NewLastAppliedUpdater (f )
121
122
122
- return NewFieldManager (f )
123
+ return NewFieldManager (f , ignoreManagedFieldsFromRequestObject )
123
124
}
124
125
125
- // Update is used when the object has already been merged (non-apply
126
- // use-case), and simply updates the managed fields in the output
127
- // object.
128
- func (f * FieldManager ) Update (liveObj , newObj runtime.Object , manager string ) (object runtime.Object , err error ) {
126
+ func decodeLiveManagedFields (liveObj runtime.Object ) (Managed , error ) {
127
+ liveAccessor , err := meta .Accessor (liveObj )
128
+ if err != nil {
129
+ return nil , err
130
+ }
131
+ managed , err := internal .DecodeObjectManagedFields (liveAccessor .GetManagedFields ())
132
+ if err != nil {
133
+ return internal .NewEmptyManaged (), nil
134
+ }
135
+ return managed , nil
136
+ }
137
+
138
+ func decodeManagedFields (liveObj , newObj runtime.Object , ignoreManagedFieldsFromRequestObject bool ) (Managed , error ) {
139
+ // We take the managedFields of the live object in case the request tries to
140
+ // manually set managedFields via a subresource.
141
+ if ignoreManagedFieldsFromRequestObject {
142
+ return decodeLiveManagedFields (liveObj )
143
+ }
144
+
129
145
// If the object doesn't have metadata, we should just return without trying to
130
146
// set the managedFields at all, so creates/updates/patches will work normally.
131
147
newAccessor , err := meta .Accessor (newObj )
132
148
if err != nil {
133
- return newObj , nil
149
+ return nil , err
150
+ }
151
+
152
+ if isResetManagedFields (newAccessor .GetManagedFields ()) {
153
+ return internal .NewEmptyManaged (), nil
154
+ }
155
+
156
+ managed , err := internal .DecodeObjectManagedFields (newAccessor .GetManagedFields ())
157
+ // If the managed field is empty or we failed to decode it,
158
+ // let's try the live object. This is to prevent clients who
159
+ // don't understand managedFields from deleting it accidentally.
160
+ if err != nil || len (managed .Fields ()) == 0 {
161
+ return decodeLiveManagedFields (liveObj )
134
162
}
135
163
164
+ return managed , nil
165
+ }
166
+
167
+ // Update is used when the object has already been merged (non-apply
168
+ // use-case), and simply updates the managed fields in the output
169
+ // object.
170
+ func (f * FieldManager ) Update (liveObj , newObj runtime.Object , manager string ) (object runtime.Object , err error ) {
136
171
// First try to decode the managed fields provided in the update,
137
172
// This is necessary to allow directly updating managed fields.
138
- var managed Managed
139
- if isResetManagedFields (newAccessor .GetManagedFields ()) {
140
- managed = internal .NewEmptyManaged ()
141
- } else if managed , err = internal .DecodeObjectManagedFields (newAccessor .GetManagedFields ()); err != nil || len (managed .Fields ()) == 0 {
142
- liveAccessor , err := meta .Accessor (liveObj )
143
- if err != nil {
144
- return newObj , nil
145
- }
146
- // If the managed field is empty or we failed to decode it,
147
- // let's try the live object. This is to prevent clients who
148
- // don't understand managedFields from deleting it accidentally.
149
- if managed , err = internal .DecodeObjectManagedFields (liveAccessor .GetManagedFields ()); err != nil {
150
- managed = internal .NewEmptyManaged ()
151
- }
173
+ managed , err := decodeManagedFields (liveObj , newObj , f .ignoreManagedFieldsFromRequestObject )
174
+ if err != nil {
175
+ return newObj , nil
152
176
}
153
177
154
178
internal .RemoveObjectManagedFields (liveObj )
0 commit comments